【问题标题】:how to create shell script to check if two commits are equal如何创建shell脚本来检查两个提交是否相等
【发布时间】:2016-07-08 11:33:02
【问题描述】:

我正在编写一个小的 shell 脚本,但我的语法不正确。它所做的只是通过使用 rev-parse 检查提交哈希来检查 git 是否是最新的。

所以这个:(git rev-parse HEAD) == $(git rev-parse @{u})

应该告诉我是否需要git pull。如果两者都返回相同的数字,那么我知道提交哈希是相同的,我不需要做任何事情。但现在我试图把它放在一个 shell 脚本中,我遇到了问题。这是我目前所拥有的:

#!/bin/sh
export isNew = (git rev-parse HEAD) -eq $(git rev-parse @{u})

if [$isNew -eq 0]; then
echo "its new"
fi

但我收到以下错误:

$./myscript.sh
./myscript.sh: line 2: syntax error near unexpected token `('
./myscript.sh: line 2: `export isNew = (git rev-parse HEAD) -eq $(git rev-parse @{u})'

【问题讨论】:

  • (git rev-parse HEAD) 之前缺少 '$' 是您的第一个问题
  • 可以简化为if [ $(git rev-parse HEAD) == $(git rev-parse @{u}) ]; then
  • 我想将结果存储在一个变量中,你能帮忙吗?
  • -eqtest 命令的参数。试试isnew=$(test $(git rev-parse HEAD) -eq $(git rev-parse @{u}))

标签: git bash shell


【解决方案1】:
#!/bin/sh

# Test for equality
[ $(git rev-parse HEAD) == $(git rev-parse @{u}) ]
# Assign result to a new variable (0 for true)
isNew=$?

# Then you can check isNew
if [ $isNew -eq 0 ]
then
    echo "its new"
fi

方括号用于测试条件。 请注意,[ $(git rev-parse HEAD) == $(git rev-parse @{u}) ] 本身不输出任何内容,而是使用返回码来指示其结果。 因此,如果您想保留以备后用,您需要使用$?,其中包含最后执行命令的返回码并将其分配给新变量,而不是直接将括号表达式分配给变量。

对于工作分配,= 周围不能有空格,这就是为什么你应该写isNew=$? 而不是isNew = $?。此外,如果您只打算在此脚本中使用 isNew,则在您的情况下,export 可能是不必要的。

还有一点,-eq 测试数值相等。要测试两个字符串是否相等,您可能需要==


编辑

但是,至于您打算使用此脚本检查是否需要执行拉取,仅将HEAD@{u} 进行比较是不够的,因为@{u} 指的是上游分支的尖端,保留自从您上次执行 git fetch 以来在本地,远程分支提示可能从那时起发生了变化,但您不会仅通过检查 @{u} 知道它。

您的脚本不会检测是否有人推送到远程分支,除非您事先执行 fetch 以“刷新”您的存储库。

考虑到这一点,最好执行以下操作:

#!/bin/sh

# Fetch the remote branch, tracked by your current local branch.
# This will set FETCH_HEAD to the latest commit in remote branch
# without affecting your working copy.
git fetch
# Test for equality between HEAD and FETCH_HEAD
[ $(git rev-parse HEAD) == $(git rev-parse FETCH_HEAD) ]
# Assign result to a new variable (0 for true)
isNew=$?

# Then you can check isNew
if [ $isNew -eq 0 ]
then
    echo "its new"
fi

【讨论】:

    【解决方案2】:

    其他人已经解决了其中的一些问题;我将首先添加一些我喜欢与后来用于布尔测试的 shell 变量一起使用的东西。

    让我们使用您的设置:

    if [ $(git rev-parse HEAD) == $(git rev-parse @{u}) ]; then
        upstream_matches_HEAD=true
        # more code here as desired
    else
        upstream_matches_HEAD=false
        # more code here if desired, again
    fi
    # whatever code here
    if $upstream_matches_HEAD; then
        # still more code
    fi
    

    将变量设置为true 时,我们最终会运行if true; then ...。将其设置为 false 时,我们最终会运行 if false; then ...。我发现它稍后也能很好地阅读,特别是如果你选择了好的变量名。

    领先、落后或两者兼而有之

    我注意到上面(每个 cmets)您可能关心谁在“领先”和/或“落后”(上游与当前分支)。请注意,在执行git fetch 之后,您可能会领先、落后,甚至两者。例如,假设在分支develop 上,您已经进行了 3 次未推送的提交……但一位同事已进行了 2 次她推送的提交。在git status 术语中,您现在“领先 3,落后 2”。

    要获取这些值,请在 HEAD-vs-@{u} 上使用 git rev-list --count

    # find out how many un-pushed commits we have,
    # i.e., commits that are on HEAD but not on the upstream
    ahead=$(git rev-list --count @{u}..HEAD)
    
    # same for un-merged un-rebased-onto commits: what is
    # on the upstream that we don't have?
    behind=$(git rev-list --count HEAD..@{u})
    

    (你可以从这些省略HEAD这个词,虽然我认为保留它读起来更好。)

    【讨论】:

      【解决方案3】:

      你打算这样做吗?

      if [ $(git rev-parse HEAD) == $(git rev-parse @{u}) ] ; then
          echo "It's different"
      fi
      

      Linux:
      那里不需要“出口”。
      您不能单独使用“-eq”并保存其结果。
      注意 '[' 之后的空格和 ']' 之前的空格,它们是必需的。


      吉特:
      不匹配的总和并不意味着哪个领先。

      【讨论】:

      • 你能帮我把结果放在一个变量中,这样我就可以在其他地方使用它了吗?所以我想要一个名为 isNew 的变量中的谓词
      • 哦,我还以为那是在前面?感谢您为我节省了一些错误。知道我可以用什么来检查我是否需要执行 git pull 吗?如果我的仓库需要进行拉取,我需要签入一个 shell 脚本。
      • 您应该以git fetch 开头,因为这将刷新您的存储库,但不会更改您的工作副本。拉取就像 fetch(获取更改)+ checkout(应用更改)。在git fetch 之后,git status 会告诉你是领先还是落后。
      猜你喜欢
      • 2015-08-21
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 2016-06-27
      • 2015-10-30
      • 2019-08-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多