Git pull 会在提交日志中产生无关的“ Merge Branch”消息

我正在和另一个开发人员合作一个项目,我们使用 Github 作为我们的远程回购。我在 Mac 上使用 git1.7.7.3,他在 Windows 上使用 git1.7.6。

事情是这样的

  1. One of us (let's call him developer A, but it doesn't matter which one) pushes a set of commits to GitHub.
  2. 另一个(开发人员 B)进行一些本地提交。
  3. B 做 git pull
  4. B does a git push.
  5. 查看提交历史日志,可以看到 Merge branch 'master' of github.com:foo/bar

提交日志中随着时间的推移充满了“ Merge Branch”消息,并且还显示开发人员 B 提交了开发人员 A 所做的更改。我们已经找到的唯一的方法,以防止这个问题已经做了 git pull --rebase在第3步,但我不知道什么副作用重新基地将引入。这是我第一次在一个多开发者 git 回购工作,所以这只是正常的行为吗?对如何解决这个问题有什么想法吗?

61426 次浏览

执行 git 提取操作将插入“ Merge Branch”消息,这正是它要做的。通过执行 git 提取,您已经将远程分支合并到本地分支中。

当您执行 git 提取操作时,如果存在冲突,git 日志将显示冲突文件的更新,作为来自解决冲突的用户的更新。我假设这是因为修复冲突的人员重新提交了文件。

据我所知,这就是 Git 的工作原理,没有别的办法。

重新基础化将消除 git 的历史记录,因此您将无法看到合并发生的时间。

你看到的承诺是完全没问题的。pull有效地运行 git fetch,然后是 git merge,因此当您运行 git pull时通常会发生合并。

使用重定基而不是合并的替代方法是可行的,但通常应该避免这种情况。Rebasing 允许您保持线性历史记录,但是也可以删除关于最初发生的分支的任何信息。它还将导致重写当前分支的历史记录,重新创建目标分支(在您的例子中是远程分支)中不包含的所有提交。由于重新创建的提交是 与众不同提交,这可能会在与其他人一起开发时造成很多混乱,特别是当人们在重写之前已经检查了这些提交的部分内容(例如特性分支)时。因此,根据经验法则,您应该 never重写任何已经推送的提交。

The commits you see are there to combine two (or more) branches. It is perfectly fine to have a commit that does nothing else then merging multiple branches. In fact it makes it very clear when you have a merge commit that combines branches when looking at the history. In comparison to rebasing, merging also allows you to effectively see the 原创的 history as it was developed, including the actual branches that coexisted.

所以,长话短说: 是的,合并提交是完全没问题的,你不应该担心他们。

由于我的理解、图表和结论是不正确的,这个答案已经被修改过了。


git pull导致合并提交,因为 git 正在合并。可以通过将分支设置为使用 rebase 而不是 merge 来更改这一点。使用 rebase 而不是 pull 操作中的 merge 为共享存储库提供了更为线性的历史记录。另一方面,合并提交显示了分支上的并行开发工作。

例如,两个人在同一个分支上工作:

...->C1

第一个人完成他们的工作,推向树枝:

...->C1->C2

The second person finishes their work and wants to push, but can't because they need to update. The local repository for the second person looks like:

...->C1->C3

如果将 pull 设置为 merge,则第二个人员存储库将类似于。

...->C1->C3->M1
\      /
->C2->

其中 M1是合并提交。这个新的分支机构的历史将被推到回购。相反,如果将拉力设置为重新定位本地回购的基础,那么回购将类似于:

...->C1->C2->C3

没有合并提交。历史记录变得更加线性。

这两种选择都反映了分支的历史记录。 git 允许您选择您喜欢的历史记录。

在一些地方,rebase 确实会导致远程分支出现问题。这不是那种案子。我们更喜欢使用 rebase,因为它简化了已经很复杂的分支历史,并显示了相对于共享存储库的历史版本。

You can set branch.autosetuprebase=always to have git automatically establish your remote branches as rebase instead of master.

git config --global branch.autosetuprebase always

此设置使 git 自动为每个远程分支创建一个配置设置:

branch.<branchname>.rebase=true

您可以自己为已经安装的远程分支设置这个属性。

git config branch.<branchname>.rebase true

我要感谢@LaurensHolst 对我以前的陈述提出质疑和追问。我当然了解了更多关于 git 如何使用 pull 和 merge 提交的知识。

有关合并提交的详细信息,请阅读 ProGit-Book中的 Contributing to a Project

You can do:

git pull --rebase

然而,这将总是将您的更改置于您的合作者的更改之上,但是您不会收到任何污染性的合并消息。

实际上有一个更简单的答案。只要让开发人员 B 在提交之前做一个拉。这将防止这些合并提交,因为它们是由你在本地回购中创建的历史引起的,而你的本地回购试图与远程回购的历史合并。如果你在拉取文件时收到类似“更改将被覆盖”这样的信息,这只是意味着你们都触碰了同一个文件,所以要这样做:

git stash
git pull
git stash pop

然后,如果存在任何合并冲突,则可以解决任何合并冲突。

Solution:

如果其他开发人员已经在远程进行了提交,那么在进行提交之前需要使用 git pull。如果你这样做,你将永远不会得到无关的“合并分支”消息在提交。

如果您在使用 git pull之前提交,那么您需要使用 git pull --rebase,那么您将不会在提交中获得无关的“ Merge Branch”消息。

还有,要知道:

  1. 这是怎么回事?Git 会回退(撤消)所有的本地提交,下拉远程提交,然后在新提取的远程提交之上重播本地提交。

  2. That's how the commit-graph looks when you push that extraneous “Merge branch” commit along with your commits.

commit-graph with extraneous “Merge branch” commit

  1. 这就是提交图在提交之前的 git pull或提交之后的 git pull --rebase时的样子。

commit-graph without extraneous “Merge branch” commit

注:

  1. 在案例和分支结构中提交数量的差异。

  2. 而且,所有这些都发生在同一个分支上,分支与自身合并。

在我的情况下,我不小心设置了一些配置与 git config -egit config --global -e的一个项目,这造成了问题。我通过删除两个添加的配置来修复它。例如,我在 global config 中有两行:

[pull]
ff = false

而且在本地配置 i 有:

[pull]
rebase = off

当我删除这两个配置时,我可以在不引起合并提交的情况下进行更改。