gpt4 book ai didi

git:为什么我不能在 Squash merge 后删除我的分支?

转载 作者:IT王子 更新时间:2023-10-29 01:26:48 26 4
gpt4 key购买 nike

我有一个带有 mainline 的 git 仓库(相当于 master )和一些局部特征分支。例如:

$ git branch
* mainline
feature1
feature2
feature3

当我执行以下操作时,我能够将我在功能分支中的所有编辑 merge 到一个对 mainline 的提交中。 :
$ git checkout mainline
$ git pull
$ git checkout feature1
$ git rebase mainline
$ git checkout mainline
$ git merge --squash feature1
$ git commit
$ git push

我的问题是,此时,当我尝试删除 feature1 时分支,它告诉我它没有完全 merge :
$ git branch -d feature1
error: The branch 'feature1' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature1'.

是什么导致了这个错误?我以为 git merge --squash feature1 merge feature1进入 mainline .

最佳答案

发生这种情况是因为 Git 不知道 Squash merge “等同于”各种特定于分支的提交。必须强行删除分支,用git branch -D而不是 git branch -d .

(剩下的只是关于为什么会这样。)

绘制提交图

让我们绘制(部分)提交图(这一步适用于 Git 中的很多事情......)。事实上,让我们再退一步,让我们先于您的git rebase开始。 ,像这样:

...--o--o--o     <-- mainline
\
A--B--C <-- feature1

分支名称,如 mainlinefeature1 , 仅指向一个特定的提交。该提交指向(向左)前一个提交,依此类推,正是这些向后的指针形成了实际的分支。

最上面一行提交,都只是叫 o在这里,有点无聊,所以我们没有给他们字母名称。提交的底行, A-B-C , 仅在分支 feature1 . C是最新的此类提交;它返回到 B ,返回 A ,这又回到了一个无聊的地方 o提交。 (顺便说一句:最左边的 o 提交,以及 ... 部分中的所有早期提交,都在两个分支上。)

当你跑 git rebase ,三 A-B-C提交被复制到附加到 mainline 提示的新提交中,给我们:
...--o--o--o            <-- mainline
\ \
\ A'-B'-C' <-- feature1
\
A--B--C [old feature1, now abandoned]

新款 A'-B'-C'提交大部分与原始三个相同,但它们在图中移动。 (请注意,所有三个无聊的 o 提交现在都在两个分支上。)放弃原来的三个意味着 Git 通常不必将副本与原件进行比较。 (如果原始文件可以通过其他名称访问——例如,附加到旧的 feature1 的分支——Git 可以解决这个问题,至少在大多数情况下。Git 如何解决这个问题的确切细节并不特别这里很重要。)

不管怎样,现在你继续运行 git checkout mainline; git merge --squash feature1 .这会生成一个新提交,它是 feature1 上的三个(或多个)提交的“压缩副本”。 .我将停止绘制旧的废弃的,并调用新的 Squash 提交 S Squash :
...--o--o--o--S         <-- mainline
\
A'-B'-C' <-- feature1

“删除安全”完全由提交历史决定

当你要求 Git 删除 feature1 ,它执行安全检查:“是否 feature1 merge 到 mainline 中?”这种“merge 到”测试纯粹基于图连通性。姓名 mainline提交点数 S ;提交 S点回第一无聊 o提交,这会导致更无聊的 o提交。提交 C'feature1的提示, 无法从 S 访问: 我们不能向右移动,只能向左移动。

将此与“正常” merge 进行对比 M :
...--o--o--o---------M   <-- mainline
\ /
A'-B'-C' <-- feature1

使用相同的测试——“是否可以从 feature1 的提示提交中访问 mainline 的提示提交?”——现在的答案是肯定的,因为提交 M有一个向下和向左提交的链接 C' . (提交 C' 在 Git 内部用语中是 merge 提交 M 的第二个父级。)

但是,由于 Squash merge 实际上并不是 merge ,因此没有来自 S 的连接。返回 C' .

同样,Git 甚至不会尝试查看 S与“相同” A' , B' , 或 C' .但是,如果是这样,它会说“不一样”,因为 S仅与所有三个提交的总和相同。唯一获取途径 S匹配压扁的提交就是只有一个这样的提交(在这种情况下,首先不需要压扁)。

关于git:为什么我不能在 Squash merge 后删除我的分支?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41946475/

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