Reputation: 66395
In my development workflow involving Gerrit for code review, branches contain one or more changes to files. After these got approved, these get cherry picked with Reviewed-by tags appended.
However, when trying to delete the working branch, I get a warning that not all changes are merged:
$ git branch -d documentation
error: The branch 'documentation' is not fully merged.
If you are sure you want to delete it, run 'git branch -D documentation'.
The changed files are however exactly the same. The only differences (found via git show --pretty=fuller
include the Committer, CommitDate and commit message. The Change-Ids inserted by Gerrit are exactly the same though.
Is there a way to delete branches without complaining about such differences? It should obviously still complain when there are really different commits that did not get merged.
Upvotes: 1
Views: 1369
Reputation: 66395
Torek suggests to attempt a merge branch to see whether everything is merged or not. This is easy to do, but requires that the working tree can be modified.
Assume the following git log where docs update
is a commit modifying the file doc/README.dissector
existing on both the documentation
and master
branch. You can see that there are no other commits since the split in commit a984dbf ("parent commit").
* 9667666 (master) latest commit * ... * 6284040 docs update (commit cherry-picked by Gerrit) * ... * a984dbf other commits on master | * 8b8cb8f (documentation) docs update (branch pushed for review) |/ * e76e140 parent commit
it works like this:
Ensure that the current working tree is clean (that is, no uncommited changes). If this is not the case, use git stash
to put the changes aside.
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
Here you can see that the attempt to remove the documentation
branch fails because of minor differences as described in the question:
$ git branch -d documentation
error: The branch 'documentation' is not fully merged.
If you are sure you want to delete it, run 'git branch -D documentation'.
No problem! Attempt a merge...
$ git merge --squash documentation
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested
... and check whether it resulted in any differences (you could as well use git diff
). As you can see, there are no remaining changes:
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
Now we have a confirmation that the branch does not contain other commits, and we can safely remove it:
$ git branch -D documentation
Deleted branch documentation (was 8b8cb8f).
There is a second, but less obvious way to test the merge without touching the working three nor the index as described in https://stackoverflow.com/a/6283843/427545.
It only works if the commit reference ("master" in the example) does not contain other changes since the split. If it did, then you would get a diff containing the new changes in master since the commit got merged. In that case, use an earlier commit instead of "master".
Example session:
Find the base commit ("e76e140 parent commit" in the given example):
$ git merge-base master documentation
e76e14074e5a9c46886ab3124a5649eabe7bfe99
Attempt the merge:
$ git merge e76e14074e5a9c46886ab3124a5649eabe7bfe99 master documentation
changed in both
base 100644 3fdc91af1748f6db1dcb9729cd6e2846b9c7b2f8 doc/README.dissector
our 100644 10ba4e6b3f1a2e91cb61dc4133bca4a61b50e47b doc/README.dissector
their 100644 61384b5df44ff0e13374e3d93b3e6d01fa9c380a doc/README.dissector
Draw conclusions. The above output might give you the impression that the documentation branch was not fulled merged into the master branch. This is however not the case. If the files were different, a diff would be displayed below those lines. When the output is empty, then the branch is fully merged (and git branch -d documentation
would not have complained).
Since there is no diff (everything got merged), we can safely remove the branch:
git branch -D documentation
With the following git alias, you can simply invoke git test-merge documentation
to automate the above steps:
git config --global alias.test-merge '!sh -c '\''branch="${2:-$(git rev-parse --abbrev-ref HEAD)}"; git merge-tree $(git merge-base "$1" "$branch") "$branch" "$1"'\'' --'
Usage:
# Test merge of branch "documentation" in the current branch
git test-merge documentation
# Test merge of branch "documentation" in the "master-1.12" branch
git test-merge documentation master-1.12
Upvotes: 0
Reputation: 487805
git branch
just works from the DAG. You're asking git to check whether the content is fully merged, which is a more difficult question.
There are two obvious git tools for finding an answer:
git cherry
: this might be just what you want; try it out.git merge
: Get onto a detached HEAD at the tip of the branch you think you should be all-into, then do a dummy merge of the branch you're proposing to delete. If the resulting merge commit has the same tree as the point at which HEAD was first detached, it's safe to do the proposed delete. (If not, it may be a mis-merge, or perhaps a merge conflict that, if/when resolved, shows that it's safe anyway.)Upvotes: 3