协慌网

登录 贡献 社区

我什么时候应该使用 git pull --rebase?

我知道有些人默认使用git pull --rebase ,还有一些人坚持不使用它。我相信我了解合并和重新定级之间的区别,但是我试图将其放在git pull的上下文中。只是不想看到很多合并提交消息,还是有其他问题?

答案

我想对 “git pull --rebase” 的实际含义提供不同的看法,因为它有时会迷路。

如果您曾经使用过 Subversion(或 CVS),则可能会习惯于 “svn 更新” 的行为。如果您有要提交的更改,并且由于在上游进行了更改而导致提交失败,则可以 “svn 更新”。颠覆是通过将上游变更与您的变更合并而进行的,有可能导致冲突。

Subversion 所做的基本上是 “拉 --rebase”。将本地更改重新构造为相对于较新版本的操作是该操作的 “基础” 部分。如果您在失败的提交尝试之前完成了 “svn diff”,然后将生成的 diff 与之后的 “svn diff” 的输出进行比较,则这两个 diff 之间的差异就是重新设置基准的操作。

在这种情况下,Git 和 Subversion 之间的主要区别在于,在 Subversion 中,“您的” 更改仅作为未提交的更改存在于您的工作副本中,而在 Git 中,您具有本地的实际提交。换句话说,在 Git 中,您创造了历史。您的历史记录和上游历史记录有所不同,但是您有共同的祖先。

在我看来,在具有当地分行只是反映了上游分支并在其上做持续发展的正常情况下,做正确的事永远是 “--rebase”,因为那是你在语义上实际什么。您和其他人正在破坏分支的预期线性历史记录。有人在您尝试进行推送之前碰巧稍稍推动了这一事实是无关紧要的,并且对于每次这样的时间错误事件(导致历史合并)似乎都适得其反。

如果您实际上出于某种原因感到需要某种东西成为分支机构,那么我认为这是另一个问题。但是,除非您有明确的积极愿望以合并的形式表示您的更改,否则我认为默认行为应为 “git pull --rebase”。

请考虑需要观察和了解您的项目历史的其他人。您是否要在整个地方散布着数百个合并的历史记录,还是只希望选择少数几个合并来表示有意的不同开发工作的真实合并?

您应该在以下情况下使用git pull --rebase

  • 您的更改不值得单独分支

确实 - 为什么不呢?这更加清楚,并且不会对提交进行逻辑分组


好的,我想需要澄清一下。您可能知道,在 Git 中,建议您进行分支和合并。实际上,要将更改拉入的本地分支和远程分支实际上是不同的分支,而git pull就是合并它们。这是合理的,因为您不经常推送,并且通常会在构成完整功能之前积累许多更改。

但是,有时,无论出于何种原因,您都认为如果将远程和本地这两个作为一个分支实际上会更好。就像在 SVN 中一样。 git pull --rebase在这里起作用。您不再合并 - 您实际上是在远程分支之上提交 。这就是实际上的意思。

危险与否是您是否将本地和远程分支视为一件不可分割的事情。有时这是合理的(当您的更改很小时,或者如果您处于健壮的开发的开始时,当小的提交带来重要的更改时)。有时不是(通常创建另一个分支,但您懒得这么做)。但这是一个不同的问题。

也许最好的解释方法是举一个例子:

  1. 爱丽丝创建主题分支 A,并对其进行处理
  2. 鲍勃创建了不相关的主题分支 B,并对其进行处理
  3. 爱丽丝做git checkout master && git pull 。主人已经是最新的。
  4. 鲍勃做git checkout master && git pull 。主人已经是最新的。
  5. 爱丽丝做git merge topic-branch-A
  6. 鲍勃做git merge topic-branch-B
  7. 鲍勃在爱丽丝之前做git push origin master
  8. 爱丽丝做git push origin master ,因为它不是快速合并,所以被拒绝了。
  9. 爱丽丝查看原始 / 母版的日志,发现提交与她的无关。
  10. 爱丽丝做git pull --rebase origin master
  11. Alice 的合并提交被取消,Bob 的提交被撤消,并且在 Bob 的提交之后应用 Alice 的提交。
  12. 爱丽丝做了git push origin master ,每个人都感到高兴的是,他们将来查看日志时不必读取无用的合并提交。

请注意,合并到的特定分支与示例无关。在此示例中,Master 可以很容易地成为 release 分支或 dev 分支。关键是 Alice 和 Bob 正在同时将其本地分支合并到共享的远程分支。