调整脚本以拉取所有远程分支

4

我已经开始使用在这个帖子中发布的一个脚本:

#!/bin/bash

main() {
  REMOTES="$@";
  if [ -z "$REMOTES" ]; then
    REMOTES=$(git remote);
  fi
  REMOTES=$(echo "$REMOTES" | xargs -n1 echo)
  CLB=$(git branch -l|awk '/^\*/{print $2}');
  echo "$REMOTES" | while read REMOTE; do
    git remote update $REMOTE
    git remote show $REMOTE -n \
    | awk '/merges with remote/{print $5" "$1}' \
    | while read line; do
      RB=$(echo "$line"|cut -f1 -d" ");
      ARB="refs/remotes/$REMOTE/$RB";
      LB=$(echo "$line"|cut -f2 -d" ");
      ALB="refs/heads/$LB";
      NBEHIND=$(( $(git rev-list --count $ALB..$ARB 2>/dev/null) +0));
      NAHEAD=$(( $(git rev-list --count $ARB..$ALB 2>/dev/null) +0));
      if [ "$NBEHIND" -gt 0 ]; then
        if [ "$NAHEAD" -gt 0 ]; then
          echo " branch $LB is $NBEHIND commit(s) behind and $NAHEAD commit(s) ahead of $REMOTE/$RB. could not be fast-forwarded";
        elif [ "$LB" = "$CLB" ]; then
          echo " branch $LB was $NBEHIND commit(s) behind of $REMOTE/$RB. fast-forward merge";
          git merge -q $ARB;
        else
          echo " branch $LB was $NBEHIND commit(s) behind of $REMOTE/$RB. reseting local branch to remote";
          git branch -l -f $LB -t $ARB >/dev/null;
        fi
      fi
    done
  done
}

main $@

到目前为止,它的工作效果很好,但我想知道如何调整它以拉取所有分支,因为某些原因它无法拉取特定的本地分支。 第一个例子:我有4个本地分支落后于主分支,运行此脚本后,几个(4个)相对于远程分支落后的分支被拉取了,但我仍然可以看到主分支落后于远程分支,如下图所示:

enter image description here

第二个例子:在运行脚本之前,我得到了这个结果,有两个本地分支落后了,而当前的一个(release)是正常的:

enter image description here

我运行了脚本,得到了这个:

enter image description here

那么,我该如何调整脚本以拉取“所有”本地分支?


1
在拉取后,我只看到master分支落后了。还有其他分支也落后吗? - Tim Biegeleisen
@TimBiegeleisen 我已经更新了我的问题,并提供了两个示例,希望这样能够澄清。 - BPL
2个回答

1

除了我之前的回答,我还想补充一点,你的脚本应该只限制给定分支与其上游分支的合并或重置。
因此我使用了%(upstream:track)

这是我刚测试过的脚本:

  • git版本2.11.0.windows.1
  • SourceTree 1.9.10.0

也就是说:

#!/bin/bash

branches=$(git for-each-ref --format="%(refname) %(upstream) %(upstream:track)" refs/heads)

echo "${branches}"
branch_checkedout=$(cat .git/HEAD|cut -f2 -d" ")
echo branch checked out: "${branch_checkedout}"

while read -r branch_line; do
  ahead=0
  behind=0
  branch_local=$(echo ${branch_line}|cut -f1 -d" ")
  branch_remote=$(echo ${branch_line}|cut -f2 -d" ")
  echo ${branch_line} | grep "ahead" >/dev/null && ahead=1
  echo ${branch_line} | grep "behind" >/dev/null && behind=1
  NAHEAD=$(( $(git rev-list --count ${branch_remote}..${branch_local} 2>/dev/null) +0))
  NBEHIND=$(( $(git rev-list --count ${branch_local}..${branch_remote} 2>/dev/null) +0));

  if [ "$NBEHIND" -gt 0 ]; then
    if [ "$NAHEAD" -gt 0 ]; then
      echo " branch $LB is $NBEHIND commit(s) behind and $NAHEAD commit(s) ahead of $REMOTE/$RB. could not be fast-forwarded";
    elif [ "${branch_local}" = "${branch_checkedout}" ]; then
      echo " branch ${branch_local} was $NBEHIND commit(s) behind of ${branch_remote}. fast-forward merge";
      echo "git merge -q ${branch_remote}"
      git merge -q ${branch_remote};
    else
      echo " branch ${branch_local} was $NBEHIND commit(s) behind of ${branch_remote}. reseting local branch to remote";
      bl=${branch_local#*/}
      bl=${bl#*/}
      echo "git branch -l -f ${bl} -t ${branch_remote}"
      git branch -l -f ${bl} -t ${branch_remote} >/dev/null;
    fi
  fi
done <<< "${branches}"

注意使用:

  • branches=$(git for-each-ref --format="%(refname) %(upstream) %(upstream:track)" refs/heads)
    获取完整的上游分支名称以及前后状态
  • branch_checkedout=$(cat .git/HEAD|cut -f2 -d" ") 获取已检出分支的名称
  • while read -r branch_line; do 循环遍历仅具有上游分支而不是“所有远程”(这可能包括或不包括给定分支)的分支

非常感谢,我已经测试了 git version 2.10.1.windows.1sourcetree 1.5.2,目前为止效果非常好。之前我没有时间测试。顺便问一下,您是否预见在使用脚本之前需要特别小心的情况? - BPL
@BPL 到目前为止,我没有遇到任何特殊情况。我将检查涉及子模块条目的存储库,以查看是否存在问题。 - VonC

1

首先检查您的上游分支master:它可能不是origin,这就是为什么从origin拉取可能没有任何效果的原因。

git rev-parse --abbrev-ref --symbolic-full-name master@{u}

其次,要在脚本中显示提交数的前后差异,请使用Git 1.9 语法%(upstream:track)

git for-each-ref --format="%(refname:short) %(upstream:track)" refs/heads

请注意,上游分支(或远程跟踪分支,即您正在拉取的分支)可能与您要推送到的分支不同。
检查是否有一个带有推送网址的分支:
git config --get-regexp branch.master

首先,感谢您的回答。您能否具体说明如何在脚本中集成这3个命令,以便我可以测试一下呢?我对Git还是个新手,对这些命令有点迷茫。 - BPL
使用System Git版本2.10.1 + SourceTree 1.5.2.0组合。尝试过SourceTree 1.6.x或最新的SourceTree 1.9.x后,我必须说没有真正的理由让我进一步升级,不喜欢那些后期版本中的一些Attlasian决定,所以我很满意留在这个相对稳定快速/(不太多错误)的旧版本 :) - BPL
@BPL 好的,这就解释了为什么我没有立即复现这个问题(我使用最新的1.9.6.1)。我会尝试你的脚本。 - VonC
好的,我会给你赏金,因为不想让它们浪费...但我现在无法验证这个。 - BPL
@BPL 不过,仅仅为了测试,检查最新版本的SourceTree是否有相同的问题会很有趣。 - VonC
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接