开发者

How to test a merge without actually merging first

Is there any way of simulating a git merge between two branches, the current working branch and the master, but w开发者_开发技巧ithout making any changes?

I often have conflicts when I have to make a git merge. Is there any way of simulating the merge first?


You can use git merge --no-commit to prevent the merge from actually being committed, and if you don't like how the merge works out, just reset to the original head.

If you definitely don't want to finalize the merge, even if it's a fast-forward (and thus has no conflicts, by definition), you could add --no-ff as well.


I don't think there is a way of simulating what will happen until you try the merge. However, if you make sure that the output of git status is empty before you do the merge, it is quite safe to just go ahead and try it. If you get conflicts, you can immediately get back to the state you were at before with:

git reset --merge

Since git 1.7.4, you can also abort the merge by doing:

git merge --abort

(As the commit message that added that option explains, this was added for consistency with git rebase --abort and so on.)


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.

Get the merge diff

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.

Pick information from the output

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'

Features

  • The diff will be empty if a branch is already merged
  • Use grep/sed to extract conflicts information
  • Use origin/feature to test branches you've never worked with
  • Can be used to see how 2 branches have diverged

Add it to your favorites

Get 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


Why not just create a throwaway branch (git checkout -b), and do a test merge there?


I use :

git merge --ff-only

according to documentation:

Refuse to merge and exit with a non-zero status unless the current HEAD is already up-to-date or the merge can be resolved as a fast-forward.

It's not really a simulation because there will be a fast-forward merge in case of no conflicts between the two branches. But in case of conflicts, you will be informed and nothing will happens.


I've been able to use git merge --abort, recently. However, this can only be used if there is a merge conflict. If you are sure that you will not want to commit, then use the other mentioned methods above.


I don't know exactly if it is your case, but your question remember me that sometimes I start a feature, I commit over the days and I merge the develop on it many times.

On this point I lose the control over the exact files I changed and I will only know it when my feature were closed and my code go to develop.

In this case, a good way to know what modifications you did (not other from the merges) is using Sourcetree.

You must click with the right button on the base branch and select Diff Against Current:

How to test a merge without actually merging first

Then sourcetree will show you all the modifications that will be merged if you merge your branch into base branch.

How to test a merge without actually merging first

Of course, it will not show you the conflicts, but it is a useful tool in merges.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜