我通常至少有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 pull -all”可以更新我所有的本地分支吗?

不,它不能。对于快进,我只是编写了一个小工具。https://github.com/changyuheng/git-fast-forward-all

该工具的优点:

在一个存储库中支持多个远程。(集线器同步目前不支持多个遥控器。) 支持在本地分支和相应的远程跟踪分支上使用不同的名称。 比其他获取每个分支的远程脚本快得多。 没有容易出错的正则表达式解析/编辑。

其他回答

我为我的giitbash写的脚本。完成以下任务:

默认情况下,为跟踪原点而设置的所有分支从原点提取,允许您根据需要指定不同的远程。 如果您的当前分支处于脏状态,那么它将存储您的更改,并在结束时尝试恢复这些更改。 对于每个用于跟踪远程分支的本地分支,将: Git结帐分支 Git拉源 最后,将您返回到原始分支并恢复状态。

**我使用这个,但没有彻底测试,使用自负风险。在.bash_alias文件中可以看到该脚本的示例。

    # Do a pull on all branches that are tracking a remote branches, will from origin by default.
    # If current branch is dirty, will stash changes and reply after pull.
    # Usage: pullall [remoteName]
    alias pullall=pullAll
    function pullAll (){
     # if -h then show help
     if [[ $1 == '-h' ]]
    then
      echo "Description: Pulls new changes from upstream on all branches that are tracking remotes."
      echo 
      echo "Usage: "
      echo "- Default: pullall"
      echo "- Specify upstream to pull from: pullall [upstreamName]"
      echo "- Help: pull-all -h"
    else

     # default remote to origin
     remote="origin"
     if [ $1 != "" ]
     then
       remote=$1
     fi

     # list all branches that are tracking remote
     # git branch -vv : list branches with their upstreams
     # grep origin : keep only items that have upstream of origin
     # sed "s/^.."... : remove leading *
     # sed "s/^"..... : remove leading white spaces
     # cut -d" "..... : cut on spaces, take first item
     # cut -d splits on space, -f1 grabs first item
     branches=($(git branch -vv | grep $remote | sed "s/^[ *]*//" | sed "s/^[ /t]*//" | cut -d" " -f1))

     # get starting branch name
     startingBranch=$(git rev-parse --abbrev-ref HEAD)

     # get starting stash size
     startingStashSize=$(git stash list | wc -l)

     echo "Saving starting branch state: $startingBranch"
     git stash

     # get the new stash size
     newStashSize=$(git stash list | wc -l)

     # for each branch in the array of remote tracking branches
     for branch in ${branches[*]}
     do
       echo "Switching to $branch"
       git checkout $branch

       echo "Pulling $remote"
       git pull $remote

     done

     echo "Switching back to $startingBranch"
     git checkout $startingBranch

     # compare before and after stash size to see if anything was stashed
     if [ "$startingStashSize" -lt "$newStashSize" ]
     then
       echo "Restoring branch state"
       git stash pop
     fi
    fi
    }

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

#!/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

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

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

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

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

这里有一个很好的答案:如何获取所有git分支

for remote in `git branch -r`; do git branch --track $remote; done
git pull --all

我使用hub的sync子命令来实现自动化。我在我的.bash_profile中有别名git=hub,所以我键入的命令是:

git sync

这将更新具有匹配上游分支的所有本地分支。从手册页:

如果本地分支已经过时,快进; 如果本地分支包含未推送的工作,请对此发出警告; 如果分支显示为已合并,且上游分支已被删除,则删除该分支。

它还处理在当前分支上存储/解存储未提交的更改。

我曾经使用过一个类似的工具,叫做git-up,但它不再被维护,git sync几乎做了完全相同的事情。