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


当前回答

如何使用git拉

git pull: Update your local working branch with commits from the remote, and update all remote tracking branches. git pull --rebase: Update your local working branch with commits from the remote, but rewrite history so any local commits occur after all new commits coming from the remote, avoiding a merge commit. git pull --force: This option allows you to force a fetch of a specific remote tracking branch when using the option that would otherwise not be fetched due to conflicts. To force Git to overwrite your current branch to match the remote tracking branch, read below about using git reset. git pull --all: Fetch all remotes - this is handy if you are working on a fork or in another use case with multiple remotes.

其他回答

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

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

你应该使用git pull -rebase when

您的更改不值得一个单独的分支

的确——那为什么不呢?它更清晰,并且没有对提交进行逻辑分组。


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

然而,有时——不管出于什么原因——您认为如果这两个分支(远程和本地)是一个分支实际上会更好。就像在SVN中。这就是git pull -rebase发挥作用的地方。你不再合并——你实际上是在远程分支上提交。这才是它真正的意义所在。

是否危险的问题是你是否把本地分支和远程分支视为一个不可分割的东西。有时这是合理的(当您的更改很小时,或者如果您处于健壮开发的开始阶段,当通过小型提交带来重要的更改时)。有时不是(当您通常创建另一个分支,但您太懒了)。但这是另一个问题。

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

Alice creates topic branch A, and works on it Bob creates unrelated topic branch B, and works on it Alice does git checkout master && git pull. Master is already up to date. Bob does git checkout master && git pull. Master is already up to date. Alice does git merge topic-branch-A Bob does git merge topic-branch-B Bob does git push origin master before Alice Alice does git push origin master, which is rejected because it's not a fast-forward merge. Alice looks at origin/master's log, and sees that the commit is unrelated to hers. Alice does git pull --rebase origin master Alice's merge commit is unwound, Bob's commit is pulled, and Alice's commit is applied after Bob's commit. Alice does git push origin master, and everyone is happy they don't have to read a useless merge commit when they look at the logs in the future.

注意,合并到的特定分支与示例无关。本例中的Master可以是一个发布分支或开发分支。关键是Alice和Bob同时将他们的本地分支合并到一个共享的远程分支。

我想提供一个不同的角度来解释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。

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

如何使用git拉

git pull: Update your local working branch with commits from the remote, and update all remote tracking branches. git pull --rebase: Update your local working branch with commits from the remote, but rewrite history so any local commits occur after all new commits coming from the remote, avoiding a merge commit. git pull --force: This option allows you to force a fetch of a specific remote tracking branch when using the option that would otherwise not be fetched due to conflicts. To force Git to overwrite your current branch to match the remote tracking branch, read below about using git reset. git pull --all: Fetch all remotes - this is handy if you are working on a fork or in another use case with multiple remotes.