我知道有些人默认使用git pull --rebase,还有一些人坚持不使用。我相信我理解合并和再平衡之间的区别,但我正试图把它放在git pull的上下文中。它只是不想看到大量的合并提交消息,还是有其他问题?
- 针对git pull的建议来源——重新平衡?rebase或git-rebase是独立于git pull的活动——rebase!
我想对"git pull-rebase"的实际含义提供一个不同的观点,因为它有时似乎会丢失。
如果您曾经使用过Subversion(或CVS),那么您可能会习惯于"SVN更新"的行为。如果您有要提交的更改,并且提交失败,因为更改是在上游进行的,那么您将"SVN更新"。颠覆通过将上游变更与您的变更合并来进行,可能导致冲突。
颠覆者刚刚做的,本质上是"拉——再平衡"。重新制定与新版本相关的本地更改的行为是它的"重新平衡"部分。如果在提交尝试失败之前执行了"svn diff",并将结果diff与随后的"svn diff"输出进行比较,则两个diff之间的差异就是重新平衡操作所做的。
在这种情况下,Git和Subversion之间的主要区别在于,在Subversion中,"您的"更改仅作为工作副本中未提交的更改存在,而在Git中,您在本地有实际提交。换句话说,在Git中,你已经分叉了历史;你的历史和上游的历史已经分化了,但是你有一个共同的祖先。
在我看来,在通常情况下,让您的本地分支仅仅反映上游分支并对其进行持续开发,正确的做法始终是"重新平衡",因为这就是您在语义上实际所做的。你和其他人正在窃取一个分支的预期线性历史。事实上,有人在你尝试推之前稍微推了一下,这是无关紧要的,而且对于每一次这样的时间事故来说,导致历史上的合并似乎都是适得其反的。
如果你真的因为任何原因觉得有必要做一个分支,在我看来这是一个不同的问题。但是,除非您有一个特定的、积极的愿望以合并的形式来表示您的更改,在我看来,默认行为应该是"git pull——rebase"。
请考虑其他需要观察和了解您的项目历史的人。你想让历史上到处都是成百上千的合并,还是只想选择少数几个代表有意不同开发努力的真正合并的合并?
- @要说清楚,我不是说Git(工具)应该默认为Rebase。那将是危险的,因为一根钢筋基本上会破坏历史。我是说,在工作流方面,当您不打算进行分支,而只是黑客攻击其他人正在处理的某个分支时,"git pull--rebase"应该是用户的默认行为。
- 你是说一个不应该是git config --global branch.autosetupmerge always吗?
- @Marcelocantos不,我不是;)我个人会将autosetupmerge设置为默认值true(如果我在本地<->remote之外的分支之间进行第四次和第四次合并,我希望它是明确的)。我只是说,作为一个人,我总是使用"git pull--rebase"作为我正常的"在主分支中获取最新的"工作流的一部分,因为我从不希望创建合并提交,除非我显式地进行分支。
- 哦!我是说...autosetuprebase...。
- +1@scode.在苦苦挣扎了好几个小时之后,终于有了一个答案。
- 这个答案只是试图让非分布式版本控制系统用户适应Git,而不是让他们有机会正确理解拥有适当分支的好处。
- 这是一个很好的答案,并且很好地解释了这个概念。
- 这应该是公认的答案……
- 令人惊叹的!我在一家公司工作,该公司的策略是cherry-pick-not-merge或pull请求,因此本地分支机构必须反映远程,我们应该在推送之前始终"更新"本地分支机构,以避免代码审查工具中的冲突。我总是明确地使用git fetch && git rebase,它和git pull --rebase做同样的事情吗?
你应该使用git pull --rebase当
事实上——那为什么不呢?更清楚的是,它不会对您的提交进行逻辑分组。
好吧,我想需要澄清一下。在Git中,正如您可能知道的,我们鼓励您进行分支和合并。您的本地分支(您将更改拉入其中),而远程分支实际上是不同的分支,而git pull是关于合并它们的。这是合理的,因为您不经常推送,并且通常在它们构成一个完整的特性之前积累一些更改。
然而,有时——不管什么原因——你认为如果这两个——远程和本地——是一个分支,实际上会更好。就像在SVN。正是在这里,git pull --rebase开始发挥作用。您不再合并——实际上是在远程分支的顶部提交。这就是它真正的意义所在。
它是否危险是一个问题,你是否把本地和远程分支视为一件不可分割的事情。有时候这是合理的(当您的变更很小时,或者如果您正处于一个健壮的开发的开始时,当重要的变更是由小的提交带来的时候)。有时不是这样(通常你会创建另一个分支,但你太懒惰了,不能这样做)。但这是另一个问题。
- 我认为当您在同一个分支上工作时,它是有用的,但是您可以更改您的工作站。我倾向于从一个工作站提交和推送我的更改,然后在另一个工作站中拉入REBASE,并继续在同一个分支上工作。
- 使用git config --global pull.rebase preserve设置git以在拉动时自动重新平衡是一个有用的最佳实践(Preserve说,除了启用重新平衡之外,如果在本地进行了任何合并,还尝试保留合并)。
- 我不同意只在处理一个分支时使用pull-rebase。你应该一直使用它,除非因为其他情况不可能。
- @嘘…'然而,有时——无论出于什么原因——你认为如果这两个——远程和本地——是一个分支——实际上会更好——可以做到吗?我的理解是,在本地环境中,我可以使用分支和远程分支镜像作为源/主。你能在这里提供输入吗?
也许最好的解释方法是举个例子:
Alice创建了主题分支A,并处理它
Bob创建了无关的主题分支B,并处理它
艾丽丝做的是埃多克斯1〔0〕。主控形状已经是最新的。
Bob做git checkout master && git pull。主控形状已经是最新的。
艾丽丝做埃多克斯
Bob做git merge topic-branch-B。
鲍勃在艾丽丝面前做埃多克斯(4)
Alice做的是git push origin master,这是被拒绝的,因为它不是一个快速前进的合并。
Alice查看origin/master的日志,发现commit与她的无关。
艾丽丝做埃多克斯(6)
Alice的合并提交被取消,Bob的提交被取消,Alice的提交在Bob的提交之后应用。
Alice做了git push origin master,每个人都很高兴,他们在将来查看日志时不必读取无用的合并提交。
请注意,要合并到的特定分支与示例无关。本例中的master可以很容易地成为发布分支或开发分支。关键是Alice&Bob同时将本地分支合并到共享的远程分支。
- 很好。我倾向于直截了当和以东(4),如果另一个人对主人的推压发生在我之前,我会重复。尽管我能从你的食谱中看到简洁的优点。
我认为你应该在同一个分支上与其他人合作时使用git pull --rebase。你在你的工作中→提交→工作→提交周期,当你决定推动你的工作时,你的推动被拒绝了,因为在同一个分支上有并行工作。在这一点上,我总是做一个pull --rebase。我不使用squash(扁平提交),但我重新设置了基以避免额外的合并提交。
随着您的Git知识的增加,您发现自己比我使用的任何其他版本控制系统都更关注历史。如果你有大量的小合并承诺,很容易失去历史上发生的更大情况的焦点。
这实际上是我唯一一次重新设定(*)的值,而我的其余工作流程是基于合并的。但是,只要你最频繁的提交者这样做,历史最终看起来会好很多。
(*)在教一门Git课程的时候,有个学生逮捕了我,因为我也主张在某些情况下重新设置功能分支。他已经读过这个答案;)这种重新平衡也是可能的,但它必须始终按照预先安排/商定的系统,因此不应"总是"应用。在那个时候,我通常也不做pull --rebase,这就是问题所在;)
- 当然,可以编写一个脚本来隐藏日志中的合并提交
- 合并也可以包含diff,这意味着它并不完全是微不足道的
- 实际上,它已经存在了:git log --no-merges。
- @是的,但这些合并的内容可能很重要。
- 与所选择的答案相比,这个答案是模糊的,固执己见的:你所说的"同一分支"到底是什么意思?有一些好的观点,但不在选择的答案中。
- "branch"周围的模糊性是有意的,因为使用refs的方法很多;"line of work"只是一个选项。
- @哈森看起来像是EDOCX1[0]只是一个可以轻易避免的问题的解决方案。
我不认为有任何理由不使用pull --rebase--我专门在git中添加了代码,以允许我的git pull命令总是针对上游提交重新平衡。
当回顾历史的时候,我们永远不会感兴趣的是,正在研究这个功能的家伙/女孩什么时候停止了同步。当他/她这样做的时候,这可能对他/她有用,但这就是reflog的目的。这只是给其他人增加噪音而已。
- "当回顾历史时,知道从事该功能的人何时停止同步是一件不有趣的事情。"/但这是否意味着这些中间提交可能是坏的构建?
- 是的,他们也不是一个"完整的国家"。这就是我们不想要它们的原因。我想知道他想要什么,而不是他是怎么到那里的。
- 如果总是使用pull --rebase,为什么不默认使用pull?
- @斯特拉亚,这是我所有回购的默认,但有些人有很大的不同,非常奇怪(对我)的偏好。违约在很多方面都不正确。例如,默认情况下,合并不包括摘要,而且未加注释的标记几乎从来都不是您想要的。
- @达斯汀很感激你的反应和需求,但对我来说,这似乎很奇怪——如果总是使用pull --rebase而不使用pull --rebase是"奇怪的",那么Git应该默认地使用更简单的方法。既然没有,我就怀疑你的说法。
- 恐怕你得形成自己的意见。我有几样东西在我的电脑里,让一些选项做正确的事情。我认为Git-Rebase在默认情况下做了错误的事情,Git标签等也是如此。如果你不同意,你不需要证明你的观点是正确的。
- 如果你从"上游"撤资,比如说从master撤资,如果你进入的分支机构还没有上市(还没有上市),这似乎是一个很好的建议。如果从另一方面将特性分支拉入master,这更像是另一种方法:没有理由使用--rebase,对吗?这可能是它不是违约的原因。我发现钢筋是变化应该如何从层次结构的顶部向下传递,而合并是它们如何向上流动的。derekgourlay.com/blog/git-when-to-merge-vs-when-to-rebase
- @Jolvi我喜欢"我发现重新平衡是变化应该如何从层次结构的顶部向下传递,而合并则是它们如何向上流动"。描述它的好方法。Git的优点在于它适合初学者和高级用户。总是重新平衡不适合初学者。如果你不了解历史,重新平衡是不可能的。但一旦你理解了,你就可以突然使用简洁的命令,展示一个干净的历史。两全其美。
记住:
- 拉=提取+合并
- pull--rebase=fetch+rebase
所以,选择您想要处理分支的方式。
你最好知道merge和rebase的区别:)
我认为归根结底是个人喜好。
你想在改变之前隐藏你的愚蠢错误吗?如果是这样,git pull --rebase是完美的。它允许您稍后将提交压缩为几个(或一个)提交。如果你合并了你的(未公布的)历史,那么做一个git rebase后一个就不那么容易了。
我个人并不介意公布我所有的愚蠢错误,所以我倾向于合并而不是重新平衡。
- 要记住的一件事是:我在问拉车的事。-)
- 我确实记住了:)
- 请注意,任何查看此问题的人:此答案与问题"何时应使用git pull--rebase?"完全无关。
- @Thereakllanni我编辑了答案,以便更清楚地了解它与问题的关系(希望不会破坏意图)。
git pull --rebase可以对合作者git push --force隐藏历史重写。我建议使用git pull --rebase,前提是你知道你忘了在别人之前推动你的承诺。
如果你什么都没做,但是你的工作空间不干净,就在去之前去12号。这样,你就不会默默地重写你的历史了(这可能会使你的一些工作陷入沉默)。