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


805

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


1
有人建议反对git pull --rebase的来源?Rebase或git rebase是 git pull --rebase 分开的活动!
przemo_li

Answers:


583

你应该用git pull --rebase什么时候

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

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


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

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

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


17
我认为在同一分支上工作时很有用,但是您可以更改工作站。我倾向于在一个工作站上提交并推送我的更改,然后在另一个工作站上进行变基,并继续在同一分支上工作。
Pablo Pazos 2015年

11
将Git设置为在拉动时自动变基是一种有用的最佳实践git config --global pull.rebase preserve (保留表示除了启用变基外,如果您在本地进行合并,则尝试保留合并)。
Colin D Bennett

2
我不同意仅在一个分支上工作时才应使用pull --rebase。您应该一直使用它,除非由于其他情况而无法使用。
托马什Fejfar

@P Shved ...'但是,有时-无论出于何种原因-您认为如果将这两个-远程和本地-合并为一个分支实际上会更好''...可以做到这一点吗?在本地环境中,我可以将我的分支和远程分支镜像作为源/主服务器。能否请您在这里提供输入?
Mandroid

736

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

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

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

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

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

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

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


18
@MarceloCantos要明确,我并不是说git(该工具)应默认为变基。这将是危险的,因为改组实质上会破坏历史。我的意思是,就工作流而言,当您不打算分支而只是在其他人也正在从事的某个分支上乱砍时,“ git pull --rebase”应该是用户的默认行为。
SCODE

1
您是说不应该git config --global branch.autosetupmerge always吗?
Marcelo Cantos

9
@MarceloCantos否,我不是;)就我个人而言,我将autosetupmerge保留为t​​rue的默认值(如果我在除local <-> remote之外的分支之间进行第四次合并,我希望它是明确的)。我只是说,作为一个人类,我总是使用“ git pull --rebase”作为我正常的“在主分支中获取最新信息”工作流的一部分,因为除非明确分支,否则我永远都不想创建合并提交。
SCODE

9
+1 @scode。经过数小时的苦苦思索的rebase / merge问题,终于有了一个可以解决问题的答案。
AgileYogi 2012年

10
这个答案只是使非分布式版本控制系统用户适应Git的尝试,而不是让他们有机会正确理解拥有适当分支的好处。
Alexey Zimarev 2013年

211

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

  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. 爱丽丝(Alice)这样做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正在同时将其本地分支合并到共享的远程分支。


2
真好 我倾向于表述得很清楚,git co master && git pull; git checkout topic-branch-A; git rebase master; git checkout master; git merge topic-branch-A; git push origin master如果别人的推动力发生在我的面前,我会重复一遍。虽然我可以在您的食谱中看到简洁的优势。
HankCa '17

很好的解释@Cody Poll
Rajanikanta Pradhan

148

我认为git pull --rebase与同一个分支上的其他人协作时应该使用。您处于工作→提交→工作→提交周期,并且当您决定推送您的工作时,您的推送被拒绝,因为在同一分支上存在并行工作。在这一点上我总是做一个pull --rebase。我不使用squash(展平提交),但我重新设置基准以避免额外的合并提交。

随着Git知识的增加,您发现自己对历史的了解要比我使用过的任何其他版本控制系统都要多。如果您有大量的小型合并提交,则很容易失去对历史上正在发生的大局面的关注。

实际上,这是我唯一一次进行rebasing(*)的时间,其余的工作流基于合并。但是,只要您最频繁的提交者这样做,历史最终就会好得多。

(*)在教授Git课程时,有一位学生因此而被捕,因为在某些情况下我还主张重新设置要素分支。他已经读过这个答案了;)这样的重新定基也是可能的,但是它总是必须根据预先安排的/商定的系统进行,因此不应“始终”应用。那时我通常都不做pull --rebase,这就是问题所在;)


2
当然,可以编写一个脚本来隐藏日志中的合并提交
Hasen

3
合并也可能包含差异,这意味着它并不完全无关紧要
krosenvold 2010年

9
@hasen j是,但是这些合并的内容可能很重要
krosenvold 2010年

与选择的答案相比,该答案含糊且含蓄:您所说的“相同分支”到底是什么意思?有一些优点,但是不在所选答案中。
iwein 2011年

1
围绕“分支”的模糊性是故意的,因为有很多使用引用的方法。“工作线”只是一种选择。
krosenvold

49

我认为没有理由使用它pull --rebase-我在Git中添加了代码,专门用于使我的git pull命令始终根据上游提交进行基准调整。

查看历史记录时,知道从事该功能的人/男何时停止同步就变得很有趣。这对男/女在他/她这样做时可能很有用,但这就是reflog目的。这只是给其他所有人增加了噪音。


2
“回顾历史时,知道从事该功能的人何时停止同步就变得很有趣。” /但这是否意味着这些中间提交很可能是损坏的版本?
eglasius 2011年

10
是的,它们也不是“整个状态”。这就是为什么我们不想要它们。我想知道他想要什么,而不是他如何到达那里。
达斯汀

4
如果pull --rebase应该始终使用,pull默认情况下为什么不这样做?
straya

2
恐怕您将不得不形成自己的意见。我有几件事情.gitconfig要使某些选项做正确的事情。我认为git rebase在默认情况下会做错事,git tag等也是如此。如果您不同意,则无需证明自己的观点。
达斯汀

8
如果您从“上游”拉出,例如从master,这似乎是个好建议,并且如果您进入的分支尚未公开(还)。另一方面,如果您从功能分支中拉入master,则更像是相反:永远没有理由使用--rebase,对吧?这可能就是为什么它不是默认值的原因。我发现Rebases是更改应如何从层次结构的顶部向下传递,而合并是它们如何向上流动。 derekgourlay.com/blog/git-when-to-merge-vs-when-to-rebase
jolvi '16

38

只记得:

  • 拉=提取+合并
  • pull --rebase =获取+重新设置

因此,选择处理分支的方式。

您最好知道merge和rebase之间的区别:)


9

我认为这归结为个人喜好。

您要隐藏您的愚蠢错误,然后再进行更改吗?如果是这样,那git pull --rebase是完美的。它允许您稍后将提交压缩为几个(或一个)提交。如果您在(未推送的)历史记录中进行了合并,那么进行下一个合并并非易事git rebase

我个人不介意发布所有愚蠢的错误,因此我倾向于合并而不是重新设置基础。


8
请注意查看此问题的任何人:该答案与“我何时应使用git pull --rebase?”这个问题完全无关。
therealklanni 2014年

3
@therealklanni我编辑了答案,以使它与问题的相关性更加清晰(希望在不破坏意图的情况下)。
圣保罗Ebermann

共享肮脏且无组织的工作日志不是诚实的努力,而只是懒惰。通过使人们追赶您进行开发和调试的麻烦,您正在浪费人们的时间。给他们结果,而不是杂乱无章。
krystah

8

git pull --rebase可能隐藏合作者的历史改写git push --force。我建议git pull --rebase 在您知道在其他人之前先不提交提交的情况下使用。

如果您什么也没做,但是您的工作空间不干净,就git stash在之前git pull。这样,您将不会默默地重写您的历史记录(这可能会默默地删除您的某些工作)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.