我通常至少有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-up不再维护,如果你阅读文档,他们提到该功能现在在git中可用。

从Git 2.9开始,Git pull -rebase -autostash基本上做了同样的事情。 因此,如果你更新到Git 2.9或更高版本,你可以使用这个别名而不是安装Git -up: Git配置——全局别名。Up 'pull -rebase -autostash'

你也可以为git 2.9的每次git拉取设置这个(谢谢@VonC,请在这里看到他的回答)

git config --global pull.rebase true
git config --global rebase.autoStash true

其他回答

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

$ 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

为了完成Matt Connolly的回答,这是一种更安全的更新本地分支引用的方法,可以快进,而不签出分支。它不会更新不能快进的分支(即已经分离的分支),也不会更新当前签出的分支(因为这样工作副本也应该更新)。

git fetch

head="$(git symbolic-ref HEAD)"
git for-each-ref --format="%(refname) %(upstream)" refs/heads | while read ref up; do
    if [ -n "$up" -a "$ref" != "$head" ]; then
        mine="$(git rev-parse "$ref")"
        theirs="$(git rev-parse "$up")"
        base="$(git merge-base "$ref" "$up")"
        if [ "$mine" != "$theirs" -a "$mine" == "$base" ]; then
            git update-ref "$ref" "$theirs"
        fi
    fi
done

从git 2.9开始:

Git pull -rebase -autostash

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

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

它可以使用下面的脚本…它将首先获取所有分支,逐个签出并自行更新。

#!/bin/bash
git branch -r | grep -v '\->' | while read remote; do git branch --track 
"${remote#origin/}" "$remote"; done

set -x
CURRENT=`git rev-parse --abbrev-ref HEAD`
git fetch --all
branch_name=$(git branch | awk '{print $1" "}' | grep -v '*' | xargs)
for branch in $branch_name; do
   git checkout "$branch" || exit 1
   git rebase "origin/$branch" || exit 1
   git pull origin $branch|| exit 1
done
git checkout "$CURRENT" || exit 1
git pull || exit 1

来自@larsmans的脚本,有一点改进:

#!/bin/sh

set -x
CURRENT=`git rev-parse --abbrev-ref HEAD`
git fetch --all
for branch in "$@"; do
  if ["$branch" -ne "$CURRENT"]; then
    git checkout "$branch" || exit 1
    git rebase "origin/$branch" || exit 1
  fi
done
git checkout "$CURRENT" || exit 1
git rebase "origin/$CURRENT" || exit 1

这样,在它完成之后,工作副本就会从调用脚本之前的同一个分支签出。

git拉版:

#!/bin/sh

set -x
CURRENT=`git rev-parse --abbrev-ref HEAD`
git fetch --all
for branch in "$@"; do
  if ["$branch" -ne "$CURRENT"]; then
    git checkout "$branch" || exit 1
    git pull || exit 1
  fi
done
git checkout "$CURRENT" || exit 1
git pull || exit 1