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

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

你应该使用git pull --rebase时候

  • 你的改变不值得一个单独的分支

确实 – 为什么不呢? 更清楚的是,不会在您的提交中强加一个逻辑分组


好吧,我想这需要一些澄清。 在Git中,你可能知道,鼓励你分支和合并。 你所在的本地分支,以及远程分支,实际上是不同的分支,而git pull则是关于它们的合并。 这是合理的,因为你不太经常推动,通常积累一些变化,才构成一个完整的function。

但是,有时 – 无论出于什么原因 – 你认为如果这两个遥远的地方是一个分支,情况会更好。 像在SVN中一样。 在这里git pull --rebase发挥作用。 你不再合并 – 你实际上在远程分支上进行提交 。 这就是它的实际情况。

无论危险与否,您是否将本地与远程分支视为一个不可分割的东西。 有时这是合理的(当你的变化很小,或者如果你刚刚开始一个强大的开发,当小的提交带来重要的变化时)。 有时不是(当你通常创build另一个分支,但你太懒了)。 但这是一个不同的问题。

我想提供一个不同的angular度来看“git pull –rebase”究竟意味着什么,因为它似乎有时会迷失方向。

如果你曾经使用过颠覆(或CVS),你可能习惯了“svn update”的行为。 如果你有更改提交,并提交失败,因为已经做了上游改变,你“svn更新”。 Subversion通过合并上游的变更,从而导致冲突。

颠覆者刚刚做了什么,实质上是“拉回”。 重新制定你的本地变化是相对于较新版本的行为是“重新定位”的一部分。 如果在失败的提交尝试之前完成了“svn diff”,之后将得到的diff与“svn diff”的输出进行比较,那么两次差异之间的区别就是重新构build操作所做的。

在这种情况下,git和subversion之间的主要区别是,在subversion中,“你的”更改只存在于工作副本中未提交的更改中,而在git中则有本地实际的提交。 换句话说,在git中,你分叉了历史; 你的历史和上游历史已经分歧,但你有一个共同的祖先。

在我看来,在你的本地分支只是简单地反映上游分支并对其进行持续开发的正常情况下,正确的做法总是“–rebase”,因为这就是你在语义上实际做的事情 。 你和其他人正在窃取分支的预期线性历史。 事实上,在你试图推行之前,其他人碰巧推迟了这一事实是无关紧要的,而且每次这样的事故导致历史上的合并似乎都是反效果的。

如果你真的觉得无论出于什么原因都需要某个分支,那么在我看来这是一个不同的问题。 但是,除非你有一个具体和积极的愿望,以合并的forms来expression你的改变,否则在我看来,默认行为应该是“git pull –rebase”。

请考虑其他需要观察和了解项目历史的人。 你是否希望历史上遍布着数以百计的合并历史,还是只想要有意合并的有意识的发展努力的less数合并?

我想你应该使用git pull --rebase与其他分支进行协作。 你在工作 – >提交 – >工作 – >提交周期,当你决定推动你的工作时,你的推送被拒绝,因为在同一个分支上有同样的工作。 在这一点上,我总是做一个拉 – 基地。 我不使用压扁(扁平提交),但我rebase避免额外的合并提交。

随着你的git知识的增加,你会发现自己在历史上比其他任何vcs都要多。 如果你有很多小的合并提交,很容易失去你历史上发生的更大的事情的焦点。

这实际上是唯一一次重新绑定(*),而我的工作stream程的其余部分是基于合并的。 但是只要你们最频繁的提交者这样做,最后历史看起来好多了。

—编辑:(*)在教一个git课程的时候,我有一个学生把我逮捕了,因为我也提倡在某些情况下重新设置特色分支。 他已经读了这个答案;)这种重新设定也是可能的,但总是必须按照预先安排/同意的制度进行,因此不应该“总是”应用。 而那个时候我通常也不会做拉 – 拉基,这就是问题所在;)

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

  1. Alice创build主题分支A,并对其进行处理
  2. 鲍勃创build不相关的主题分支B,并在其上工作
  3. Alice做git checkout master && git pull 。 师父已经是最新的了
  4. 鲍勃做git checkout master && git pull 。 师父已经是最新的了
  5. Alice做混合git merge topic-branch-A
  6. 鲍勃没有git merge topic-branch-B
  7. Bob在Alice之前做git push origin master
  8. 爱丽丝做混合git push origin master ,这是拒绝,因为它不是一个快进合并。
  9. Alice查看origin / master的日志,并看到提交与她无关。
  10. 爱丽丝做混合git pull --rebase origin master
  11. Alice的合并提交被解除,Bob的提交被提取,Alice的提交被应用在Bob的提交之后。
  12. Alice是git push origin master ,每个人都很高兴,他们在将来查看日志时不必阅读无用的合并提交。

请注意,合并到的特定分支与示例无关。 在这个例子中的硕士可以很容易地是一个发布分支或开发分支。 关键是Alice&Bob同时将他们的本地分支合并到一个共享的远程分支上。

我不认为有没有理由使用pull --rebase – 我添加代码专门git pull允许我的git pull命令始终rebase上游提交。

当浏览历史时,知道何时在该function上工作的人停止同步是无关紧要的。 这对他来说可能是有用的,但是这就是reflog的作用。 这只是增加了其他人的噪音。

只要记住:

  • 拉=取+合并
  • 拉–rebase = fetch + rebase

所以,select你想要处理你的分支的方式。

你最好知道合并和rebase之间的区别:)

我认为这归结于个人偏好。

推送您的更改之前,您是否想隐藏您的愚蠢的错误? 如果是这样, git pull --rebase是完美的,它允许你稍后git pull --rebase你的提交几个(或一个)提交。 如果你已经在你的(没有logging的)历史中合并,那么稍后再做一次git rebase并不是那么容易。

我个人不介意发表我所有的愚蠢的错误,所以我倾向于合并而不是重组。

git pull --rebase可能会隐藏来自合作者git push --force的历史重写。 我build议使用git pull --rebase 只有当你知道你忘记推送你的提交之前,别人也一样。

如果你没有提交任何内容,但是你的工作空间不干净,只需要把它git stash就可以了。 这样,你不会默默地重写你的历史(这可能会默默地放弃你的一些工作)。