diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh
index 542a6a75eb..555fdd0392 100644
--- a/git-mergetool--lib.sh
+++ b/git-mergetool--lib.sh
@@ -64,6 +64,12 @@ $(list_tool_variants)"
 				fi
 				shown_any=yes
 				printf "%s%s\n" "$per_line_prefix" "$toolname"
+
+				diff_mode && diff_cmd_help "$toolname" || merge_cmd_help "$toolname" |
+				while read -r line
+				do
+					printf "%s\t%s\n" "$per_line_prefix" "$line"
+				done
 			fi
 		done
 
@@ -162,10 +168,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 c7b3cf84a2..faef0d6a63 100644
--- a/mergetools/vimdiff
+++ b/mergetools/vimdiff
@@ -462,6 +462,47 @@ diff_cmd () {
 }
 
 
+diff_cmd_help() {
+	case "$1" in
+	vimdiff)
+		cat <<-\EOF
+		Opens vim with two vertical windows: LOCAL changes will be placed in the left
+		window and REMOTE changes in the right one.
+		EOF
+		;;
+	vimdiff*)
+		cat <<-\EOF
+		Same as 'vimdiff'
+		EOF
+		;;
+	gvimdiff)
+		cat <<-\EOF
+		Same as 'vimdiff' but opens 'gvim' instead (which uses a graphical toolkit for
+		opening its own window)
+		EOF
+		;;
+	gvimdiff*)
+		cat <<-\EOF
+		Same as 'gvimdiff'
+		EOF
+		;;
+	nvimdiff)
+		cat <<-\EOF
+		Same as 'vimdiff' but opens 'neovim' instead (which is a fork of the original
+		'vim' 'focused on extensibility and usability' according to their authors)
+		EOF
+		;;
+	nvimdiff*)
+		cat <<-\EOF
+		Same as 'nvimdiff'
+		EOF
+		;;
+	esac
+
+	return 0
+}
+
+
 merge_cmd () {
 	layout=$(git config mergetool.$merge_tool.layout)
 
@@ -533,6 +574,227 @@ merge_cmd () {
 }
 
 
+merge_cmd_help() {
+	case "$1" in
+	vimdiff)
+		cat <<-\EOF
+		Opens 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 a specific git commit ("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".
+		
+		You can change the windows layout used by vim by setting configuration variable
+		"mergetool.vimdiff.layout" which accepts a string where these 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. In not present, "MERGED" will be used by default.
+		
+		The precedence of the operators is this one (you can use parenthesis to change
+		it):
+		
+		    @ > + > / > ,
+		
+		Let's see some examples to undertand 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 #1> |  TAB #2  |  TAB #3  |       |
+		           ------------------------------------------
+		           |             |           |              |
+		           |   LOCAL     |   BASE    |   REMOTE     |
+		           |             |           |              |
+		           ------------------------------------------
+		           |                                        |
+		           |                MERGED                  |
+		           |                                        |
+		           ------------------------------------------
+		
+		           ------------------------------------------
+		           |  TAB #1  | <TAB #2> |  TAB #3  |       |
+		           ------------------------------------------
+		           |                   |                    |
+		           |                   |                    |
+		           |                   |                    |
+		           |     BASE          |    LOCAL           |
+		           |                   |                    |
+		           |                   |                    |
+		           |                   |                    |
+		           ------------------------------------------
+		
+		           ------------------------------------------
+		           |  TAB #1  |  TAB #2  | <TAB #3> |       |
+		           ------------------------------------------
+		           |                   |                    |
+		           |                   |                    |
+		           |                   |                    |
+		           |     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  | <TAB #4> |
+		           ---------------------------------------------
+		           |       LOCAL         |                     |
+		           |---------------------|                     |
+		           |       BASE          |        MERGED       |
+		           |---------------------|                     |
+		           |       REMOTE        |                     |
+		           ---------------------------------------------
+		
+		    Note how in the third tab definition we need to use parenthesis to make ","
+		    more prioritary than "/".
+		
+		EOF
+		;;
+	vimdiff1)
+		cat <<-\EOF
+		Same as 'vimdiff' using this layout: "@LOCAL,REMOTE"
+		EOF
+		;;
+	vimdiff2)
+		cat <<-\EOF
+		Same as 'vimdiff' using this layout: "LOCAL,MERGED,REMOTE"
+		EOF
+		;;
+	vimdiff3)
+		cat <<-\EOF
+		Same as 'vimdiff' using this layout: "MERGED"
+		EOF
+		;;
+	gvimdiff)
+		cat <<-\EOF
+		Same as 'vimdiff' but opens 'gvim' instead (which uses a graphical toolkit for
+		opening its own window).
+		The desired layout can be set with configuration variable
+		"mergetool.gvimdiff.layout"
+		EOF
+		;;
+	gvimdiff1)
+		cat <<-\EOF
+		Same as 'gvimdiff' using this layout: "@LOCAL,REMOTE"
+		EOF
+		;;
+	gvimdiff2)
+		cat <<-\EOF
+		Same as 'gvimdiff' using this layout: "LOCAL,MERGED,REMOTE"
+		EOF
+		;;
+	gvimdiff3)
+		cat <<-\EOF
+		Same as 'gvimdiff' using this layout: "MERGED"
+		EOF
+		;;
+	nvimdiff)
+		cat <<-\EOF
+		Same as 'vimdiff' but opens 'neovim' instead (which is a fork of the original
+		'vim' 'focused on extensibility and usability' according to their authors)
+		The desired layout can be set with configuration variable
+		"mergetool.nvimdiff.layout"
+		EOF
+		;;
+	nvimdiff1)
+		cat <<-\EOF
+			Same as 'nvimdiff' using this layout: "@LOCAL,REMOTE"
+		EOF
+		;;
+	nvimdiff2)
+		cat <<-\EOF
+		Same as 'nvimdiff' using this layout: "LOCAL,MERGED,REMOTE"
+		EOF
+		;;
+	nvimdiff3)
+		cat <<-\EOF
+		Same as 'nvimdiff' using this layout: "MERGED"
+		EOF
+		;;
+	esac
+
+	return 0
+}
+
+
 translate_merge_tool_path() {
 	case "$1" in
 	nvimdiff*)
