You can determine with git merge-base if a fast forward is possible, but is there some git trick to determine if two branches will merge cleanly with some strategy without actually doing the merge? I know about git merge --no-commit --no-ff $BRANCH
but that affects the working directory, which I'd like to avoid since this is part of a webservice.

- 9,291
- 5
- 65
- 93

- 562
- 5
- 15
4 Answers
I'd do this by creating a third, temporary branch.
Let's say you want to merge branch branchFrom
into branchTo
. It would then go like this:
git checkout branchTo #only if not already at branchTo
git checkout -b branchTmp
git merge branchFrom
# see what happens
git checkout branchTo
git branch -d branchTmp
# act accordingly
That way you get accurate results without screwing any of your branches.

- 4,249
- 1
- 32
- 34
-
I agree, the 'create a backup temp branch and see' method is often overlooked. good answer – fontno Jun 20 '13 at 22:29
-
1This will most definitely affect the working directory. – Vladimir Panteleev Feb 07 '21 at 12:38
There's no built-in way; a work tree is required to perform a merge. Seeing if a merge will work (in the general case) means trying the strategy and seeing what happens.
You could however check for the trivial case: the two branches don't touch the same files. Find the merge base, and then check if git diff --name-only $merge_base branchA
and git diff --name-only $merge_base branchB
have anything in common.
Otherwise, you'll need a work tree to try the merge in. You could easily create a second one - either clone the repository, or to save space, just create a work tree. The git-new-workdir
script (from git.git's contrib directory) can help with this; it creates a new repo whose .git
directory is full of symlinks back to the original one. Just be careful that in that new work directory you don't modify the branch the original repo has checked out - they'll get out of sync, in the same way that pushing into a currently checked out branch messes things up.

- 479,068
- 72
- 370
- 318
-
3Another trivial case is when one of the branches contains the another one. You can check that with `git branch --contains branchB' to see if the current branch contains entirely the `branchB` branch. – Haralan Dobrev Sep 05 '12 at 07:47
-
@Haralan If you're doing the check I suggested, and one branch contains the other, the merge base will be equal to that branch, so you can either notice that right away, or else the diff will be empty and trivially nonoverlapping with the other. – Cascabel Sep 05 '12 at 13:29
-
The `git-merge-tree` command will "show three-way merge without touching index", which contradicts basically all of your answer. – Kenny Evitt Mar 13 '17 at 15:45
TLDR
Assuming your merge 'target' is checked-out, i.e. HEAD
, and your merge 'source' is $BRANCH
:
git merge-tree `git merge-base $BRANCH HEAD` HEAD $BRANCH | grep "^<<<<<<<\|changed in both"
Details
Assuming your merge 'target' is checked-out, i.e. HEAD
, and your merge 'source' is $BRANCH
, first "find as good common ancestors as possible for a merge":
git merge-base $BRANCH HEAD
The above should output a hash value for a commit; call that value $merge_base
.
Next, "show three-way merge without touching index":
git merge-tree $merge_base HEAD $BRANCH
The above should output "trivial merge results and conflicting stages to the standard output".
If HEAD
is already up-to-date with respect to $BRANCH
there should be no output.
If there are merge conflicts, the output should contain the Git conflict markers. You can determine whether there any with a command like:
git merge-tree $merge_base HEAD $BRANCH | grep "^<<<<<<<"
You can also look for the text "changed in both":
git merge-tree $merge_base HEAD $BRANCH | grep "changed in both"
All of the above commands as a (Bash) one-liner:
git merge-tree `git merge-base $BRANCH HEAD` HEAD $BRANCH | grep "^<<<<<<<\|changed in both"
This was adapted from this answer to this question:

- 1
- 1

- 1,034
- 12
- 21
-
2This answer above can lead you to a very powerful one-liner, here I provide a summary of a coment by jakub.g on the linked answer. Suppose you are on branch `master` and you want to check if the `git merge origin/devel` will work. Then just do: `git merge-tree \`git merge-base origin/devel master\` master origin/devel`. But this one line is way more powerful than it looks, because you can also do this on a branch that is not checked out. Powerful! – mbdevpl Jul 30 '15 at 06:27
-
See also `git read-tree -m` with three tree-ish-es (which is mentioned in `git-merge-base`'s documentation). – Vladimir Panteleev Feb 07 '21 at 13:00
You can't do it without affecting the working directory, but you can do it without affecting your current changes.
git stash
git merge ...
woops
git reset --hard HEAD
git stash apply
Will get you what you need.

- 5,103
- 3
- 32
- 49

- 25,788
- 10
- 70
- 111