我通常至少有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 branch \
--format "%(if)%(upstream:short)%(then)git push . %(upstream:short):%(refname:short)%(end)" |
sh
它是如何工作的?
它使用git分支命令的自定义格式。对于每个具有上游分支的分支,它打印一行具有以下模式的代码:
git push . <remote-ref>:<branch>
这可以直接通过管道传输到sh(假设分支名称是格式良好的)。忽略| sh,看看它在做什么。
警告
单行程序不会联系你的遥控器。在运行它之前,发出git fetch或git fetch。
当前签出的分支将不会用类似于
! [remote rejected] origin/master -> master (branch is currently checked out)
为此,您可以求助于常规的git pull -ff-only。
别名
将以下内容添加到你的.gitconfig中,以便git fft执行此命令:
[alias]
fft = !sh -c 'git branch --format \"%(if)%(upstream:short)%(then)git push . %(upstream:short):%(refname:short)%(end)\" | sh' -
参见my .gitconfig。别名是“快进跟踪(分支)”的缩写。
如果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