Git 的规则是,在共享、发布或推送后,您永远不应尝试更改历史记录。当然,如果你真的想要并且拥有足够的权限,你可以这样做,但应该非常小心,因为它可能会搞砸其他人。
现在幸运的是,当您拥有一个具有单个上游存储库(源)的典型 Git 部署时,这是宇宙中所有美好和真实的源泉,您可以尽情使用 git pull --rebase,这将是完美的安全,在我看来给你一个更理智(意思是线性)的历史。我和我的团队一直在使用它。
但是,如果您开始拥有多个遥控器并开始执行 git pull --rebase <arguments> 以便您不再每次都针对同一个目标进行重新定位,或者开始将您的分支推送到备用存储库之前运行 @987654323 @ 与你的主要上游 - 然后你就可以开始遇到麻烦了。
任何时候您与另一个远程/存储库共享您的更改,然后更改这些更改(对于更改的值等于更改 SHA、父级等,即使提交消息/内容没有更改),您可能会搞砸把有旧变化的人扶起来。
只要您不超出 rebase 理智的范围,git pull --rebase 将非常适合您。
那个,呃,没有回答关于git pull --rebase 和git fetch && git rebase @{u} 之间区别的问题。我会继续说我不知道有什么区别,如果有的话,那已经足够微妙了,以至于我在使用 Git 的这些年里都没有注意到它。如果您有多个存储库并且“来源”不是该分支的上游,系统可能会计算出您的分支应该获取的正确存储库?
即使你在使用 git-rebase 时确实出错了,你当然可以使用 git log -g 和/或 git reset --hard ORIG_HEAD 轻松地将自己恢复到原来的 rebase 前环境。只是不要强制推送(几乎所有 Git 服务器默认不允许),你会很高兴的。
已编辑
随着时间的推移,我的理解有所扩展。 git pull --rebase 调用 git rebase 进行变基工作,因此从这个意义上说,它们之间没有区别。但是,git-pull 实际上调用git rebase --onto @{u} $(git merge-base HEAD @{u}@{1})
好的,那个语法 ("@{u}@{1}") 可能有点不透明,并且可以简化引导,但关键是它找出了上游的合并基础是什么BEFORE 它运行了 fetch 命令。你问这有什么不同?
嗯,在正常情况下没有。但是,如果您要更改上游指向的位置,或者上游本身已重新设置基础,则相当多。如果上游被重写,然后您执行了git rebase @{u},您可能会非常不高兴,并且可能会出现双重提交或冲突,具体取决于旧提交被重写的程度。
但是,git pull --rebase 背后的魔力只有你自己的提交才会应用到 @{u} 之上。
好的,这也是一个简化。如果上游从之前的 100 次提交开始进行变基(但实际上历史上有 101 次以上的提交)并且你做了一个git fetch 之前做了一个git pull --rebase 然后Git 将无法准确确定正确的历史合并库是什么来确定您的本地提交是什么。
其结果是,git fetch 被认为是有害的(当您有本地提交并且上游被重写时)。然而,真正的经验法则是“在历史被共享、发布或推送后,永远不要试图改变它”,这就是我开始的地方。
TL;DR:
git fetch 被认为是有害的(所以使用git pull --rebase);并且在共享、发布或推送后切勿尝试更改历史记录(因为除其他外,这会导致 git fetch 有害)。