I'm trying to merge a big topic branch into the master, but I want a separate commit that shows how the conflict resolution happened. The goal is to have one commit that shows "these files conflicted and how they conflicted" and the next commit would show "this is how the conflicts were resolved". I.e. the first commit would contain the conflict markers.
The reason for this is that the big topic branch has been reviewed and tested, as has the master branch. Of the merge, we want to review only the parts that needed some work (conflicts and other merge work).
Here's what I'm doing this far:
git checkout master
git checkout -b merge-from-topic
git merge topic
To record the files that have conflicts, I use a temporary file:
git diff --name-only --diff-filter=U >conflicts.txt
First I simply add those files, with the conflict markers, to a commit:
xargs git add <conflicts.txt
git commit
Then I create another branch (for review purposes) in which I'd like to do the conflict resolution:
git checkout -b resolve-merge-from-topic
To restore the conflicts, I tried
xargs git reset HEAD^ -- <conflicts.txt
but then git mergetool said that none of the files need merging although files in my working tree had conflict markers.
How do I restore files listed in conflicts.txt, so that I can use git mergetool on them?
I'm also open to other ways of getting the "separate commit for conflict resolution" effect.
this is a very bad idea. You want a stable code base at all times. Why would you ever push a code in a state where its conflicted.
If you want to see how conflict was resolved, do a diff on the file and see the history of it.
git merge
will leave conflict markers.You then (usually) invoke
git mergetool
(with the--tool
of your preference) to resolve the conflicts. Most of the time, this will result in staged changes. This you want to change (e.g. usinggit reset
).Now commit the 'raw' merge in isolation, and subsequently
git add . && git commit -m 'resolutions'
orgit commit -am 'resolutions'
to add the conflict resolutions.Note this leaves you with a 'broken' build at the merge boundary revision.
In steps:
if you are really insistent on getting the merge history, then your best bet is to use git-imerge
AFAIK the git imerge gives you a choice if the merging history should be preserved or not
REF:
an exert from the author's blog:
which may be exactly why you require a conflict-commit in the first place.
On another hand, a different perspective:
The merging changes should be kept as minimal as possible on an trivial project Why this is being said is that a merge touching all of the files in the repository will make you have a real pain in the future. As if you are to merge your branch with some major branch , lets say you work on the production branch, while the releases are done from the release branch, a branch maintainer will just try to rebase your branch with his branch.
Now if you had a commit which touched all the files in the place, this is going to be a read bad stuff as the merge will most likely to have conflict (major one, probably the conflict-commit you made) so the maintainer will have 2 options:
its more likely that maintainer will be opting the latter as it's the easier one for him.
So this you'll be spending more time in resolving the conflicts than doing some productive work.
NOTE:
The second perspective is only applicable when you have feature topics that have simple span. When merging the feature topics having larger span, it's better to use imerge and keep the history, that way you'll have smaller commits and rebase will not be painful.