Is there any way of simulating a git merge
between two branches, the current working branch and the master, but without making any changes?
I often have
If I want to compare changes on a topic branch to master, I find it easiest and safest to do the following:
git checkout master
git checkout -b trial_merge
git merge topic_branch
After completing the merge, it is easy to see the consolidated change from master
git diff master
When done, simply delete the trial_merge branch
git checkout master
git branch -D trial_merge
This way, the master branch never changes.
Here is the solution that I have found: git merge-tree
does merging "in memory" and prints the diff without touching your working directory. You can even test a branch without checking it out.
First, do this to make sure your repository knows about all the remote branches:
$ git fetch --all
Now use this bash snippet to see how branch $branch
would merge into $master
:
$ branch='feature'
$ git merge-tree $(git merge-base $branch master) master $branch
No changes are made to your workdir or index. It's a dry-run merge.
The output is a diff. In case the branch has been merged, it will be empty.
To find whether there are conflicts, grep it for <<<
:
$ git merge-tree $(git merge-base $branch master) master $branch | fgrep '<<<'
To extract conflict diffs, use sed to extract lines between <<<
and >>>
:
$ git merge-tree $(git merge-base $branch master) master $branch | \
sed -ne '/^\+<<</,/^\+>>>/ p'
origin/feature
to test branches you've never worked withGet the diff of the merge:
git config --global alias.mergediff '!f(){ branch="$1" ; into="$2" ; git merge-tree $(git merge-base "$branch" "$into") "$into" "$branch" ; };f '
Usage:
$ git mergediff <feature-branch> <merge-into>
$ git mergediff feature master
Get merge conflicts:
git config --global alias.mergetest '!f(){ git mergediff $@ | sed -ne "/^+<<</,/^+>>>/ p" ; };f '
Usage:
$ git mergetest <feature-branch> <merge-into>
$ git mergetest feature master