为什么 git 将分支合并到自身?

Why does git merge a branch into itself?

我今天早上醒来,查看了我的一个开发团队在 BitBucket 上的私有存储库的提交历史记录。我看到了这个:

Anonymous committed fcde879 MERGE

Merge branch 'develop' of https://bitbucket.org/abc/xyz into develop

这,嗯,有点不寻常。我的猜测是这是从一台没有正确配置 git 的新机器上推送的。不过,我不确定为什么要这样做。在 BitBucket 上,它显示两个单独的哈希作为提交父级,但它没有其他提交的 "view raw commit" 选项。

我检查了那个分支,拉了,然后手动查看了日志。

sidious@DS-1:/path/to/repo$ git log -1 --format=raw
tree 2931d14f48e61eaf0bbe0660af5b5dd76c07f063
parent 6bb38dee681df7620ffa42b6790641a7873166f2
parent f59c82e19e3e79310a53e273bab78139c49ff063
author root <root@somemachine> 1437069530 +0000
committer root <root@somemachine> 1437069530 +0000

Merge branch 'develop' of https://bitbucket.org/abc/xyz into develop

据我所知,6bb 父级在开发分支上,而 f59 父级似乎来自不同的分支。很难说这是怎么回事。

我搜索了但找不到答案,我需要回到正题,因此我在这里提出我的问题:为什么 git 将一个分支合并到它自己中?或者,更确切地说,为什么将此命名法用作提交消息?

所有者在 develop 上有一些他们没有推送的提交,然后 运行 git pull 和 fetched/merged 在远程仓库中来自 develop 的新提交中。

这种情况并不罕见。

这里的关键是被合并的分支是不同的:它是远程存储库的 develop 分支被合并到开发人员的本地(工作)develop 分支。

在开发者的本地存储库中有两个不同的分支:

  • develop = he/she 当前正在处理分支。新的提交在这里。
  • origin/develop = 这本质上是当前存储库保存的关于远程服务器上 develop 分支状态的快照。当您执行 fetchpull 时,它会随着远程更改而更新,并在 push.
  • 成功后随着本地更改而更新

现在,当您执行 git pull 时,会发生两件事。这是因为 git pull 本质上是其他两个 git 操作的别名:fetchmerge:

  • fetch - 将远程存储库中的所有新提交(如果有)带到本地 origin/develop 分支。
  • merge - 获取新的提交并将它们应用到本地工作 develop branch。这可以通过以下两种方式之一发生:
    • 如果本地工作分支不包含不同的历史(远程不知道的新提交),那么它只是将 develop 分支指针向前推进,使其指向最新的提交origin/develop。这被称为 快进合并
    • 如果开发人员有一些他自己的新提交不存在于远程仓库中,因此不在 origin/develop 分支中,然后进行常规合并,这意味着有一个新的提交,包含来自两个分支的更改。默认情况下,git 将这样的消息分配给此类提交:Merge branch 'develop' of https://bitbucket.org/abc/xyz into develop.

所以,这个场景很常见。

现在,如果这种情况经常发生,并且您不希望看到非常复杂的提交历史记录图,其中包含我们正在谈论的提交,请尝试查看 using rebase instead of merge

您可以通过两种方式执行此操作(从远程服务器获取更改时):

  • git fetch; git rebase
  • git pull --rebase

我收到了相同类型的消息。 Merge branch 'feature/customfeature' of https://mylocalrepo.com/project.git into develop 而且它还没有损坏任何东西,哈哈……所以不要惊慌。它只是将远程开发分支合并到您本地的开发分支中。只要不发生冲突,就可以可以开始了 :)

如果你想在拉取之前避免这种类型的合并存储,就像这样:

git stash
git pull
git stash pop