为什么git pull合并是默认行为?

8
通常在使用git更新本地仓库中的新提交时,我们会使用git fetch和git rebase命令。但是我们不使用git fetch git merge命令。通常,原因是我们不想添加新的提交(合并提交),只是想在我们的代码顶部获取所有新的提交。那么为什么git pull的默认行为不是使用合并呢?我知道我们可以更改它,但是否有更好的理由使用fetch-merge而不是fetch-rebase?

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Maroun
2个回答

12
我假设你的问题是为什么使用git pull时,默认行为是合并而不是变基合并拉取的更改。
答案相当简单:变基会重新创建正在被变基的提交。这些新的提交对象将替换旧的提交。但是这些新提交与旧的提交完全不兼容。这会导致之前已经拉取了原始提交的所有其他用户拥有与你刚刚重新创建的变基提交不兼容的提交。因此,您有两个冲突版本,主要变化相同。通常这意味着有很多问题,因为您需要手动修复这些冲突(通过指定要保留哪个版本来解决冲突;因此如果您进行了变基,其他人都需要手动放弃旧版本)。
这也是为什么您永远不应该变基已发布的提交。
所以默认的解决方案是合并,因为合并是一个完全安全的操作,不会引起冲突。合并提交只是将提交添加到历史记录中,但不会替换现有的历史记录。是的,它可能会使历史记录变得更加复杂,但它完全透明且与之前存在的所有版本兼容。
当然,在某些情况下,变基是没有问题的。特别是如果您在本地工作并且有一些未发布的更改,并且想要更新您的存储库。然后,获取和变基您的本地更改是可以的,因为它们只属于您自己,没有其他人知道它们。但这应该始终是一个显式的操作,以便不会出错。这就是为什么变基拉取只是一个选项:git pull -r

Poke,我的问题是当您使用源代码提交更新本地代码时。所以在这种情况下,我猜您建议使用rebase。而我认为,要更新本地代码,应该使用“pull”,对吗?而且“pull”不会执行“rebase”。除了更新本地代码之外,您不会在其他情况下使用“pull”,对吗? - Narek
1
你可以使用 git pull -r 命令来将本地修改进行变基(rebase),而不是合并它们(这本质上与先使用 fetch 再进行变基相同,但更简短)。但是,你只应该对没有其他人接收到的 本地 修改使用此命令。在所有其他情况下(以及当你有疑问时),只需使用 git pull 命令进行合并即可。 - poke
为了合并,我会使用fetch-rebase来获取两个分支并进行合并。这样做不是最优的吗?在本地仓库合并分支时,我应该使用pull命令吗? - Narek
如果你想要变基的提交只存在于本地,并且从未发布过,那么你可以进行变基操作。否则,就执行合并操作。(pull等同于拉取和合并;pull -r等同于拉取和变基) - poke
1
@JonathanBenn 当您可以像快进一样快速前进时,就不会发生变基,就像在使用合并解决策略拉取时没有发生合并一样,当拉取可以快速前进时也没有发生合并。- 答案(和问题)假设您有分叉的本地和远程分支的情况。 - poke
显示剩余2条评论

3

我认为默认情况下它的工作方式是为了避免重写本地历史记录并更改现有提交的哈希值。这些提交可能已经被推送到远程。 rebase 是一种破坏性的命令,从远程拉取更改默认情况下不应该破坏任何东西。

您可以使用 git pull --rebase 或者创建别名来执行此操作。


但是,如果您添加新的合并提交,则会影响历史记录。因为在源中不存在该合并提交。 - Narek
@Narek 我的意思是现有的提交记录不应该被更改。 - Stas
2
@Narek,在分支的顶端添加一个新提交(新合并提交)和重写现有提交以具有新哈希值(变基)之间存在很大的区别。 - Chris
@Chris 在从本地分支上的 origin 进行 rebase 操作后,提交的 SHA-1 值仍然保持不变,对吗? - Narek
1
@Narek 它会更改您本地(尚未推送)提交的哈希值,因为它们基于新的代码库(您刚刚拉取的代码库)。如果您在中央存储库方案中使用 git(例如替代 CVS/SVN),通常需要执行 git pull --rebase,因为在这种情况下合并提交是无用的。 - Stas
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接