在我们的 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)cherry-pick(通常我如何在 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 the merge”(到第一个分支点) 嗯,似乎很难描述和做。
所以,我正在寻找的是一种可移植的 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-
但他不是一个 git 简单或可移植的命令(即没有 Bash 或 Cygwin 工具就不能工作)