diff --git a/Documentation/Makefile b/Documentation/Makefile index 1eb9192dae..faed285462 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -302,12 +302,12 @@ $(mergetools_txt): mergetools-list.made mergetools-list.made: ../git-mergetool--lib.sh $(wildcard ../mergetools/*) $(QUIET_GEN) \ - $(SHELL_PATH) -c 'MERGE_TOOLS_DIR=../mergetools && \ + $(SHELL_PATH) -c 'MERGE_TOOLS_DIR=../mergetools && TOOL_MODE=diff && \ . ../git-mergetool--lib.sh && \ - show_tool_names can_diff "* " || :' >mergetools-diff.txt && \ - $(SHELL_PATH) -c 'MERGE_TOOLS_DIR=../mergetools && \ + show_tool_names can_diff' | sed -e "s/\([a-z0-9]*\)/\`\1\`;;/" >mergetools-diff.txt && \ + $(SHELL_PATH) -c 'MERGE_TOOLS_DIR=../mergetools && TOOL_MODE=merge && \ . ../git-mergetool--lib.sh && \ - show_tool_names can_merge "* " || :' >mergetools-merge.txt && \ + show_tool_names can_merge' | sed -e "s/\([a-z0-9]*\)/\`\1\`;;/" >mergetools-merge.txt && \ date >$@ TRACK_ASCIIDOCFLAGS = $(subst ','\'',$(ASCIIDOC_COMMON):$(ASCIIDOC_HTML):$(ASCIIDOC_DOCBOOK)) diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt index cafbbef46a..90b3809700 100644 --- a/Documentation/config/mergetool.txt +++ b/Documentation/config/mergetool.txt @@ -45,6 +45,15 @@ mergetool.meld.useAutoMerge:: value of `false` avoids using `--auto-merge` altogether, and is the default value. +mergetool.vimdiff.layout:: + The vimdiff backend uses this variable to control how its split + windows look like. Applies even if you are using Neovim (`nvim`) or + gVim (`gvim`) as the merge tool. See BACKEND SPECIFIC HINTS section +ifndef::git-mergetool[] + in linkgit:git-mergetool[1]. +endif::[] + for details. + mergetool.hideResolved:: During a merge Git will automatically resolve as many conflicts as possible and write the 'MERGED' file containing conflict markers around diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt index e587c7763a..f784027bc1 100644 --- a/Documentation/git-mergetool.txt +++ b/Documentation/git-mergetool.txt @@ -101,6 +101,7 @@ success of the resolution after the custom tool has exited. CONFIGURATION ------------- +:git-mergetool: 1 include::config/mergetool.txt[] TEMPORARY FILES @@ -113,6 +114,13 @@ Setting the `mergetool.keepBackup` configuration variable to `false` causes `git mergetool` to automatically remove the backup as files are successfully merged. +BACKEND SPECIFIC HINTS +---------------------- + +vimdiff +~~~~~~~ +include::mergetools/vimdiff.txt[] + GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/mergetools/vimdiff.txt b/Documentation/mergetools/vimdiff.txt new file mode 100644 index 0000000000..2d631e9b1f --- /dev/null +++ b/Documentation/mergetools/vimdiff.txt @@ -0,0 +1,194 @@ +Description +^^^^^^^^^^^ + +When specifying `--tool=vimdiff` in `git mergetool` Git will open Vim with a 4 +windows layout distributed in the following way: +.... +------------------------------------------ +| | | | +| LOCAL | BASE | REMOTE | +| | | | +------------------------------------------ +| | +| MERGED | +| | +------------------------------------------ +.... +`LOCAL`, `BASE` and `REMOTE` are read-only buffers showing the contents of the +conflicting file in specific commits ("commit you are merging into", "common +ancestor commit" and "commit you are merging from" respectively) + +`MERGED` is a writable buffer where you have to resolve the conflicts (using the +other read-only buffers as a reference). Once you are done, save and exit Vim as +usual (`:wq`) or, if you want to abort, exit using `:cq`. + +Layout configuration +^^^^^^^^^^^^^^^^^^^^ + +You can change the windows layout used by Vim by setting configuration variable +`mergetool.vimdiff.layout` which accepts a string where the following separators +have special meaning: + + - `+` is used to "open a new tab" + - `,` is used to "open a new vertical split" + - `/` is used to "open a new horizontal split" + - `@` is used to indicate which is the file containing the final version after + solving the conflicts. If not present, `MERGED` will be used by default. + +The precedence of the operators is this one (you can use parentheses to change +it): + + `@` > `+` > `/` > `,` + +Let's see some examples to understand how it works: + +* `layout = "(LOCAL,BASE,REMOTE)/MERGED"` ++ +-- +This is exactly the same as the default layout we have already seen. + +Note that `/` has precedence over `,` and thus the parenthesis are not +needed in this case. The next layout definition is equivalent: + + layout = "LOCAL,BASE,REMOTE / MERGED" +-- +* `layout = "LOCAL,MERGED,REMOTE"` ++ +-- +If, for some reason, we are not interested in the `BASE` buffer. +.... +------------------------------------------ +| | | | +| | | | +| LOCAL | MERGED | REMOTE | +| | | | +| | | | +------------------------------------------ +.... +-- +* `layout = "MERGED"` ++ +-- +Only the `MERGED` buffer will be shown. Note, however, that all the other +ones are still loaded in vim, and you can access them with the "buffers" +command. +.... +------------------------------------------ +| | +| | +| MERGED | +| | +| | +------------------------------------------ +.... +-- +* `layout = "@LOCAL,REMOTE"` ++ +-- +When `MERGED` is not present in the layout, you must "mark" one of the +buffers with an asterisk. That will become the buffer you need to edit and +save after resolving the conflicts. +.... +------------------------------------------ +| | | +| | | +| | | +| LOCAL | REMOTE | +| | | +| | | +| | | +------------------------------------------ +.... +-- +* `layout = "LOCAL,BASE,REMOTE / MERGED + BASE,LOCAL + BASE,REMOTE"` ++ +-- +Three tabs will open: the first one is a copy of the default layout, while +the other two only show the differences between (`BASE` and `LOCAL`) and +(`BASE` and `REMOTE`) respectively. +.... +------------------------------------------ +| | TAB #2 | TAB #3 | | +------------------------------------------ +| | | | +| LOCAL | BASE | REMOTE | +| | | | +------------------------------------------ +| | +| MERGED | +| | +------------------------------------------ +.... +.... +------------------------------------------ +| TAB #1 | | TAB #3 | | +------------------------------------------ +| | | +| | | +| | | +| BASE | LOCAL | +| | | +| | | +| | | +------------------------------------------ +.... +.... +------------------------------------------ +| TAB #1 | TAB #2 | | | +------------------------------------------ +| | | +| | | +| | | +| BASE | REMOTE | +| | | +| | | +| | | +------------------------------------------ +.... +-- +* `layout = "LOCAL,BASE,REMOTE / MERGED + BASE,LOCAL + BASE,REMOTE + (LOCAL/BASE/REMOTE),MERGED"` ++ +-- +Same as the previous example, but adds a fourth tab with the same +information as the first tab, with a different layout. +.... +--------------------------------------------- +| TAB #1 | TAB #2 | TAB #3 | | +--------------------------------------------- +| LOCAL | | +|---------------------| | +| BASE | MERGED | +|---------------------| | +| REMOTE | | +--------------------------------------------- +.... +Note how in the third tab definition we need to use parenthesis to make `,` +have precedence over `/`. +-- + +Variants +^^^^^^^^ + +Instead of `--tool=vimdiff`, you can also use one of these other variants: + + * `--tool=gvimdiff`, to open gVim instead of Vim. + + * `--tool=nvimdiff`, to open Neovim instead of Vim. + +When using these variants, in order to specify a custom layout you will have to +set configuration variables `mergetool.gvimdiff.layout` and +`mergetool.nvimdiff.layout` instead of `mergetool.vimdiff.layout` + +In addition, for backwards compatibility with previous Git versions, you can +also append `1`, `2` or `3` to either `vimdiff` or any of the variants (ex: +`vimdiff3`, `nvimdiff1`, etc...) to use a predefined layout. +In other words, using `--tool=[g,n,]vimdiffx` is the same as using +`--tool=[g,n,]vimdiff` and setting configuration variable +`mergetool.[g,n,]vimdiff.layout` to... + + * `x=1`: `"@LOCAL, REMOTE"` + * `x=2`: `"LOCAL, MERGED, REMOTE"` + * `x=3`: `"MERGED"` + +Example: using `--tool=gvimdiff2` will open `gvim` with three columns (LOCAL, +MERGED and REMOTE). diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh index 542a6a75eb..9f99201bcc 100644 --- a/git-mergetool--lib.sh +++ b/git-mergetool--lib.sh @@ -63,7 +63,7 @@ $(list_tool_variants)" preamble= fi shown_any=yes - printf "%s%s\n" "$per_line_prefix" "$toolname" + printf "%s%-15s %s\n" "$per_line_prefix" "$toolname" $(diff_mode && diff_cmd_help "$toolname" || merge_cmd_help "$toolname") fi done @@ -162,10 +162,18 @@ setup_tool () { return 1 } + diff_cmd_help () { + return 0 + } + merge_cmd () { return 1 } + merge_cmd_help () { + return 0 + } + hide_resolved_enabled () { return 0 } diff --git a/mergetools/vimdiff b/mergetools/vimdiff index 9d1bf4f455..461a89b6f9 100644 --- a/mergetools/vimdiff +++ b/mergetools/vimdiff @@ -365,6 +365,25 @@ diff_cmd () { } +diff_cmd_help () { + TOOL=$1 + + case "$TOOL" in + nvimdiff*) + printf "Use Neovim" + ;; + gvimdiff*) + printf "Use gVim (requires a graphical session)" + ;; + vimdiff*) + printf "Use Vim" + ;; + esac + + return 0 +} + + merge_cmd () { layout=$(git config mergetool.vimdiff.layout) @@ -436,6 +455,40 @@ merge_cmd () { } +merge_cmd_help () { + TOOL=$1 + + case "$TOOL" in + nvimdiff*) + printf "Use Neovim " + ;; + gvimdiff*) + printf "Use gVim (requires a graphical session) " + ;; + vimdiff*) + printf "Use Vim " + ;; + esac + + case "$TOOL" in + *1) + echo "with a 2 panes layout (LOCAL and REMOTE)" + ;; + *2) + echo "with a 3 panes layout (LOCAL, MERGED and REMOTE)" + ;; + *3) + echo "where only the MERGED file is shown" + ;; + *) + echo "with a custom layout (see \`git help mergetool\`'s \`BACKEND SPECIFIC HINTS\` section)" + ;; + esac + + return 0 +} + + translate_merge_tool_path () { case "$1" in nvimdiff*)