背景:
>我想为使用Git进行版本控制的项目提供错误修复;
>我没有对项目公共存储库的写访问权限;
>项目维护者需要通过电子邮件提交补丁.
工作流程:
>我克隆项目的公共存储库;
>我创建了一个本地分支,在其中我开发了我的bug修复;
>我将补丁通过电子邮件发送给维护者;
>维护者应用补丁并推送到项目的公共存储库;
>我从origin / master将更改提取到我的本地主分支;
>我确认我的补丁是由维护者应用的.
问题:
> git branch -d现在不会删除我的bug修复分支,给出错误:分支…没有完全合并.
但是,维护者应用的补丁包含了我在我的错误修复分支中所做的所有更改,因此直观地认为Git应该声称分支“未完全合并”似乎是错误的.
Git书似乎与我同意.它提到了git branch -d失败的唯一原因 – 因为分支“contains work that isn’t merged in yet” – 在我的情况下不适用.
我不确定我是否遇到过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应该知道我现在可以安全地删除我的bug修复分支,对吧?错误!
$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)与fix_bug_42中的提交具有不同的哈希值(244540f …).即Git认为因为提交244540f在master中不存在,这意味着fix_bug_42“没有完全合并”.
问题
>我的假设是否正确?
>无论如何,如果不使用git branch -D,我该怎么办呢? (例如,我可以使用更好的工作流程,这可以避免这个问题吗?)
> Git的这种意外(至少对我来说)行为是代表Git中的错误,还是至少是改进处理此用例的合法功能请求?
最佳答案 你的假设是正确的,一个更好的工作流程会使用像git request-pull这样的东西:
https://git-scm.com/docs/git-request-pull
git没有办法知道你的提交与没有进行大量详细检查的合并提交相同,所以它不是一个错误.