【发布时间】:2013-05-17 09:52:42
【问题描述】:
在我们的 Git 流程中,“master”是当前发布周期的 topic 和 fix 分支的集成分支,但我们还维护一个“稳定”分支,我们必须小心地向后移植一些已经在 master 上成功测试的修复.
所有的困难是分支已经被合并回“master”(否则使用 rebase --onto 真的很容易)
- 我们不想以其他方式更改流程,因为 a) 我们不想修复“稳定”分支中的所有内容,并且 b) 我们有时必须对“稳定”分支进行一些更改我们不想合并到“master”中。
- 显然,我们无法将修复合并到“稳定”分支中,因为这会向后移植许多不需要的功能。
我描述的初始情况图表:
I--J (stable)
/
/
/
- A - B - C - D - E - F - G (master)
\ /
X -- Y (fix/123)
我们想要达到的那种情况的图表:
I--J (stable)
/ \
/ X'- Y' (fix/123-stable)
/
- A - B - C - D - E - F - G (master)
\ /
X -- Y (fix/123)
更复杂的情况是可能的,例如多次合并以完成修复:
- A - B - C - D - E - F - G - H (master)
\ / /
X - Y ----- Z (fix/123)
但是我们不允许合并到一个修复分支中,所以我们永远不会有这样的东西:
- A - B - C - D - E - F - G (master)
\ \ /
X - Y - Z (fix/123)
为了实现这一点,我们可以挑选或变基修复分支:
1) 樱桃采摘(典型的是How do I backport a commit in git?):
git checkout -b fix/123-stable stable
git cherry-pick X Y
这看起来很容易,但在处理现实生活中的例子时却不是这样;忘记某些提交或选择错误的提交总是有风险!
2) 变基 --onto (https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html) :
2.a) “不工作”的方式:
git rebase --onto stable master fix/123
这没有任何作用,因为 fix/123 已经合并到 master ! 2.b)“比樱桃采摘好不了多少”的方式:
git rebase --onto stable D fix/123
这仍然有点冒险,因为您需要采用 D 的 SHA(例如,而不是 X)。
2.c)“使用临时起始参考”方式:
git tag begin D
git rebase --onto stable begin fix/123
git tag -d begin
这改善了以前的情况,因为标签更容易做到或在图形工具中绘制它,但仍然需要大量的手动工作。
3.d) "reset hard master before merge"(到第一个分支点) 嗯,似乎很难描述和做。
所以,我正在寻找的是一种 git portable(没有隐含的 bash/grep/cut/sed)方式;
1) 列出已经合并回“master”的分支上的所有提交(这里是 X 和 Y,在“多合并”的情况下还有 Z),以便轻松挑选它们
2) 获取已经合并回“master”的分支的第一个分支点的提交
2.a) 这不能通过“git merge-base”命令完成,因为合并已经完成(甚至多次)
2.b) 我在这里Finding a branch point with Git? 找到了以下我稍微调整的 bash 命令:
git rev-list --boundary --date-order --reverse fix/123..master | grep -m 1 - | cut -c2-
但他的命令不是 git 简单或可移植的命令(即在没有 Bash 或 Cygwin 工具的情况下无法工作)
【问题讨论】:
标签: git branch rebase cherry-pick