我经常至少有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
Run Code Online (Sandbox Code Playgroud)
我很乐意能够做一个"git pull -all",但我无法让它发挥作用.它似乎执行"fetch --all",然后更新(快进或合并)当前工作分支,而不是其他本地分支.
我仍然卡在手动切换到每个本地分支和更新.
Joh*_*ohn 199
我用的sync子命令的中枢自动执行此.Hub的别名为alias git=hub,所以我输入的命令是:
git sync
Run Code Online (Sandbox Code Playgroud)
这将更新具有匹配上游分支的所有本地分支.从手册页:
- 如果本地分支已过时,请快进;
- 如果当地分支机构包含未完成的工作,请对此进行警告;
- 如果分支似乎已合并且其上游分支已删除,请将其删除.
它还处理当前分支上的存储/取消存储未提交的更改.
我曾经使用过类似的工具git-up,但它不再被维护,并且.bash_profile几乎完全相同.
Cas*_*bel 178
您描述的行为pull --all完全符合预期,但不一定有用.该选项被传递给git fetch,然后从所有遥控器获取所有引用,而不仅仅是所需的引用; pull然后合并(或在你的情况下,rebase)适当的单个分支.
如果你想查看其他分支机构,你将不得不检查它们.是的,合并(和重新定位)绝对需要一个工作树,所以如果不检查其他分支就无法完成.如果你愿意的话,你可以把你描述的步骤包装成一个脚本/别名,虽然我建议加入这些命令,&&这样如果其中一个失败了,它就不会尝试使用.
muh*_*hqu 37
我知道这个问题已经快3年了,但我问自己同样的问题并没有找到任何现成的解决方案.所以,我自己创建了一个自定义git命令shell脚本.
在这里,git-ffwd-update脚本执行以下操作......
git remote update来获取lates revsgit remote show获取跟踪远程分支的本地分支列表(例如可以使用的分支git pull)git rev-list --count <REMOTE_BRANCH>..<LOCAL_BRANCH>遥控器后面的本地分支提交的数量(反之亦然)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
Run Code Online (Sandbox Code Playgroud)
完整的脚本应该保存为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 $@
Run Code Online (Sandbox Code Playgroud)
Fre*_*Foo 24
自动化并不是那么难:
#!/bin/sh
# Usage: fetchall.sh branch ...
set -x
git fetch --all
for branch in "$@"; do
git checkout "$branch" || exit 1
git rebase "origin/$branch" || exit 1
done
Run Code Online (Sandbox Code Playgroud)
Mat*_*lly 17
这仍然不是自动的,因为我希望有一个选项 - 并且应该进行一些检查以确保这只能发生在快进更新中(这就是为什么手动执行拉动更安全!!),但除了警告,你可以:
git fetch origin
git update-ref refs/heads/other-branch origin/other-branch
Run Code Online (Sandbox Code Playgroud)
更新本地分支的位置而无需检查.
注意:您将失去当前的分支位置并将其移动到原始分支的位置,这意味着如果您需要合并,则会丢失数据!
Jak*_*ski 11
这个问题尚未解决(至少不容易/没有脚本):请参阅Junio C Hamano在git邮件列表上的这篇文章,解释情况并提供简单解决方案.
主要原因是你不应该需要这个:
使用不古老的git(即v1.5.0或更新版本),没有理由让本地"dev"完全跟踪遥控器.如果您只想去看看,可以直接在带有"
git checkout origin/dev" 的分离式HEAD上查看远程跟踪分支.这意味着我们需要使用户方便的唯一情况是处理这些本地分支,这些分支在您进行本地更改时"跟踪"远程分支,或者您计划拥有一些分支.
如果您对"dev"进行了本地更改,标记为跟踪删除"dev",如果您位于与"dev"不同的分支上,那么在"
git fetch"更新远程跟踪"dev" 后我们不应该执行任何操作.无论如何它不会快进
对解决方案的要求是一个选项或外部脚本来修剪现在跟随远程跟踪分支的本地分支,而不是通过快进来保持它们是最新的,就像请求的原始海报一样.
那么"
git branch --prune --remote=<upstream>"迭代本地分支如何,如果(1)它不是现在的分支; 和
(2)它被标记来跟踪从采取了一些分支的<上游>; 和
(3)它不会对自己的任何承诺;然后删除那个分支?"
git remote --prune-local-forks <upstream>"也没事; 我不关心哪个命令实现了这个功能.
注意:从git 2.10开始,不存在这样的解决方案.请注意git remote prune子命令,并且git fetch --prune关于删除远程不再存在的分支的远程跟踪分支,而不是删除跟踪远程跟踪分支的本地分支(远程跟踪分支是上游分支).
quo*_*ian 11
这里有很多答案,但没有一个用于git-fetch直接更新本地ref,这比检查分支要简单得多,比安全更安全git-update-ref.
这里我们git-fetch用来更新非当前分支和git pull --ff-only当前分支.它:
这是:
#!/bin/bash
currentbranchref="$(git symbolic-ref HEAD 2>&-)"
git branch -r | grep -v ' -> ' | while read remotebranch
do
# Split <remote>/<branch> into remote and branchref parts
remote="${remotebranch%%/*}"
branchref="refs/heads/${remotebranch#*/}"
if [ "$branchref" == "$currentbranchref" ]
then
echo "Updating current branch $branchref from $remote..."
git pull --ff-only
else
echo "Updating non-current ref $branchref from $remote..."
git fetch "$remote" "$branchref:$branchref"
fi
done
Run Code Online (Sandbox Code Playgroud)
从联机帮助页git-fetch:
<refspec>
The format of a <refspec> parameter is an optional plus +, followed by the source ref <src>,
followed by a colon :, followed by the destination ref <dst>.
The remote ref that matches <src> is fetched, and if <dst> is not empty string, the local ref
that matches it is fast-forwarded using <src>. If the optional plus + is used, the local ref is
updated even if it does not result in a fast-forward update.
Run Code Online (Sandbox Code Playgroud)
通过指定git fetch <remote> <ref>:<ref>(没有任何+),我们得到一个获取,只有当它可以快进时才更新本地ref.
注意:这假设本地和远程分支的名称相同(并且您希望跟踪所有分支),它应该真正使用有关您拥有哪些本地分支以及它们设置为跟踪的内容的信息.
这里有很多可接受的答案,但有些管道可能对于不熟悉的人来说有点不透明.这是一个可以轻松定制的更简单的示例:
$ 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 "$@"
Run Code Online (Sandbox Code Playgroud)
如果你添加~/bin/git到你的PATH(假设文件是~/bin/git/git-update-all),你可以运行:
$ git update-all
Run Code Online (Sandbox Code Playgroud)
小智 7
我遇到了这个问题的同样问题......
我想知道这一点,我在我的 .bashrc文件中做了一个小的别名函数:
gitPullAll() {
for branch in `git branch | sed -E 's/^\*/ /' | awk '{print $1}'`; do
git checkout $branch
git pull -p
printf "\n"
done
echo "Done"
}
Run Code Online (Sandbox Code Playgroud)
为我工作(:
这是一个很好的答案:如何获取所有git分支
for remote in `git branch -r`; do git branch --track $remote; done
git pull --all
Run Code Online (Sandbox Code Playgroud)
添加这个脚本到.profileMac OS X上:
# Usage:
# `git-pull-all` to pull all your local branches from origin
# `git-pull-all remote` to pull all your local branches from a named remote
function git-pull-all() {
START=$(git symbolic-ref --short -q HEAD);
for branch in $(git branch | sed 's/^.//'); do
git checkout $branch;
git pull ${1:-origin} $branch || break;
done;
git checkout $START;
};
function git-push-all() {
git push --all ${1:-origin};
};
Run Code Online (Sandbox Code Playgroud)
您无法仅使用一个 git 命令来完成此操作,但您可以使用一根 bash 行将其自动化。
为了用一行安全地更新所有分支,我会这样做:
git fetch --all && for branch in $(git branch | sed '/*/{$q;h;d};$G' | tr -d '*') ; do git checkout $branch && git merge --ff-only || break ; done
Run Code Online (Sandbox Code Playgroud)
如果它无法快进一个分支或遇到错误,它将停止并将您留在该分支,以便您可以收回控制权并手动合并。
如果所有分支都可以快进,它将以您当前所在的分支结束,让您保持在更新之前的位置。
说明:
为了更好的可读性,可以将其分为几行:
git fetch --all && \
for branch in $(git branch | sed '/*/{$q;h;d};$G' | tr -d '*')
do git checkout $branch && \
git merge --ff-only || break
done
Run Code Online (Sandbox Code Playgroud)
git fetch --all && ...=> 从所有遥控器获取所有引用,如果没有错误,则继续执行下一个命令。
git branch | sed '/*/{$q;h;d};$G' | tr -d '*'=> 从 的输出中git branch,sed取出带有 a 的行*并将其移动到末尾(以便当前分支将最后更新)。然后tr只需删除*.
for branch in $(...) ; do git checkout $branch && git merge --ff-only || break ; done=> 对于从上一个命令获得的每个分支名称,检出该分支并尝试与快进合并。如果失败,break则调用该命令并且命令在此停止。
当然,如果你想要的话,你可以替换git merge --ff-only成。git rebase
最后,您可以将其作为别名放入bashrc中:
alias git-pull-all='git fetch --all && for branch in $(git branch | sed '\''/*/{$q;h;d};$G'\'' | tr -d "*") ; do git checkout $branch && git merge --ff-only || break ; done'
Run Code Online (Sandbox Code Playgroud)
或者,如果您担心弄乱 ' 和 ",或者您只是希望在编辑器中保持语法可读性,则可以将其声明为函数:
git-pull-all()
{
git fetch --all && for branch in $(git branch | sed '/*/{$q;h;d};$G' | tr -d '*') ; do git checkout $branch && git merge --ff-only || break ; done
}
Run Code Online (Sandbox Code Playgroud)
奖金:
对于那些想要这sed '/*/{$q;h;d};$G'部分解释的人:
/*/=> 搜索带有*.
{$q=> 如果它在最后一行,则退出(我们不需要做任何事情,因为当前分支已经是列表中的最后一个)。
;h;d}=> 否则,将该行存储在保留缓冲区中,并在当前列表位置中将其删除。
;$G=> 当到达最后一行时,追加保留缓冲区的内容。