4

背景:

  • 我想为使用 Git 进行版本控制的项目提供错误修复;
  • 我没有对该项目的公共存储库的写入权限;
  • 项目维护者要求通过电子邮件提交补丁。

工作流程:

  • 我克隆了项目的公共存储库;
  • 我创建了一个本地分支,在其中开发我的错误修复;
  • 我将补丁通过电子邮件发送给维护者;
  • 维护者应用补丁并推送到项目的公共存储库;
  • 我将更改拉到我的本地master分支origin/master
  • 我确认我的补丁是由维护者应用的。

问题:

  • git branch -d现在不会删除我的错误修复分支,给error: The branch ... is not fully merged.

但是,维护者应用的补丁包含了我在错误修复分支中所做的所有更改,因此从直觉上看,Git 声称该分支“未完全合并”似乎是错误的。

Git 书似乎同意我的看法。它只提到了失败的一个原因git branch -d——因为分支“包含尚未合并的工作”——这不适用于我的情况。

我不确定我是否在 Git 中遇到了错误,或者 Git 是否不支持我的用例。

是的,我可以继续使用 删除分支git branch -D,但我不想养成这样做的习惯,除非我想删除一个分支,其对工作树中文件的更改确实没有合并到任何其他分支。

我更愿意:

  • 了解为什么 Git 声称错误修复分支“未完全合并”,即使分支的更改确实已应用于master,并且
  • 找到比诉诸 更优雅的回应git branch -D

例子

$ git clone https://git.example.com/repo.git
# Output omitted for brevity. Clone proceeded fine.
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
$ git checkout -b fix_bug_42
Switched to a new branch 'fix_bug_42'
$ vim foo.txt # Fix bug 42.
$ git add foo.txt
$ git commit -m "Fix bug 42"
[fix_bug_42 244540f] Fix bug 42
 1 file changed, 1 insertion(+)
$ git format-patch HEAD^
0001-Fix-bug-42.patch

然后我通过电子邮件发送0001-Fix-bug-42.patch给维护者。

维护者使用 来应用这个git am < 0001-Fix-bug-42.patch,也许也做一些其他的提交,然后推送到 origin/master。

然后我做:

$ git remote update
Fetching origin
remote: Counting objects: 54, done.               # Numbers illustrative only
remote: Compressing objects: 100% (42/42), done.
remote: Total 42 (delta 29), reused 0 (delta 0)
Unpacking objects: 100% (42/42), done.
From https://git.example.com/repo
   7787ce5..1c1a981  master     -> origin/master
$ git status
On branch fix_bug_42
nothing to commit, working directory clean
$ git co master
Switched to branch 'master'
Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)
$ git pull
Updating 7787ce5..1c1a981
Fast-forward
 bar.txt          |   3 +--
 contributors.txt |   1 +
 foo.txt          |   1 +
 3 files changed, 3 insertions(+), 2 deletions(-) # Numbers illustrative only

到目前为止,一切都很好!让我们看看我的补丁是否应用于这三个提交之一:

$ git log @...@^^^ # Show the last two commits
commit 1c1a981f0b9cbaa593c949cea07e3265e2f8c9fa
Author: A Maintainer <maintainer@example.com>
Date:   Thu Aug 11 20:58:32 2016 +0000

    Add sampablokuper to list of contributors

commit 44a35eae3dc69002b6d3484cd17ad653ee7de3c3
Author: Sam Pablo Kuper <sampablokuper@example.edu>
Date:   Thu Aug 11 19:00:00 2016 +0000

    Fix bug 42

commit 25c3562fecd3f42f76c7552fabec440dd4473c6e
Author: A Maintainer <maintainer@example.com>
Date:   Thu Aug 11 14:44:53 2016 +0000

    Edit bar.txt

看起来它已应用于倒数第二次提交。让我们确认一下!

$ diff -s <(git diff @^^ @^) <(git diff fix_bug_42^ fix_bug_42)
Files /dev/fd/63 and /dev/fd/62 are identical
$

我在fix_bug_42分支中所做的所有更改肯定已由维护者应用和提交。耶!

这意味着 Git 应该知道我现在可以安全地删除我的错误修复分支,对吗?错误的!

$ git branch -d fix_bug_42
error: The branch 'fix_bug_42' is not fully merged.
If you are sure you want to delete it, run 'git branch -D fix_bug_42'.

啊!

假设

现在,我想我知道为什么会这样了。我认为这是因为master应用了我的补丁的提交(44a35eae3dc69002b6d3484cd17ad653ee7de3c3)与制作该补丁的提交(244540f ...)具有不同的哈希值fix_bug_42。即Git认为因为commit 244540f 中不存在master,这意味着fix_bug_42“没有完全合并”。

问题

  • 我的假设正确吗?

  • 无论如何,除了使用,我能做些什么来解决这个问题git branch -D?(例如,我可以使用更好的工作流程来避免这个问题吗?)

  • 来自 Git 的这种意外(至少对我而言)行为是否代表 Git 中的错误,或者至少代表改进处理此用例的合法功能请求?

4

1 回答 1

1

您的假设是正确的,更好的工作流程将使用以下内容git request-pull

https://git-scm.com/docs/git-request-pull

如果不进行大量详细检查,git 无法知道您的提交与合并的提交相同,因此它不完全是一个错误。

于 2016-08-13T01:45:36.200 回答