{"thread":{"id":"15548","subject":"[PATCH] contrib: add a 'git difftool' command for driving common merge tools","startedAt":"2008-09-16T07:57:33Z","lastAt":"2008-09-16T07:57:33Z","messageCount":1,"participants":["David Aguilar"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"90818","messageId":"6385cbdec792ad2cd932dba38d68e2542efa5827.1221551358.git.davvid@gmail.com","threadId":"15548","inReplyTo":null,"subject":"[PATCH] contrib: add a 'git difftool' command for driving common merge tools","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2008-09-16T07:57:33Z","receivedAt":"2008-09-16T07:57:33Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"'git-difftool' is a git command that allows you to compare and edit files\nbetween revisions using standard git merge tools.  At its most basic level,\n'git-difftool' does what 'git-mergetool' does but its use is for non-merge\nsituations, such as when preparing commits or comparing changes against\nthe index.  It uses the same configuration variables as git-mergetool,\nso it automagically supports existing custom merge tool configurations.\n\n'git-difftool' shows differences between the work tree and the index by\ndefault but can also show differences between arbitrary commits by using\nthe --start and --end options.  When operating on the index, saving the\nmerged file from within the merge tool (and a successful exit code) will\ninstruct 'git-difftool' to stage the new content for commit.\n\nSigned-off-by: David Aguilar <davvid@gmail.com>\n---\n\ngit-difftool was adapted from git-mergetool, so there's some common code.\nIf people like this enough to move it out of contrib then I'll happily help\nfactor out the similarities.\n\nEvery CVS user I've met has asked for the functionality provided by this\ncommand in one form or another.  For some reason they just can't let go of\ntheir side-by-side diff viewer.\n\n contrib/difftool/git-difftool.sh  |  538 +++++++++++++++++++++++++++++++++++++\n contrib/difftool/git-difftool.txt |  130 +++++++++\n 2 files changed, 668 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/difftool/git-difftool.sh b/contrib/difftool/git-difftool.sh\nnew file mode 100755\nindex 0000000..bafd650\n--- /dev/null\n+++ b/contrib/difftool/git-difftool.sh\n@@ -0,0 +1,538 @@\n+#!/bin/sh\n+#\n+# This program uses merge tools to stage and compare commits\n+#\n+# Copyright (c) 2008 David Aguilar\n+#\n+# Adapted from git-mergetool.sh\n+# Copyright (c) 2006 Theodore Y. Ts'o\n+#\n+# This file is licensed under the GPL v2, or a later version\n+# at the discretion of Junio C Hamano.\n+#\n+USAGE='[--tool=tool] [--commit=ref] [--start=ref --end=ref] [--no-prompt] [file to merge] ...'\n+SUBDIRECTORY_OK=Yes\n+OPTIONS_SPEC=\n+. git-sh-setup\n+require_work_tree\n+cd_to_toplevel\n+dirname=\n+keep_backup_mode=\"$(git config --bool mergetool.keepBackup || echo true)\"\n+\n+keep_backup () {\n+\ttest \"$keep_backup_mode\" = \"true\"\n+}\n+\n+parse_arg () {\n+\texpr \"z$1\" : 'z-[^=]*=\\(.*\\)'\n+}\n+\n+index_present () {\n+    test -n \"$index_mode\"\n+}\n+\n+modified_present () {\n+    test -n \"$modified_mode\"\n+}\n+\n+commitish_present () {\n+\ttest -n \"$commitish\"\n+}\n+\n+should_prompt () {\n+\t! test -n \"$no_prompt\"\n+}\n+\n+use_rev_range () {\n+\ttest -n \"$start\" && test -n \"$end\"\n+}\n+\n+handle_dir () {\n+\ttest -n \"$non_existant_dir\"\n+}\n+\n+merge_three () {\n+\tindex_present && modified_present && ! use_rev_range\n+}\n+\n+modified_files () {\n+\tif use_rev_range; then\n+\t\tgit diff --name-only \"$start\"..\"$end\" -- \"$@\" 2>/dev/null\n+\telif commitish_present; then\n+\t\tgit diff --name-only \"$commitish\" -- \"$@\" 2>/dev/null\n+\telse\n+\t\tgit diff --name-only -- \"$@\" 2>/dev/null\n+\tfi\n+}\n+\n+staged_files() {\n+\tgit diff --name-only --cached \"$@\" 2>/dev/null\n+}\n+\n+cleanup_temp_files () {\n+\tif keep_backup && test \"$MERGED\" -nt \"$BACKUP\"; then\n+\t\ttest -f \"$BACKUP\" && mv -- \"$BACKUP\" \"$MERGED.orig\"\n+\t\trm -f -- \"$LOCAL\" \"$REMOTE\" \"$BASE\"\n+\telse\n+\t\trm -f -- \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$BACKUP\"\n+\tfi\n+\thandle_dir && rmdir -p \"$dirname\"\n+}\n+\n+check_unchanged () {\n+\tif test \"$MERGED\" -nt \"$BACKUP\"; then\n+\t\tstatus=0\n+\telse\n+\t\tstatus=1\n+\t\tuse_rev_range && status=0 # we don't 'git add' in rev-range mode\n+\t\tif ! use_rev_range && should_prompt; then\n+\t\t\twhile true\n+\t\t\tdo\n+\t\t\t\tprintf \"\\n$MERGED seems unchanged.\\n\"\n+\t\t\t\tprintf \"Was the merge successful? [y/n] \"\n+\t\t\t\tread answer < /dev/tty\n+\t\t\t\tcase \"$answer\" in\n+\t\t\t\ty*|Y*) status=0; break ;;\n+\t\t\t\tn*|N*) status=1; break ;;\n+\t\t\t\tesac\n+\t\t\tdone\n+\t\tfi\n+\tfi\n+}\n+\n+merge_file ()\n+{\n+\tMERGED=\"$1\"\n+\n+\tmodified_mode=$(modified_files \"$MERGED\")\n+\tindex_mode=$(staged_files \"$MERGED\")\n+\n+\tif ! modified_present && use_rev_range; then\n+\t\techo \"$MERGED: no changes between '$start' and '$end'.\"\n+\t\texit 1\n+\telif ! modified_present && ! index_present; then\n+\t\tif ! test -f \"$MERGED\"; then\n+\t\t\techo $(pwd)\n+\t\t\techo \"$MERGED: file not found\"\n+\t\telse\n+\t\t\techo \"$MERGED: file is unchanged.\"\n+\t\tfi\n+\t\texit 1\n+\tfi\n+\n+\tdirname=$(dirname \"$MERGED\")\n+\ttest -d \"$dirname\" || non_existant_dir=true\n+\thandle_dir && mkdir -p \"$dirname\"\n+\n+\text=\"$$$(expr \"$MERGED\" : '.*\\(\\.[^/]*\\)$')\"\n+\tBACKUP=\"./$MERGED.BACKUP.$ext\"\n+\n+\ttest -f \"$MERGED\" &&\n+\tmv -- \"$MERGED\" \"$BACKUP\" &&\n+\tcp -- \"$BACKUP\" \"$MERGED\"\n+\n+\tif use_rev_range; then\n+\t\tBASE=\"./$MERGED.LOCAL.$ext\"\n+\t\tLOCAL=\"./$MERGED.START.$ext\"\n+\t\tREMOTE=\"./$MERGED.END.$ext\"\n+\t\tbase=local\n+\t\tlocal=start\n+\t\tremote=end\n+\n+\t\tif ! git show \"$start\":\"$MERGED\" > \"$LOCAL\" 2>/dev/null; then\n+\t\t\tcleanup_temp_files;\n+\t\t\tif ! should_prompt; then\n+\t\t\t\techo \"$MERGED does not exist at $start\"\n+\t\t\t\texit 1\n+\t\t\tfi\n+\t\t\treturn\n+\t\tfi\n+\t\tif ! git show \"$end\":\"$MERGED\" > \"$REMOTE\" 2>/dev/null; then\n+\t\t\tcleanup_temp_files;\n+\t\t\tif ! should_prompt; then\n+\t\t\t\techo \"$MERGED does not exist at $end\"\n+\t\t\t\texit 1\n+\t\t\tfi\n+\t\t\treturn\n+\t\tfi\n+\n+\t\t# $BASE could be used by custom mergetool commands, so provide it.\n+\t\t# $MERGED might not exist in the worktree, start or end so commit\n+\t\t# so check in that order.\n+\t\tif test -f \"$MERGED\"; then\n+\t\t\tcp -- \"$MERGED\" \"$BASE\"\n+\t\telif test -f \"$REMOTE\"; then\n+\t\t\tcp -- \"$REMOTE\" \"$BASE\"\n+\t\telif test -f \"$LOCAL\"; then\n+\t\t\tcp -- \"$LOCAL\" \"$BASE\"\n+\t\telse\n+\t\t\ttouch \"$BASE\"\n+\t\tfi\n+\telse\n+\t\tbase=index\n+\t\tlocal=local\n+\t\tremote=${commitish-HEAD}\n+\t\tLOCAL=\"./$MERGED.LOCAL.$ext\"\n+\t\tREMOTE=\"./$MERGED.HEAD.$ext\"\n+\t\tBASE=\"./$MERGED.INDEX.$ext\"\n+\t\tcp -- \"$MERGED\" \"$LOCAL\"\n+\t\tgit show \"$remote\":\"$MERGED\" > \"$REMOTE\" 2>&1\n+\t\t# If changes are present in the index use them as $BASE\n+\t\tgit checkout-index --prefix=.index- \"$MERGED\"\n+\t\tmv -- .index-\"$MERGED\" \"$BASE\"\n+\tfi\n+\n+\tif should_prompt; then\n+\t\tprintf \"\\nEditing '$MERGED':\\n\"\n+\t\tprintf \"Hit return to start merge tool (%s): \" \"$merge_tool\"\n+\t\tread ans\n+\tfi\n+\n+\tcase \"$merge_tool\" in\n+\tkdiff3)\n+\t\tbasename=$(basename \"$MERGED\")\n+\t\tif merge_three; then\n+\t\t(\n+\t\t\t\"$merge_tool_path\" --auto \\\n+\t\t\t\t--L1 \"[$base] $basename\" \\\n+\t\t\t\t--L2 \"[$local] $basename\" \\\n+\t\t\t\t--L3 \"[$remote] $basename\" \\\n+\t\t\t\t-o \"$MERGED\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t> /dev/null 2>&1\n+\t\t)\n+\t\telse\n+\t\t(\n+\t\t\t\"$merge_tool_path\" --auto \\\n+\t\t\t\t--L1 \"[$local] $basename\" \\\n+\t\t\t\t--L2 \"[$remote] $basename\" \\\n+\t\t\t\t-o \"$MERGED\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t> /dev/null 2>&1\n+\t\t)\n+\t\tfi\n+\t\tstatus=$?\n+\t\t;;\n+\n+\ttkdiff)\n+\t\tif merge_three; then\n+\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t-a \"$BASE\" \\\n+\t\t\t\t-o \"$MERGED\" \"$LOCAL\" \"$REMOTE\"\n+\t\telse\n+\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t-o \"$MERGED\" \"$LOCAL\" \"$REMOTE\"\n+\t\tfi\n+\t\tstatus=$?\n+\t\t;;\n+\n+\tmeld|vimdiff)\n+\t\t\"$merge_tool_path\" \"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n+\t\tcheck_unchanged\n+\t\t;;\n+\n+\tgvimdiff)\n+\t\t\"$merge_tool_path\" -f \"$LOCAL\" \"$MERGED\" \"$REMOTE\"\n+\t\tcheck_unchanged\n+\t\t;;\n+\n+\txxdiff)\n+\t\tif merge_three; then\n+\t\t\t\"$merge_tool_path\" -X --show-merged-pane \\\n+\t\t\t\t-R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n+\t\t\t\t-R 'Accel.Search: \"Ctrl+F\"' \\\n+\t\t\t\t-R 'Accel.SearchForward: \"Ctrl-G\"' \\\n+\t\t\t\t--merged-file \"$MERGED\" \\\n+\t\t\t\t\"$LOCAL\" \"$BASE\" \"$REMOTE\"\n+\t\telse\n+\t\t\t\"$merge_tool_path\" -X --show-merged-pane \\\n+\t\t\t\t-R 'Accel.SaveAsMerged: \"Ctrl-S\"' \\\n+\t\t\t\t-R 'Accel.Search: \"Ctrl+F\"' \\\n+\t\t\t\t-R 'Accel.SearchForward: \"Ctrl-G\"' \\\n+\t\t\t\t--merged-file \"$MERGED\" \\\n+\t\t\t\t\"$LOCAL\" \"$REMOTE\"\n+\t\tfi\n+\t\tcheck_unchanged\n+\t\t;;\n+\n+\topendiff)\n+\t\tif merge_three; then\n+\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t-ancestor \"$BASE\" \\\n+\t\t\t\t-merge \"$MERGED\" | cat\n+\t\telse\n+\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t-merge \"$MERGED\" | cat\n+\t\tfi\n+\t\tcheck_unchanged\n+\t\t;;\n+\n+\tecmerge)\n+\t\tif merge_three; then\n+\t\t\t\"$merge_tool_path\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t--default --mode=merge3 --to=\"$MERGED\"\n+\t\telse\n+\t\t\t\"$merge_tool_path\" \"$LOCAL\" \"$REMOTE\" \\\n+\t\t\t\t--default --mode=merge2 --to=\"$MERGED\"\n+\t\tfi\n+\t\tcheck_unchanged\n+\t\t;;\n+\n+\temerge)\n+\t\tif merge_three; then\n+\t\t\t\"$merge_tool_path\" \\\n+\t\t\t\t-f emerge-files-with-ancestor-command \\\n+\t\t\t\t\"$LOCAL\" \"$REMOTE\" \"$BASE\" \\\n+\t\t\t\t\"$(basename \"$MERGED\")\"\n+\t\telse\n+\t\t\t\"$merge_tool_path\" -f emerge-files-command \\\n+\t\t\t\t\"$LOCAL\" \"$REMOTE\" \"$(basename \"$MERGED\")\"\n+\t\tfi\n+\t\tstatus=$?\n+\t\t;;\n+\t*)\n+\t\tif test -n \"$merge_tool_cmd\"; then\n+\t\t\tif test \"$merge_tool_trust_exit_code\" = \"false\"; then\n+\t\t\t\t( eval $merge_tool_cmd )\n+\t\t\t\tcheck_unchanged\n+\t\t\telse\n+\t\t\t\t( eval $merge_tool_cmd )\n+\t\t\t\tstatus=$?\n+\t\t\tfi\n+\t\tfi\n+\t\t;;\n+\tesac\n+\n+\tif ! use_rev_range; then\n+\t\tif test \"$status\" -ne 0; then\n+\t\t\tif should_prompt; then\n+\t\t\t\techo \"merge of $MERGED failed\" 1>&2\n+\t\t\tfi\n+\t\t\tcleanup_temp_files\n+\t\t\texit 1\n+\t\tfi\n+\t\tgit add -- \"$MERGED\"\n+\tfi\n+\tcleanup_temp_files\n+}\n+\n+while test $# != 0\n+do\n+\tcase \"$1\" in\n+\t-t|--tool*)\n+\t\tcase \"$#,$1\" in\n+\t\t*,*=*)\n+\t\t\tmerge_tool=$(parse_arg \"$1\")\n+\t\t\tshift\n+\t\t\t;;\n+\t\t1,*)\n+\t\t\tusage\n+\t\t\t;;\n+\t\t*)\n+\t\t\tshift\n+\t\t\tmerge_tool=\"$1\"\n+\t\t\tshift\n+\t\t\t;;\n+\t\tesac\n+\t\t;;\n+\t-c|--commit*)\n+\t\tcase \"$#,$1\" in\n+\t\t*,*=*)\n+\t\t\tcommitish=$(parse_arg \"$1\")\n+\t\t\tshift\n+\t\t\t;;\n+\t\t1,*)\n+\t\t\tusage\n+\t\t\t;;\n+\t\t*)\n+\t\t\tshift\n+\t\t\tcommitish=\"$1\"\n+\t\t\tshift\n+\t\t\t;;\n+\t\tesac\n+\t\t;;\n+\t-s|--start*)\n+\t\tcase \"$#,$1\" in\n+\t\t*,*=*)\n+\t\t\tstart=$(parse_arg \"$1\")\n+\t\t\tshift\n+\t\t\t;;\n+\t\t1,*)\n+\t\t\tusage\n+\t\t\t;;\n+\t\t*)\n+\t\t\tshift\n+\t\t\tstart=\"$1\"\n+\t\t\tshift\n+\t\t\t;;\n+\t\tesac\n+\t\t;;\n+\t-e|--end*)\n+\t\tcase \"$#,$1\" in\n+\t\t*,*=*)\n+\t\t\tend=$(parse_arg \"$1\")\n+\t\t\tshift\n+\t\t\t;;\n+\t\t1,*)\n+\t\t\tusage\n+\t\t\t;;\n+\t\t*)\n+\t\t\tshift\n+\t\t\tend=\"$1\"\n+\t\t\tshift\n+\t\t\t;;\n+\t\tesac\n+\t\t;;\n+\t--no-prompt)\n+\t\tno_prompt=true\n+\t\tshift\n+\t\t;;\n+\t--)\n+\t\tshift\n+\t\tbreak\n+\t\t;;\n+\t-*)\n+\t\tusage\n+\t\t;;\n+\t*)\n+\t\tbreak\n+\t\t;;\n+\tesac\n+done\n+\n+valid_custom_tool()\n+{\n+    merge_tool_cmd=\"$(git config mergetool.$1.cmd)\"\n+    test -n \"$merge_tool_cmd\"\n+}\n+\n+valid_tool()\n+{\n+\tcase \"$1\" in\n+\tkdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge)\n+\t\t;; # happy\n+\t*)\n+\t\tif ! valid_custom_tool \"$1\"\n+\t\tthen\n+\t\t\treturn 1\n+\t\tfi\n+\t\t;;\n+\tesac\n+}\n+\n+init_merge_tool_path()\n+{\n+\tmerge_tool_path=$(git config mergetool.\"$1\".path)\n+\tif test -z \"$merge_tool_path\"; then\n+\t\tcase \"$1\" in\n+\t\temerge)\n+\t\t\tmerge_tool_path=emacs\n+\t\t\t;;\n+\t\t*)\n+\t\t\tmerge_tool_path=\"$1\"\n+\t\t\t;;\n+\t\tesac\n+\tfi\n+}\n+\n+\n+if test -z \"$merge_tool\"; then\n+\tmerge_tool=$(git config merge.tool)\n+\tif test -n \"$merge_tool\" && ! valid_tool \"$merge_tool\"; then\n+\t\techo >&2 \"git config option merge.tool set to unknown tool: $merge_tool\"\n+\t\techo >&2 \"Resetting to default...\"\n+\t\tunset merge_tool\n+\tfi\n+fi\n+\n+if test -z \"$merge_tool\"; then\n+\tif test -n \"$DISPLAY\"; then\n+\t\tmerge_tool_candidates=\"kdiff3 tkdiff xxdiff meld gvimdiff\"\n+\t\tif test -n \"$GNOME_DESKTOP_SESSION_ID\"; then\n+\t\t\tmerge_tool_candidates=\"meld $merge_tool_candidates\"\n+\t\tfi\n+\t\tif test \"$KDE_FULL_SESSION\" = \"true\"; then\n+\t\t\tmerge_tool_candidates=\"kdiff3 $merge_tool_candidates\"\n+\t\tfi\n+\tfi\n+\n+\tif echo \"${VISUAL:-$EDITOR}\" | grep 'emacs' > /dev/null 2>&1; then\n+\t\tmerge_tool_candidates=\"$merge_tool_candidates emerge\"\n+\tfi\n+\n+\tif echo \"${VISUAL:-$EDITOR}\" | grep 'vim' > /dev/null 2>&1; then\n+\t\tmerge_tool_candidates=\"$merge_tool_candidates vimdiff\"\n+\tfi\n+\n+\tmerge_tool_candidates=\"$merge_tool_candidates opendiff emerge vimdiff\"\n+\techo \"merge tool candidates: $merge_tool_candidates\"\n+\n+\tfor i in $merge_tool_candidates\n+\tdo\n+\t\tinit_merge_tool_path $i\n+\t\tif type \"$merge_tool_path\" > /dev/null 2>&1; then\n+\t\t\tmerge_tool=$i\n+\t\t\tbreak\n+\t\tfi\n+\tdone\n+\n+\tif test -z \"$merge_tool\" ; then\n+\t\techo \"No known merge resolution program available.\"\n+\t\texit 1\n+\tfi\n+\n+else\n+\tif ! valid_tool \"$merge_tool\"; then\n+\t\techo >&2 \"Unknown merge tool $merge_tool\"\n+\t\texit 1\n+\tfi\n+\n+\tinit_merge_tool_path \"$merge_tool\"\n+\n+\tif test -z \"$merge_tool_cmd\" && ! type \"$merge_tool_path\" > /dev/null 2>&1; then\n+\t\techo \"The merge tool $merge_tool is not available as '$merge_tool_path'\"\n+\t\texit 1\n+\tfi\n+\n+\tif ! test -z \"$merge_tool_cmd\"; then\n+\t\tmerge_tool_trust_exit_code=\"$(git config --bool mergetool.$merge_tool.trustExitCode || echo false)\"\n+\tfi\n+fi\n+\n+\n+if test $# -eq 0; then\n+\tuse_index=0\n+\tfiles=$(modified_files)\n+\n+\tif test -z \"$files\"; then\n+\t\tuse_index=1\n+\t\tfiles=$(staged_files)\n+\tfi\n+\n+\tif test -z \"$files\"; then\n+\t\techo \"No modified files exist.\"\n+\t\texit 0\n+\tfi\n+\n+\tif test $use_index -eq 0; then\n+\t\tmodified_files |\n+\t\twhile IFS= read i\n+\t\tdo\n+\t\t\tmerge_file \"$i\" < /dev/tty > /dev/tty\n+\t\tdone\n+\telif ! use_rev_range; then\n+\t\tstaged_files |\n+\t\twhile IFS= read i\n+\t\tdo\n+\t\t\tmerge_file \"$i\" < /dev/tty > /dev/tty\n+\t\tdone\n+\telse\n+\t\techo \"Nothing to compare.\"\n+\t\texit 0\n+\tfi\n+else\n+\twhile test $# -gt 0\n+\tdo\n+\t\tmerge_file \"$1\"\n+\t\tshift\n+\tdone\n+fi\n+exit $status\ndiff --git a/contrib/difftool/git-difftool.txt b/contrib/difftool/git-difftool.txt\nnew file mode 100644\nindex 0000000..ddc090d\n--- /dev/null\n+++ b/contrib/difftool/git-difftool.txt\n@@ -0,0 +1,130 @@\n+git-difftool(1)\n+===============\n+\n+NAME\n+----\n+git-difftool - stage and compare changes using git merge tools\n+\n+SYNOPSIS\n+--------\n+'git difftool' [--tool=<tool>]\n+               [--commit=<ref> | --start=<ref> --end=<ref>]\n+               [--no-prompt]\n+               [--] [<file>]...\n+\n+DESCRIPTION\n+-----------\n+'git-difftool' is a git command that allows you to compare and edit files\n+between revisions using standard git merge tools.  At its most basic level,\n+'git-difftool' does what 'git-mergetool' does but its use is for non-merge\n+situations, such as when preparing commits or comparing changes against\n+the index.\n+\n+'git-difftool' shows differences between the work tree and the index by\n+default but can also show differences between arbitrary commits by using\n+the --start and --end options.  When operating on the index, saving the\n+merged file from within the merge tool (and a successful exit code) will\n+instruct 'git-difftool' to stage the new content for commit.\n+\n+OPTIONS\n+-------\n+\n+-t or --tool=<tool>::\n+\tUse the merge resolution program specified by <tool>.\n+\tValid merge tools are:\n+\tkdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, and opendiff\n++\n+If a merge resolution program is not specified, 'git-difftool'\n+will use the configuration variable `merge.tool`.  If the\n+configuration variable `merge.tool` is not set, 'git-difftool'\n+will pick a suitable default.\n++\n+You can explicitly provide a full path to the tool by setting the\n+configuration variable `mergetool.<tool>.path`. For example, you\n+can configure the absolute path to kdiff3 by setting\n+`mergetool.kdiff3.path`. Otherwise, 'git-difftool' assumes the\n+tool is available in PATH.\n++\n+Instead of running one of the known merge tool programs,\n+'git-difftool' can be customized to run an alternative program\n+by specifying the command line to invoke in a configuration\n+variable `mergetool.<tool>.cmd`.\n++\n+When 'git-difftool' is invoked with this tool (either through the\n+`-t` or `--tool` option or the `merge.tool` configuration variable)\n+the configured command line will be invoked with the following\n+variables available: `$BASE` is set to the name of a temporary file\n+containing the contents of the index; `$LOCAL` set to the name of a\n+temporary file containing the contents of the file as it appears in\n+the work tree; `$REMOTE` set to the name of a temporary file\n+containing the contents of the file to be merged, and `$MERGED` set\n+to the name of the file to which the merge tool should write the\n+result of the merge resolution.\n++\n+When `--start=<ref>` and `--end=<ref>` are specified\n+`$LOCAL` contains the contents of the file from the\n+starting revision and `$REMOTE` contains the contents\n+of the file in the ending revision.  `$BASE` contains\n+the contents of the file in the work tree if it exists,\n+and the starting revision otherwise.\n++\n+If the custom merge tool correctly indicates the success of a\n+merge resolution with its exit code then the configuration\n+variable `mergetool.<tool>.trustExitCode` can be set to `true`.\n+Otherwise, 'git-difftool' will prompt the user to indicate the\n+success of the resolution after the custom tool has exited.\n+\n+-c or --commit=<ref>::\n+\tSpecifies a commit reference for comparing against.\n+\t'git-difftool' compares against the index by default.\n+\n+--no-prompt::\n+\tDo not prompt before and after launching a merge tool.\n+\n+-s or --start=<ref> and -e or --end=<ref>::\n+\tSee changes between commits start and end.\n+\tThis example shows the latest commit: `--start=HEAD^ --end=HEAD`.\n+\n+CONFIG VARIABLES\n+----------------\n+\n+merge.tool::\n+\tThe default merge tool to use.\n++\n+See the `--tool=<tool>` option above for more details.\n+\n+mergetool.<tool>.path::\n+\tOverride the path for the given tool.  This is useful in case\n+\tyour tool is not in the PATH.\n+\n+mergetool.<tool>.cmd::\n+\tSpecify the command to invoke the specified merge tool.\n++\n+See the `--tool=<tool>` option above for more details.\n+\n+mergetool.<tool>.trustExitCode::\n+\tFor a custom merge command, specify whether the exit code of\n+\tthe merge command can be used to determine whether the merge was\n+\tsuccessful.  If this is not set to true then the merge target file\n+\ttimestamp is checked and the merge assumed to have been successful\n+\tif the file has been updated, otherwise the user is prompted to\n+\tindicate the success of the merge.\n+\n+mergetool.keepBackup::\n+\tThe original, unedit file content can be saved to a file with\n+\ta `.orig` extension. Defaults to `true` (i.e. keep the backup files).\n+\n+\n+SEE ALSO\n+--------\n+linkgit:git-mergetool[1]::\n+\t'git-difftool' uses many of the same concepts as the core\n+\t'git-mergetool' command.\n+\n+linkgit:git-config[7]::\n+\t Get and set repository or global options.\n+\n+AUTHOR\n+------\n+Written by David Aguilar <davvid@gmail.com>.\n+\n-- \n1.6.0.2.229.g1293c\n"}]}