git 为什么我需要一个强制推后,一个rebase?

brjng4g3  于 10个月前  发布在  Git
关注(0)|答案(3)|浏览(88)

我读了很多关于变基后的强制推送的文章,但我仍然不理解所有的东西。
我不清楚的是,rebase是以何种方式重写git历史的。
假设处于这种情况:

所以有一个main分支,在某个时候我从提交d(在main分支上)创建一个新分支(feat1)。然后I 4提交(eh)。与此同时,其他人继续在main上工作,并推送提交il
现在我准备在main上重定feat1分支的基,所以在执行之前,我拉main

git checkout main
git pull --rebase
git checkout feat1
git rebase main

现在的情况是这样的:

我解决(如果是)冲突,并测试一切都按我预期的那样工作。太棒了,太完美了。
现在我想推我的分支,但我不能。因为我做了一个变基,我需要做力推。为什么?为什么?
我为什么要重写git历史?

4nkexdtk

4nkexdtk1#

如果你在变基之前将你的修改向上游推送到你的特性分支,那么你的本地副本将与上游的顺序不同--因此需要强制推送。
然而,如果你把你的本地副本合并到主分支上,这将是一个只允许快进的合并,所以可以不需要强制地将其向上推到主分支上。

brvekthn

brvekthn2#

第二个图中的e与第一个图中的e不是同一个提交。它可能 * 做出相同的更改 *(尽管不一定),它可能有相同的消息(尽管不一定),但它的祖先和树的内容都不同,所以它是一个不同的提交。同样地,第二个f不可能与第一个f相同,这同样适用于gh。通常,人们在解释换基时会将第二个图中的黄色提交表示为e'f'g'h',以显示差异。
当你去推时,上游有h,你推h'h'h不是同一个提交,也不是h的后代(我们不能通过在h上添加更多提交来达到h'),所以这被称为“非快进”推送。
h作为feat1发布的时候,其他人可能已经做了更多的提交ij,从h开始。在你推送h'之后,它们留下的提交仍然是h的后代,而h不再是feat1的一部分(可能不再是任何分支的一部分)。对他们来说,修复这种情况实际上并不困难(这只是另一个rebase,使用--onto),但这是一个烦恼,它迫使人们停下来弄清楚发生了什么,所以git在你的路上设置了一个路障,以确保这是你真正想要做的事情。

8cdiaqws

8cdiaqws3#

当你在main分支的顶部重定基新创建的提交时,在@hobbs回答中可以看到很好的解释。
你现在应该明白了,在你的特性分支中,当你的推送成功时,新提交ile'f'g'h'将替换旧提交efgh

普通的分支推送只能在现有提交的基础上添加新提交(我们称之为快进),以确保您不会错误地丢失数据。

所以git迫使你强制push来确保你完全意识到你正在重写历史,你会丢失一些提交(那些被替换的)。这是为你准备的,因为你已经创造了类似的东西。

相关问题