When I run git difftool --tool-help or git mergetool --tool-help, I see:
vimdiffvimdiff1vimdiff2vimdiff3What are these different "versions"? I assume they all start Vim with different options, but what are the options? Are they documented anywhere?
They don't seem to be documented anywhere, unfortunately.
The relevant source code is here. Note how vimdiff, nvimdiff, and gvimdiff are all implemented with the same script.
When invoked as a difftool, they all do the same thing:
vim -R -f -d \
-c 'wincmd l' \
-c 'cd $GIT_PREFIX' \
"$LOCAL" "$REMOTE"
This starts Vim in read-only mode -R and diff mode -d. For information on diff mode, see the manpage vimdiff(1) and the Vim help page diff.txt.
When invoked as a mergetool, the behavior of these options varies.
In the diagrams below, Local corresponds to "ours", Remote corresponds to "theirs", Base corresponds to "merge base", and Merge is the file that will actually be saved to the work tree (and staged to the index if the resolution is successful).
vimdiffIf there is a "merge base" present, the window layout is:
# | Local | Base | Remote |
# | --------------------- |
# | Merge |
vim -f -d \
-c '4wincmd w | wincmd J' \
"$LOCAL" "$BASE" "$REMOTE" "$MERGED"
If there is not a merge base present, the layout is:
# | | | |
# | Local | Merge | Remote |
# | | | |
vim -f -d \
-c 'wincmd l' \
"$LOCAL" "$MERGED" "$REMOTE"
vimdiff1The layout is:
# | | |
# | Local | Remote |
# | | |
vim -f -d "$LOCAL" "$REMOTE"
ret="$?"
if test "$ret" -eq 0
then
cp -- "$LOCAL" "$MERGED"
fi
Local will then be saved to the work tree upon success, taking the place of Merged.
vimdiff2The layout is identical to vimdiff without a merge base.
vimdiff3Each of Local, Remote, Base (if present) will be opened but hidden. Merged will be opened and visible. You can switch among these buffers with the :buffer command.
# With Base
vim -f -d \
-c 'hid | hid | hid' \
"$LOCAL" "$REMOTE" "$BASE" "$MERGED"
# Without Base
vim -f -d \
-c 'hid | hid' \
"$LOCAL" "$REMOTE" "$MERGED"
Let's create a vimdiff4, which uses the same layout as vimdiff-with-Base, but omitting the Base part.
Add the following to your Git config (e.g. $XDG_CONFIG_HOME/git/config):
[mergetool "nvimdiff4"]
# Like "nvimdiff", but always ignore $BASE.
cmd = nvim -f -d -c '$wincmd w' -c 'wincmd J' $LOCAL $REMOTE $MERGED
When you invoke git mergetool --tool-help, you will see a new line in the output:
user-defined:
nvimdiff4.cmd nvim -d -c '$wincmd w' -c 'wincmd J' $LOCAL $REMOTE $MERGED
Now you can run git mergetool --tool=nvimdiff4, which will invoke the command we specified above.
The Documentation/mergetools/vimdiff.txt recently (2022) documented:
In addition, for backwards compatibility with previous Git versions, you can also append
1,2or3to eithervimdiffor any of the variants (ex:vimdiff3,nvimdiff1, etc...) to use a predefined layout.In other words, using
--tool=[g,n,]vimdiffxis the same as using--tool=[g,n,]vimdiffand setting configuration variablemergetool.[g,n,]vimdiff.layoutto...
x=1:"@LOCAL, REMOTE"x=2:"LOCAL, MERGED, REMOTE"x=3:"MERGED"Example: using
--tool=gvimdiff2will opengvimwith three columns (LOCAL,MERGEDandREMOTE).
This should work better with Git 2.37.3 (Q3 2022), which does fix a "vimdiff3" regression.
See commit 34133d9, commit b6014ee, commit ffcc33f, commit 60184ab, commit 66dd83a, commit 79db50d, commit d619183 (10 Aug 2022) by Felipe Contreras (felipec).
(Merged by Junio C Hamano -- gitster -- in commit 4d8074b, 18 Aug 2022)
mergetools: vimdiff: fix single window layoutsCc: Fernando Ramos
Signed-off-by: Felipe Contreras
Reviewed-by: Fernando Ramos
Layouts with a single window other than "
MERGED" do not work (e.g. "LOCAL" or "MERGED+LOCAL").This is because as the documentation of
bufdosays:The last buffer (or where an error occurred) becomes the current buffer.And we do always do
bufdothe end.Additionally, we do it only once, when it should be per tab.
Fix this by doing it once per tab right after it's created and before any buffer is switched.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With