user82216
user82216

Reputation:

git branch -d fails even though branch's changes have been applied to master

Background:

Workflow:

Problem:

However, the patch that the maintainer applied contained all the changes that I had made in my bug fix branch, so intuitively it seems wrong that Git should claim that the branch "is not fully merged."

The Git book seems to agree with me. It mentions only one reason why git branch -d would fail - because the branch "contains work that isn’t merged in yet" - which doesn't apply in my case.

I am unsure whether I have encountered a bug in Git, or whether Git just doesn't support my use-case.

Yes, I could just go ahead and delete the branch using git branch -D, but I would rather not get into the habit of doing that except in cases where I want to delete a branch whose changes to the files in the working tree really have not been merged into any other branch.

I would much rather:

Example

$ 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

I then email 0001-Fix-bug-42.patch to the maintainer.

The maintainer applies this using git am < 0001-Fix-bug-42.patch, maybe makes some other commits too, and pushes to origin/master.

I then do:

$ 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

So far, so good! Let's see if my patch was applied in one of those three commits:

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

    Add sampablokuper to list of contributors

commit 44a35eae3dc69002b6d3484cd17ad653ee7de3c3
Author: Sam Pablo Kuper <[email protected]>
Date:   Thu Aug 11 19:00:00 2016 +0000

    Fix bug 42

commit 25c3562fecd3f42f76c7552fabec440dd4473c6e
Author: A Maintainer <[email protected]>
Date:   Thu Aug 11 14:44:53 2016 +0000

    Edit bar.txt

Looks like it was applied in the penultimate commit. Let's confirm that!

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

All the changes I made in my fix_bug_42 branch have definitely been applied and committed by the maintainer. Yay!

That means Git should know it is now safe for me to delete my bug fix branch, right? Wrong!

$ 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'.

Argh!

Hypotheses

Now, I think I know why this is happening. I think it is because the commit in master in which my patch was applied (44a35eae3dc69002b6d3484cd17ad653ee7de3c3) has a different hash to the commit in fix_bug_42 from which that patch was made (244540f...). I.e. Git thinks that because commit 244540f doesn't exist in master, that means fix_bug_42 "is not fully merged".

Questions

Upvotes: 4

Views: 540

Answers (1)

Plasma
Plasma

Reputation: 2439

Your hypothesis is correct, a better workflow would have been using something like git request-pull:

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

There's no way for git to know that your commit is the same as the commit that was merged without doing a lot of detailed checking, so it's not exactly a bug.

Upvotes: 1

Related Questions