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


当前回答

一个实践案例是当你与Bitbucket PR合作时。 让我们用下面的例子来理解它:

这里有公共关系部门。

然后你决定通过BitBucket GUI用最新的Master分支重新构建PR远程分支。这个操作将改变你的PR的提交id。

因为您已经使用GUI重新创建了远程分支。首先,你必须同步你电脑上的本地分支和远程分支。

在这种情况下,git pull -rebase就像魔法一样有效。

在git pull -rebase之后,你的本地分支和远程分支具有相同的历史和相同的提交id。

那么现在,如果您向PR分支添加一个新的提交/更改。

你可以很好地推送一个新的提交,而不需要使用强制或任何东西到远程分支/BitBucket PR。

其他回答

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

您想要在推动更改之前隐藏您的愚蠢错误吗?如果是这样,git拉-rebase是完美的。它允许您稍后将提交压缩为几个(或一个)提交。如果你在你的(未推送的)历史中有合并,那么以后做git rebase就不那么容易了。

我个人并不介意公布我所有的愚蠢错误,所以我倾向于合并而不是重新建立数据库。

我认为你应该使用git pull -rebase与他人在同一分支上合作。你处于你的工作→提交→工作→提交循环中,当你决定推送你的工作时,你的推送被拒绝了,因为在同一个分支上有并行的工作。在这一点上,我总是做一个拉-rebase。我不使用squash(扁平提交),但我使用rebase来避免额外的合并提交。

随着Git知识的增长,你会发现自己比使用过的其他版本控制系统更多地关注历史。如果您有大量的小型合并提交,很容易失去对历史中正在发生的大局的关注。

这实际上是我唯一一次执行rebase(*),其余的工作流程都是基于合并的。但只要你最频繁的提交者这样做,历史最终看起来会更好。

(*) 在教授Git课程时,我有一个学生因为这个问题逮捕了我,因为我也主张在某些情况下重新定义功能分支。他读到了这个答案;)这种调整基数也是可能的,但它总是必须根据预先安排/商定的制度,因此不应该“总是”适用。在那个时候,我通常也不做拉-rebase,这就是问题所在;)

我想提供一个不同的角度来解释git pull -rebase的实际含义,因为它似乎有时会丢失。

如果您曾经使用过Subversion(或CVS),那么您可能已经习惯了svn update的行为。如果要提交更改,并且由于上游已经进行了更改而导致提交失败,则svn update。Subversion通过将上游更改与您的更改合并进行,这可能会导致冲突。

Subversion刚刚做的,本质上是git pull -rebase。将您的局部更改重新定义为相对于新版本的行为是“重基”的一部分。如果您在失败的提交尝试之前执行了svn diff,并将结果diff与之后的svn diff输出进行比较,那么这两个diff之间的差异就是重基操作所做的。

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

In my opinion, in the normal case of having your local branch simply reflecting the upstream branch and doing continuous development on it, the right thing to do is always --rebase, because that is what you are semantically actually doing. You and others are hacking away at the intended linear history of a branch. The fact that someone else happened to push slightly prior to your attempted push is irrelevant, and it seems counter-productive for each such accident of timing to result in merges in the history.

在我看来,如果出于某种原因,您确实觉得有必要将某些东西作为一个分支,那就另当别论了。但是,除非您有一个特定的和积极的愿望,以合并的形式表示您的更改,在我看来,默认的行为应该是git pull -rebase。

请考虑其他需要观察和理解项目历史的人。您是希望历史上到处都是数百个合并,还是希望只选择代表有意的不同开发工作的真正合并的少数合并?

一个实践案例是当你与Bitbucket PR合作时。 让我们用下面的例子来理解它:

这里有公共关系部门。

然后你决定通过BitBucket GUI用最新的Master分支重新构建PR远程分支。这个操作将改变你的PR的提交id。

因为您已经使用GUI重新创建了远程分支。首先,你必须同步你电脑上的本地分支和远程分支。

在这种情况下,git pull -rebase就像魔法一样有效。

在git pull -rebase之后,你的本地分支和远程分支具有相同的历史和相同的提交id。

那么现在,如果您向PR分支添加一个新的提交/更改。

你可以很好地推送一个新的提交,而不需要使用强制或任何东西到远程分支/BitBucket PR。

我不认为有任何理由不使用pull——rebase——我专门为Git添加了代码,以允许我的Git pull命令始终针对上游提交进行rebase。

当我们回顾历史的时候,我们总是不愿意知道那些致力于某一功能的人何时停止了工作。当他/她在做这件事的时候,它可能对男人/女孩有用,但这就是reflog的目的。这只是给其他人增加了噪音。