Skip to content

Merge Conflicts Resolving and Remembering them

Johannes Schindelin edited this page Dec 19, 2020 · 13 revisions

Work in Progress as I try and work out how to do this (06-04-2019)..

When building a new release for Git-for-Windows, the full range of Windows patches the maintainer applies need to be moved (rebased) from being on top of the old upstream Git, to being on top of the new upstream release.

There is a process, a script and the support of the merging-rebase code, but still there maybe conflicts, old and new, especially if some of the Windows code has been adopted upstream in a different form.

This note looks at how to remember those resolutions, reuse them, and to learn from previous Git-for-Windows rebases. The magic is in the REuse REcorded REsolution (rerere) command and it's underlying database.

The documentation is terse, so let's also point to some on-line articles:

So, enable rerere - git config --global rerere.enabled true, consider setting git config --global rerere.autoupdate true and away you go!

Determine a previous Git-for-Windows merging-rebase end points and run the contrib/rerere-train.sh

Remember the parameters passed to rerere-train are <rev-list-args> (apparently) for selecting the training set.

From the git List

Threads about the internal workings:

saving and replaying multiple variants with rerere 2015-09-14 Should rerere auto-update a merge resolution? 2017-08-23 rebase: use OPT_RERERE_AUTOUPDATE() 2019-03-19 git/Documentation/technical/rerere.txt committed on 5 Aug 2018 git rerere unresolve file 2009-11-21 patch series Make git-rerere a builtin 2006-12-20 convert from a perl script Add a test for git-rerere 2006-12-20

Patch series, Rebase and Merge conflicts: When and where

For the rerere (redo) database, it is worth taking a few moments to consider the difference between the conflict resolution that you would perform during a rebase when a patch fails to merge cleanly, and the conflict resolution for a merge.

For a subsequent rebase, of the repeating merging-rebase kind, it is easy to forget that the patches being forward ported to the new base commit already contain the previous resolution, so will not conflict next time, unless the upstream has changed, whereupon you have a new conflict to resolve.

This partially extends to the merges within the merging-rebase. If previous rebases have tidied the merging branches to avoid merge conflicts then there will be no resolutions to record. However if the cleanest approach was to resolve at merge, then the merge resolution can (should) be learned. Further, if you also had upstream changes and resolutions in the branches being merged, there may still be further residual merge resolutions to be performed. So unless the merges were clean then these are all new merge resolutions that should be learned (or relearned) for later reuse in redoing the next merging rebase.

Moreover, if you are rebasing a series that has temporary merges from upstream or other independent side merges (?Cousins?), then these resolutions will need to be remembered for future merging-rebase is repeated (after dropping those merges from the 'todo' list)

merging-rebase, as used in Git for Windows.

When upstream provides a tagged release, we create a commit with duplicated content tree (same oid hash) that has parents of: the upstream release and our previous release. This 'fake merge', with commit message title Start the merging-rebase, along with its predecessor fake merge, provides anchors for the rebase of the patch series.

A side effect is that, via the second parent line, we have many repetitions of the same patch series when searching via blame or grep, or doing a git bisect. The effect can be mitigated by inserting a temporary git replace of the Start the merging-rebasemerge commit, by its first (upstream) parent, making the merge disappear, along with all those historical duplicate patches. It becomes: upstream Git, with Windows patches on top - simple.

Clone this wiki locally