如何将 long 运行 git 分支重置为 master?

How to reset long running git branch to master?

我们有一个 master 分支和许多短期特性分支,在客户接受更改后合并到 master

除此之外,我们还有用于用户验收系统和生产系统的长期生存环境分支,名为 stageprod,它们最初是从 master 分支出来的。

我们的工作流程是这样的:

客户接受时间可能很短也可能很长,因此 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,并摆脱了所有废弃的功能。