我的团队中的工作流程如下:
- 在任何时候,我们都有一个以上的活动分支;对于一个应用程序的两个不同版本(比如说,
v4
表示即将发布的版本,v5
表示在遥远的将来发布),开发并行地进入两个或多个分支。我们定期将v4
合并为v5
- 从来没有人直接在
v4
或v5
上工作,我们在fork中处理功能分支并创建拉请求,指向上游v4
或v5
(使用Atlassian Stash)
比方说我创造了一个新的发展。我创建了一个新分支:
git checkout -b SOMETHING_FOR_V4 v4
现在我在SOMETHING_FOR_V4
。我做提交和推送:
git push -u origin SOMETHING_FOR_V4
我已经用-u
设置了远程跟踪分支,所以下次更新时,我可以在不指定分支的情况下执行git push
,Git就会知道推送到哪里。
然而,时间已经过去了,我想重新做人。
我需要明确告诉git rebase origin/v4
相反,我可以在创建分支时将origin/v4
设置为我的跟踪分支,但在推送时,每次都必须说git push origin SOMETHING_FOR_V4
。
我想要的是让Git足够聪明,知道在哪个基础上重新建立基础。如果我只是在做了git push -u
之后说git rebase
,它会占用我在推送时指定的远程跟踪分支,这不是我想要的。
基本上,我想让单独的跟踪分支用于git push
(我第一次推到的那个),并为git rebase
单独一个(根据我开始[1]的位置,在v4
或v5
的顶部重新设置基准)。
有可能得到这种行为吗
或者,我会用什么命令来确定自己是"更接近"v4
还是v5
(我正在考虑在别名中自动获取和重新建立数据库)?
[1] 它可以在我开始的基础上重新设置基础,比如v4
,也可以在这个场景中为远程origin/v4
。假设我可以自己处理保持v4
和origin/v4
同步的问题。
目前还没有内置的方法来实现您想要做的事情。但如果您不能自己处理这种情况,git就不会是git。
配置
为了使其发挥作用,我们必须配置要重新建立基础的分支。Git让你可以自由添加任何你能想象到的配置;所以让我们把这个配置密钥称为CCD_ 29。
要将origin/v4
设置为SOMETHING_FOR_V4
的rebase-upstream
,我们可以简单地执行:
git configure branch.SOMETHING_FOR_V4.rebase-upstream origin/v4
外壳脚本
现在,我们需要一个脚本来读取此配置并将其传递给rebase
。
以下脚本将尝试读取当前分支的配置;如果您现在不在任何分支上,或者当前分支不存在rebase-upstream
配置,它将向您发出警告。
#!/bin/sh
current_branch="$(git symbolic-ref --short -q HEAD)"
if [ $? == 1 ]; then
echo "You are on no branch!" >&2
exit 1
fi
upstream="$(git config --get branch.$current_branch.rebase-upstream)"
if [ $? == 1 ]; then
echo "No rebase-upstream reference configured for $current_branch (config: branch.$current_branch.rebase-upstream)" >&2
exit 1
fi
echo "Rebase $current_branch onto $upstream"
git rebase "$upstream"
用法
为了方便地使用这个脚本,您现在有两种可能性。
您可以将脚本添加到路径中的某个位置,并将其称为git-rebase-upstream
(或类似名称);前导CCD_ 36是本文的重要组成部分。Git在您的路径中查找以git-
开头的可执行文件,并将它们作为命令提供。现在您可以通过git rebase-upstream
使用它。
更"可移植"的方法是添加一个别名,该别名包含带有脚本的shell函数。优点是,如果您想在多台机器上同步git配置和命令,则只需备份全局.gitconfig
。
添加一个名为rebase-upstream
的别名如下所示:
git config --global alias.rebase-upstream '!f() { current_branch="$(git symbolic-ref --short -q HEAD)"; if [ $? == 1 ]; then echo "You are on no branch!" >&2; exit 1; fi; upstream="$(git config --get branch.$current_branch.rebase-upstream)"; if [ $? == 1 ]; then echo "No rebase-upstream reference configured for $current_branch (config: branch.$current_branch.rebase-upstream)" >&2; exit 1; fi; echo "Rebase $current_branch onto $upstream"; git rebase "$upstream"; }; f'
如果您想在任一方法中使用较短的别名(ru
),您可以使用
git config --global alias.ru '!git rebase-upstream'