如何将 long 运行 git 分支重置为 master?
How to reset long running git branch to master?
我们有一个 master
分支和许多短期特性分支,在客户接受更改后合并到 master
。
除此之外,我们还有用于用户验收系统和生产系统的长期生存环境分支,名为 stage
和 prod
,它们最初是从 master 分支出来的。
我们的工作流程是这样的:
- 在功能分支上开发功能
- 将功能分支合并到
stage
- 等待客户验收
- 接受合并到
master
master
第二天被合并到 prod
客户接受时间可能很短也可能很长,因此 stage
上有几个 "features" 正在等待接受或被放弃。因为如果客户 不 接受更改,我们不会将该功能合并到 master
但遗憾的是它像僵尸一样继续存在 stage
:)
现在问题:
我们如何将分支 stage
重置为当前 master
而不会失去将仍在等待接受的功能分支再次合并到 stage
的能力?这里的目标是摆脱被遗弃的"features"。
在不改变历史和强制推送的情况下这可能吗?
如果不重写历史,我唯一能想到的就是从废弃的功能中恢复那些提交。
如果您通过真正的合并将特征合并到 stage
中,则很容易恢复这些合并。只需 运行 git revert
在合并提交上,使用适当的 -m
参数(通常是 -m 1
)。
如果您通过复制提交或 fast-forwarding 将功能合并到 stage
中,则更加困难,因为您必须还原每个提交。您可以给 git revert
一个 范围 的提交来还原,它会以适当的顺序执行所有这些操作,即 last-to-first 顺序。请注意,A..B
形式的范围意味着 "everything reachable from B
, except for everything reachable from A
",并且由于 A
显然可以从自身到达,因此 排除 提交 A
本身.因此 1234567..fedcba9
包括提交 fedcba9
和更早的提交回 1234567
但 排除 1234567 本身。
如果您使用 git merge --squash
将功能合并到 stage
,这会将所有提交复制到一个大的(但独立的)提交中,这样您就可以再次简单地 运行 git revert
在一个复制的提交上(没有 -m
因为它不是合并提交)。
(请注意,无论您如何还原这些,如果您最终发现您毕竟想要该功能,那就有点痛苦了。)
由于所有已批准的功能都已合并到 master 中,因此舞台上第一个未合并的提交是废弃的功能。假设F1、F2、F3是舞台支线等待客户验收的生活特征。 F1 是放弃的特征,F2、F3 是接受的特征。所以它需要在舞台上摆脱F1。
C-----…-----D---F1---F2---F3 stage
/ \
A---…---B---…---E---…---G master
\ \
F----…----H prod
您可以使用以下命令:
git checkout stage
git rebase --onto <commit id for D> <commit id for F1> stage
那么结构将如下所示:
C-----…-----D ---F2’---F3’ stage
/ \
A---…---B---…---E---…---G master
\ \
F----…----H prod
所以我们最终做的就是删除分支 stage
并从当前 master
创建一个新分支 stage
。这样所有未合并的功能都被删除,并且因为所有功能分支仍然存在,它们也仍然可以合并到新的 stage
分支。
因此,我们将一些我们知道目前正在等待客户接受的分支合并回 stage
,并摆脱了所有废弃的功能。
我们有一个 master
分支和许多短期特性分支,在客户接受更改后合并到 master
。
除此之外,我们还有用于用户验收系统和生产系统的长期生存环境分支,名为 stage
和 prod
,它们最初是从 master 分支出来的。
我们的工作流程是这样的:
- 在功能分支上开发功能
- 将功能分支合并到
stage
- 等待客户验收
- 接受合并到
master
master
第二天被合并到prod
客户接受时间可能很短也可能很长,因此 stage
上有几个 "features" 正在等待接受或被放弃。因为如果客户 不 接受更改,我们不会将该功能合并到 master
但遗憾的是它像僵尸一样继续存在 stage
:)
现在问题:
我们如何将分支 stage
重置为当前 master
而不会失去将仍在等待接受的功能分支再次合并到 stage
的能力?这里的目标是摆脱被遗弃的"features"。
在不改变历史和强制推送的情况下这可能吗?
如果不重写历史,我唯一能想到的就是从废弃的功能中恢复那些提交。
如果您通过真正的合并将特征合并到 stage
中,则很容易恢复这些合并。只需 运行 git revert
在合并提交上,使用适当的 -m
参数(通常是 -m 1
)。
如果您通过复制提交或 fast-forwarding 将功能合并到 stage
中,则更加困难,因为您必须还原每个提交。您可以给 git revert
一个 范围 的提交来还原,它会以适当的顺序执行所有这些操作,即 last-to-first 顺序。请注意,A..B
形式的范围意味着 "everything reachable from B
, except for everything reachable from A
",并且由于 A
显然可以从自身到达,因此 排除 提交 A
本身.因此 1234567..fedcba9
包括提交 fedcba9
和更早的提交回 1234567
但 排除 1234567 本身。
如果您使用 git merge --squash
将功能合并到 stage
,这会将所有提交复制到一个大的(但独立的)提交中,这样您就可以再次简单地 运行 git revert
在一个复制的提交上(没有 -m
因为它不是合并提交)。
(请注意,无论您如何还原这些,如果您最终发现您毕竟想要该功能,那就有点痛苦了。)
由于所有已批准的功能都已合并到 master 中,因此舞台上第一个未合并的提交是废弃的功能。假设F1、F2、F3是舞台支线等待客户验收的生活特征。 F1 是放弃的特征,F2、F3 是接受的特征。所以它需要在舞台上摆脱F1。
C-----…-----D---F1---F2---F3 stage
/ \
A---…---B---…---E---…---G master
\ \
F----…----H prod
您可以使用以下命令:
git checkout stage
git rebase --onto <commit id for D> <commit id for F1> stage
那么结构将如下所示:
C-----…-----D ---F2’---F3’ stage
/ \
A---…---B---…---E---…---G master
\ \
F----…----H prod
所以我们最终做的就是删除分支 stage
并从当前 master
创建一个新分支 stage
。这样所有未合并的功能都被删除,并且因为所有功能分支仍然存在,它们也仍然可以合并到新的 stage
分支。
因此,我们将一些我们知道目前正在等待客户接受的分支合并回 stage
,并摆脱了所有废弃的功能。