Usage
There are two ways to use Mergiraf.
- You can register it as a merge driver in Git so that Mergiraf is directly used during the merge process.
- Or you can invoke it after a merge conflict, for it to attempt to solve the conflict.
The first way is recommended as it avoids interrupting your workflow with spurious conflicts. Also, certain conflicts can only be resolved by Mergiraf if it is used as a merge driver. The second way can be useful for more occasional uses or when changes to Git's configuration are not possible.
Registration as a Git merge driver
Registering Mergiraf in Git will enable you to benefit from its conflict solving when merging and various other operations, such as rebasing, cherry-picking or even reverting. For best results, use Git v2.44.0 or newer.
First, add the following section in your ~/.gitconfig
file:
[merge "mergiraf"]
name = mergiraf
driver = mergiraf merge --git %O %A %B -s %S -x %X -y %Y -p %P
# if you haven't got a global gitattributes file yet
[core]
attributesfile = ~/.gitattributes
Then, you also need to specify for which sorts of files this merge driver should be used. Add the following lines to your global ~/.gitattributes
file:
*.java merge=mergiraf
*.rs merge=mergiraf
*.go merge=mergiraf
*.js merge=mergiraf
*.jsx merge=mergiraf
*.json merge=mergiraf
*.yml merge=mergiraf
*.yaml merge=mergiraf
*.html merge=mergiraf
*.htm merge=mergiraf
*.xhtml merge=mergiraf
*.xml merge=mergiraf
*.c merge=mergiraf
*.h merge=mergiraf
*.cpp merge=mergiraf
*.hpp merge=mergiraf
*.cs merge=mergiraf
This is the complete list of all supported formats - you can of course keep only the ones you need. You can also obtain this list by running mergiraf languages --gitattributes
.
If you want to enable Mergiraf only in a certain repository, add the lines above in the .gitattributes
file at the root of that repository instead, or in .git/info/attributes
if you don't want it to be tracked in the repository.
Reviewing Mergiraf's work
When Git invokes Mergiraf to merge a file, it can either:
- successfully merge the file as a line-based merge, just like normal Git would do,
- encounter conflicts in the line-based merge, which it completely solves via its syntax-aware heuristics. In this case it invites you to review its work via the
mergiraf review
command, - encounter conflicts it cannot solve. In this case, it lets you merge the file manually by leaving conflict markers behind.
If it turns out that Mergiraf's output is unsatisfactory and you would rather use the built-in merge algorithms, abort the operation (such as with git merge --abort
) and start again with Mergiraf disabled.
Temporarily disabling Mergiraf
You can disable Mergiraf by defining the MERGIRAF_DISABLE
environment variable:
$ MERGIRAF_DISABLE=1 git rebase origin/master
This will fall back on Git's regular merge heuristics, without requiring changes to your configuration.
Reporting a bad merge
If the output of a merge looks odd, you are encouraged to report it as a bug. The mergiraf report
command generates an archive containing all necessary information to reproduce the faulty merge.
If the merge did not produce any conflicts, use the merge id (identical to what mergiraf review
accepts) in Git's output:
$ git rebase origin/master
INFO Mergiraf: Solved 2 conflicts. Review with: mergiraf review geolocation.cpp_o0i2JL8B
Successfully rebased and updated refs/heads/my_branch.
$ mergiraf review geolocation.cpp_o0i2JL8B
$ mergiraf report geolocation.cpp_xyuSMcme
Bug report archive created:
mergiraf_report_6weNKAXO.zip
Please submit it to https://codeberg.org/mergiraf/mergiraf/issues if you are happy with its contents being published,
or reach out privately to a contributor if not.
Thank you for helping Mergiraf improve!
If the merge to report has conflicts, use the path to the file instead:
$ mergiraf report src/lib/geolocation.cpp
Compact conflict presentation
By default, Mergiraf aligns the conflicts it outputs to line boundaries to ease their resolution in existing merge tools:
<<<<<<< HEAD
<div class="vocab-panel" id="main-panel">
||||||| 15b798c
<div class="vocab-panel">
=======
<div class="vocab-panel" id="root-panel">
>>>>>>> origin/main
Because merging is done syntax trees, it is often able to highlight narrower conflicts.
The option --compact
(or -c
) of the mergiraf merge
command enables a more compact presentation of conflicts which highlights mismatching parts only:
<div class="vocab-panel" id=
<<<<<<< HEAD
"main-panel"
||||||| 15b798c
=======
"root-panel"
>>>>>>> origin/main
>
The main downside of this mode is that reformatting is often required after resolving conflicts.
Interactive use after encountering a merge conflict
Say you have encountered a conflict during merge:
$ git merge origin/main
Auto-merging config.yml
CONFLICT (content): Merge conflict in config.yml
Automatic merge failed; fix conflicts and then commit the result.
$ cat config.yml
<<<<<<< HEAD
restaurant:
tasks:
plates: 1
bowls: 2
||||||| 15b798c
tasks:
plates: 1
bowls: 2
=======
tasks:
plates: 1
bowls: 4
>>>>>>> origin/main
You can then run Mergiraf to attempt to solve the conflicts automatically:
$ mergiraf solve config.yml
Solved 1 conflict(s)
You can then inspect the result again:
restaurant:
tasks:
plates: 1
bowls: 4
You can then mark the conflict as solved with git add
and continue merging with git merge --continue
.