gpt4 book ai didi

git - 使用 merge 的提交重新设置Git

转载 作者:太空狗 更新时间:2023-10-29 13:58:04 24 4
gpt4 key购买 nike

不确定这是否是重复的,但花了几乎一天的时间试图找到一个整洁的解决方案,但还没有找到答案。
我的git repo状态如下:

      C---D---E  feature-branch
/
A---B---C---D---X---F master
|
Reverts C and D

我一直在做 feature-branch的工作,而提交的 C& D意外地合并为master(复杂的故事)。其他正在处理repo的人会恢复那些提交,因为它会中断构建。
现在,在提交 E之后,我想将功能分支与当前主分支重新定位。但问题是,由于提交 C& D已经存在于主节点中,因此在重新调整基址时不会包含这些提交。
来自Git手册页:
如果上游分支已经包含您所做的更改(例如,因为您邮寄了一个应用于上游的修补程序),则将跳过该提交。例如,在以下历史记录上运行git rebase master(其中a'和a引入相同的更改集,但具有不同的提交者信息):
      A---B---C topic
/
D---E---A'---F master

将导致:
               B'---C' topic
/
D---E---A'---F master

既然commit C还原了更改,我现在如何才能包括提交 D& X(可能有一个新的sha)?

最佳答案

tl;dr:你可以用命令做你想做的事情,比如

git rebase --onto master feature-branch~3 feature-branch

(其中 feautre-branch~3在示例中有效,但通常是解析为commit B的任何表达式,例如 B的commit散列等)
要知道为什么这样做,请继续阅读…
首先,我们应该澄清一下你的图表。你说过
我一直在功能分支上工作,commits c&d偶然合并为master(复杂的故事)。其他正在处理repo的人会恢复那些提交,因为它会中断构建。
(强调补充)。现在merge可以做两件事之一[1],但复制提交 CD不是其中之一。默认行为如下所示:
A -- B -- C -- D -- !CD -- F <-(master)
\
E <-(feature-branch)

由于意外合并时 master显然是 ,默认行为将是 B到现有 master提交的“快进”。就好像 D手是在 feature-branch之后才被创造出来的。
(我也做了一些符号的修改。 D表示还原为 !CDC的合并(不需要注释)。我发现用这种方法画线更容易阅读。但重要的是 DC是如何表示的…)
另一种可能性是,如果您使用了 D选项(或者如果 --no-ff在合并之前已经从 master中分离出来),那么看起来更像
       C - D -- E <--(feature-branch)
/ \
A -- B ----- M -- !CD -- F <--(master)

同样, feature-branch不会复制 mergeC;相反,它会创建一个“合并提交” D,将 MC中的更改合并到 D的历史中(并使 masterC中的“可访问”)。
在这两种情况下,合并后 Dmaster之间的“合并基”是 feature-branch。因此,您必须解决两个问题:文档中描述的“重复修补程序ID”问题;合并基位于排除提交的点上,因为 master甚至不考虑从上游复制已经可以访问的提交。[2]
通常只解决“合并基”问题是有用的。最后,我们将了解为什么您不必为了您的目的而这样做,但为了完整起见,您可以这样做:
首先找到一个解析为commit D的表达式(如上面的示例中commit has for rebaseB)。在命令中使用它,比如
git rebase -f feature-branch~3 feature-branch

这将复制提交 Bfeature-branch~3C,以便
                 E
/
A -- B -- C -- D -- !CD -- F <-(master)
\
C' -- D' -- E' <-(feature-branch)

D技术上仍然存在但不可达,最终可能被 E破坏)。当然,这假设是“快进”情况;如果您有一个合并提交,它看起来会不同,但结果是一样的。
结果是,现在可以毫无问题地将 E合并到 gc中。但是如果你想 feature-branch masterrebase(为快速前进做准备),那么你仍然需要解决你指出的原始问题: feature-branchmaster将作为 C'D'的副本被跳过。
您想要的是阻止补丁id重复检查;虽然似乎没有实际的选项,但是您可以通过让git不知道在哪里查找重复项来实现。与其将 C作为上游,不如将commit D作为上游;然后再将 master作为基础。
git rebase --onto master feature-branch~3 feature-branch

当您发出此命令时, B不仅没有理由考虑 --onto mastergit,而且因为您不再使用 C作为上游, D-to- master合并基不再重要。你明确地说 master是你的上游,所以这同时解决了这两个问题-这就是为什么,正如我上面提到的,你最终不必担心 feature-branch命令。
[1]实际上,它至少可以做第三件事。如果您指定了 B选项,那么它不会进行真正的合并,而是在 rebase -f上创建一个新的commit --squash。这基本上与通常创建的合并提交相同,只是它不包括作为父级的 CD
       C - D -- E <--(feature-branch)
/
A -- B ----- CD -- !CD -- F <--(master)

这在某些特定情况下是有用的,但一般来说,我不建议这样做,因为git“忘记”了 masterDC中已经被“考虑”了这一事实。在你的情况下,这会很好的解决-这就是为什么我知道你没有这样做,也没有包括在答案的主要文本的可能性。但在大多数情况下,这使得分支之间的未来交互更加困难。
[2]这些问题看似相似,但却是截然不同的。在一种情况下, D本身已经可以从您要重新定位的上游访问;在另一种情况下,它不是,但是引入相同更改的另一个提交是。

关于git - 使用 merge 的提交重新设置Git,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51194261/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com