我通常至少有3个远程分支:master、staging和production。我有3个本地分支来跟踪这些远程分支。

更新我所有的本地分支是乏味的:

git fetch --all
git rebase origin/master
git checkout staging
git rebase origin/staging
git checkout production
git rebase origin/production

我很想做一个“git pull -all”,但我还没能让它工作。它似乎做了一个“fetch -all”,然后更新(快进或合并)当前工作的分支,但不包括其他本地分支。

我仍然需要手动切换到每个本地分支并进行更新。


当前回答

从git 2.9开始:

Git pull -rebase -autostash

参见https://git-scm.com/docs/git-rebase

在行动开始前自动创建一个临时藏匿点, 操作结束后再应用。这意味着你可以跑 基于一个肮脏的工作树。然而,小心使用:最后的收藏 应用程序在成功的重基后可能会导致非平凡 冲突。

其他回答

我知道这个问题已经提了将近3年了,但我也问过自己同样的问题,但没有找到任何现成的解决方案。所以,我自己创建了一个自定义的git命令shell脚本。

在这里,git-ffwd-update脚本执行以下操作…

it issues a git remote update to fetch the lates revs then uses git remote show to get a list of local branches that track a remote branch (e.g. branches that can be used with git pull) then it checks with git rev-list --count <REMOTE_BRANCH>..<LOCAL_BRANCH> how many commit the local branch is behind the remote (and ahead vice versa) if the local branch is 1 or more commits ahead, it can NOT be fast-forwarded and needs to be merged or rebased by hand if the local branch is 0 commits ahead and 1 or more commits behind, it can be fast-forwarded by git branch -f <LOCAL_BRANCH> -t <REMOTE_BRANCH>

脚本可以这样调用:

$ git ffwd-update
Fetching origin
 branch bigcouch was 10 commit(s) behind of origin/bigcouch. resetting local branch to remote
 branch develop was 3 commit(s) behind of origin/develop. resetting local branch to remote
 branch master is 6 commit(s) behind and 1 commit(s) ahead of origin/master. could not be fast-forwarded

完整的脚本应该保存为git-ffwd-update,并且需要在PATH上。

#!/bin/bash

main() {
  REMOTES="$@";
  if [ -z "$REMOTES" ]; then
    REMOTES=$(git remote);
  fi
  REMOTES=$(echo "$REMOTES" | xargs -n1 echo)
  CLB=$(git rev-parse --abbrev-ref HEAD);
  echo "$REMOTES" | while read REMOTE; do
    git remote update $REMOTE
    git remote show $REMOTE -n \
    | awk '/merges with remote/{print $5" "$1}' \
    | while read RB LB; do
      ARB="refs/remotes/$REMOTE/$RB";
      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. resetting local branch to remote";
          git branch -f $LB -t $ARB >/dev/null;
        fi
      fi
    done
  done
}

main $@

如果你在Windows上,你可以使用PyGitUp,它是Python的一个克隆版本。您可以使用pip和pip install -user git-up安装它,或者通过Scoop使用Scoop install git-up安装它

[

这里有很多可以接受的答案,但对于外行来说,有些管道可能有点不透明。下面是一个可以轻松定制的简单示例:

$ cat ~/bin/git/git-update-all
#!/bin/bash
# Update all local branches, checking out each branch in succession.
# Eventually returns to the original branch. Use "-n" for dry-run.
git_update_all() {
  local run br
  br=$(git name-rev --name-only HEAD 2>/dev/null)
  [ "$1" = "-n" ] && shift && run=echo

  for x in $( git branch | cut -c3- ) ; do
     $run git checkout $x && $run git pull --ff-only || return 2
  done

  [ ${#br} -gt 0 ] && $run git checkout "$br"
}

git_update_all "$@"

如果你添加~/bin/git到你的PATH(假设文件是~/bin/git/git-update-all),你可以运行:

$ git update-all

如果refs/heads/master可以快进到refs/remotes/foo/master,则

git merge-base refs/heads/master refs/remotes/foo/master

应该返回refs/heads/master指向的SHA1 id。这样,您就可以将一个脚本组合在一起,自动更新没有应用转移提交的所有本地分支。

这个小shell脚本(我称之为git-can-ff)说明了如何做到这一点。

#!/bin/sh

set -x

usage() {
    echo "usage: $(basename $0) <from-ref> <to-ref>" >&2
    exit 2
}

[ $# -ne 2 ] && usage

FROM_REF=$1
TO_REF=$2

FROM_HASH=$(git show-ref --hash $FROM_REF)
TO_HASH=$(git show-ref --hash $TO_REF)
BASE_HASH=$(git merge-base $FROM_REF $TO_REF)

if [ "$BASE_HASH" = "$FROM_HASH" -o \
     "$BASE_HASH" = "$FROM_REF" ]; then
    exit 0
else
    exit 1
fi

这仍然不是自动的,因为我希望有一个选项-应该有一些检查,以确保这只能发生在快进更新(这就是为什么手动做拉更安全!!),但注意事项:

git fetch origin
git update-ref refs/heads/other-branch origin/other-branch

更新本地分支的位置,而无需签出。

注意:你将丢失你当前的分支位置,并将其移动到原点的分支所在的位置,这意味着如果你需要合并,你将丢失数据!