SRo*_*uts 4 git branch rebase cherry-pick
在我们的Git流程中,"master"是当前发布周期的主题和修复分支的集成分支,但我们还维护一个"稳定"分支,我们必须谨慎地向后移植已经在master上成功测试的一些修复.
所有困难都是分支已经合并回"master"(否则它很容易与rebase --onto)
我描述的初始情况图:
I--J (stable)
/
/
/
- A - B - C - D - E - F - G (master)
\ /
X -- Y (fix/123)
Run Code Online (Sandbox Code Playgroud)
我们想要达到的那种情况的图表:
I--J (stable)
/ \
/ X'- Y' (fix/123-stable)
/
- A - B - C - D - E - F - G (master)
\ /
X -- Y (fix/123)
Run Code Online (Sandbox Code Playgroud)
更复杂的情况是可能的,例如多次合并以完成修复:
- A - B - C - D - E - F - G - H (master)
\ / /
X - Y ----- Z (fix/123)
Run Code Online (Sandbox Code Playgroud)
但我们不允许合并到一个修复分支,所以我们永远不会有这样的东西:
- A - B - C - D - E - F - G (master)
\ \ /
X - Y - Z (fix/123)
Run Code Online (Sandbox Code Playgroud)
为实现这一目标,我们可以挑选或修改修复分支:
1)cherry-pick(典型地如何在git中向后端移植提交?):
git checkout -b fix/123-stable stable
git cherry-pick X Y
Run Code Online (Sandbox Code Playgroud)
这似乎很容易,但在处理现实生活中的例子时并非如此; 总是存在忘记一些提交或挑错的风险!
2)rebase --onto(https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html):
2.a)"不工作"的方式:
git rebase --onto stable master fix/123
Run Code Online (Sandbox Code Playgroud)
这没有任何作用,因为fix/123已经合并为master!2.b)"不比樱桃挑选更好"的方式:
git rebase --onto stable D fix/123
Run Code Online (Sandbox Code Playgroud)
这仍然有点冒险,因为您需要使用D的SHA(例如,不是X).
2.c)"使用临时起始参考"的方式:
git tag begin D
git rebase --onto stable begin fix/123
git tag -d begin
Run Code Online (Sandbox Code Playgroud)
这改善了以前的情况,因为标签使其更容易实现或在图形工具中进行描绘,但仍然需要大量的手动工作.
3.d)"合并前重置硬主人"(到第一个分支点)哼,似乎很难描述和去做.
所以,我正在寻找的是一个git 便携式(没有bash/grep/cut/sed隐含)的方式;
1)列出已经合并回"master"的分支上的所有提交(这里是X和Y,以及"多合并"情况下的Z),以便轻松地挑选它们
2)获取已经合并回"master"的分支的第一个分支点的提交
2.a)这不能通过"git merge-base"命令完成,因为合并已经完成(甚至多次)
2.b)我在这里找到了用Git寻找分支点?我调整了以下bash命令:
git rev-list --boundary --date-order --reverse fix/123..master | grep -m 1 - | cut -c2-
Run Code Online (Sandbox Code Playgroud)
但他不是一个简单易用的便携式命令(即没有Bash或Cygwin工具就无法工作)
为了记录,这里是我最终使用的两个解决方案,基于Craig Otis的回答,在这里指出lindes在"使用Git查找分支点"的答案,使用Bash别名".gitconfig"文件(在Linux下测试) Ubuntu 12.10)
初始状态,分支"fix/123"已经合并回"master":
I--J (stable)
/
- A - B - C - D - E - F - G (master)
\ /
X - Y (fix/123)
Run Code Online (Sandbox Code Playgroud)
1)将从"master"开始的分支"fix/123"重新定义为"stable"(对于大多数人来说这是一个通用的答案):
将以下Bash别名添加到".gitconfig"文件中:
[alias]
oldest-ancestor = !bash -c 'diff -u <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | sed -ne \"s/^ //p\" | head -1' -
rebase-onto = !bash -c 'git rebase --onto $1 `git oldest-ancestor $2 $3` $3' -
Run Code Online (Sandbox Code Playgroud)
然后使用命令行:
git rebase-onto stable master fix/123
Run Code Online (Sandbox Code Playgroud)
你在这里:
I--J (stable)
/ \
/ X'- Y' (fix/123)
/
- A - B - C - D - E - F - G (master)
\ /
X - Y
Run Code Online (Sandbox Code Playgroud)
2)从"master"开始重新分支"fix/123"分支,在"stable"上创建一个新的分支"fix/123-stable"(这是我将要使用的更具体的答案).
将以下Bash别名添加到".gitconfig"文件中:
[alias]
oldest-ancestor = !bash -c 'diff -u <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | sed -ne \"s/^ //p\" | head -1' -
rebase-onto = !bash -c 'git branch $4 $2 && git rebase --onto $3 `git oldest-ancestor $1 $4` $4' -
Run Code Online (Sandbox Code Playgroud)
然后使用命令行:
git rebase-onto master fix/123 stable fix/123-stable
Run Code Online (Sandbox Code Playgroud)
你在这里:
I--J (stable)
/ \
/ X'- Y' (fix/123-stable)
/
- A - B - C - D - E - F - G (master)
\ /
X - Y (fix/123)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2244 次 |
| 最近记录: |