#!/bin/sh # git-difftool--helper is a GIT_EXTERNAL_DIFF-compatible diff tool launcher. # This script is typically launched by using the 'git difftool' # convenience command. # # Copyright (c) 2009, 2010 David Aguilar global TOOL_MODE := 'diff' source git-mergetool--lib # difftool.prompt controls the default prompt/no-prompt behavior # and is overridden with $GIT_DIFFTOOL*_PROMPT. proc should_prompt { global prompt_merge := $[git config --bool mergetool.prompt || echo true] global prompt := $[git config --bool difftool.prompt || echo $prompt_merge] if test $prompt = true { test -z $GIT_DIFFTOOL_NO_PROMPT } else { test -n $GIT_DIFFTOOL_PROMPT } } # Indicates that --extcmd=... was specified proc use_ext_cmd { test -n $GIT_DIFFTOOL_EXTCMD } proc launch_merge_tool { # Merged is the filename as it appears in the work tree # Local is the contents of a/filename # Remote is the contents of b/filename # Custom merge tool commands might use $BASE so we provide it global MERGED := $1 global LOCAL := $2 global REMOTE := $3 global BASE := $1 # $LOCAL and $REMOTE are temporary files so prompt # the user with the real $MERGED name before launching $merge_tool. if should_prompt { printf "\nViewing (%s/%s): '%s'\n" $GIT_DIFF_PATH_COUNTER \ $GIT_DIFF_PATH_TOTAL $MERGED if use_ext_cmd { printf "Launch '%s' [Y/n]? " \ $GIT_DIFFTOOL_EXTCMD } else { printf "Launch '%s' [Y/n]? " $merge_tool } read ans || return if test $ans = n { return } } if use_ext_cmd { export BASE eval $GIT_DIFFTOOL_EXTCMD '"$LOCAL"' '"$REMOTE"' } else { run_merge_tool $merge_tool } } if ! use_ext_cmd { if test -n $GIT_DIFF_TOOL { global merge_tool := $GIT_DIFF_TOOL } else { global merge_tool := $[get_merge_tool] || exit } } if test -n $GIT_DIFFTOOL_DIRDIFF { global LOCAL := $1 global REMOTE := $2 run_merge_tool $merge_tool false } else { # Launch the merge tool on each path provided by 'git diff' while test $# -gt 6 { launch_merge_tool $1 $2 $5 global status := $Status if test $status -ge 126 { # Command not found (127), not executable (126) or # exited via a signal (>= 128). exit $status } if test $status != 0 && test $GIT_DIFFTOOL_TRUST_EXIT_CODE = true { exit $status } shift 7 } } exit 0 (CommandList children: [ (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:TOOL_MODE) op:Equal rhs:{(diff)} spids:[19])] spids: [19] ) (C {(.)} {(git-mergetool--lib)}) (FuncDef name: should_prompt body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:prompt_merge) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (AndOr children: [ (C {(git)} {(config)} {(--bool)} {(mergetool.prompt)}) (C {(echo)} {(true)}) ] op_id: Op_DPipe ) ] ) left_token: spids: [42 56] ) } spids: [41] ) ] spids: [41] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:prompt) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (AndOr children: [ (C {(git)} {(config)} {(--bool)} {(difftool.prompt)}) (C {(echo)} {($ VSub_Name "$prompt_merge")}) ] op_id: Op_DPipe ) ] ) left_token: spids: [60 74] ) } spids: [59] ) ] spids: [59] ) (If arms: [ (if_arm cond: [(C {(test)} {(DQ ($ VSub_Name "$prompt"))} {(Lit_Other "=")} {(true)})] action: [(C {(test)} {(-z)} {(DQ ($ VSub_Name "$GIT_DIFFTOOL_NO_PROMPT"))})] spids: [-1 90] ) ] else_action: [(C {(test)} {(-n)} {(DQ ($ VSub_Name "$GIT_DIFFTOOL_PROMPT"))})] spids: [102 114] ) ] spids: [38] ) spids: [33 37] ) (FuncDef name: use_ext_cmd body: (BraceGroup children: [(C {(test)} {(-n)} {(DQ ($ VSub_Name "$GIT_DIFFTOOL_EXTCMD"))})] spids: [127] ) spids: [122 126] ) (FuncDef name: launch_merge_tool body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:MERGED) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [165] ) ] spids: [165] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:LOCAL) op: Equal rhs: {(DQ ($ VSub_Number "$2"))} spids: [171] ) ] spids: [171] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:REMOTE) op: Equal rhs: {(DQ ($ VSub_Number "$3"))} spids: [177] ) ] spids: [177] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:BASE) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [183] ) ] spids: [183] ) (If arms: [ (if_arm cond: [(C {(should_prompt)})] action: [ (C {(printf)} { (DQ (EscapedLiteralPart token:) ("Viewing (%s/%s): '%s'") (EscapedLiteralPart token:) ) } {(DQ ($ VSub_Name "$GIT_DIFF_PATH_COUNTER"))} {(DQ ($ VSub_Name "$GIT_DIFF_PATH_TOTAL"))} {(DQ ($ VSub_Name "$MERGED"))} ) (If arms: [ (if_arm cond: [(C {(use_ext_cmd)})] action: [ (C {(printf)} {(DQ ("Launch '%s' [Y/n]? "))} {(DQ ($ VSub_Name "$GIT_DIFFTOOL_EXTCMD"))} ) ] spids: [-1 234] ) ] else_action: [ (C {(printf)} {(DQ ("Launch '%s' [Y/n]? "))} {(DQ ($ VSub_Name "$merge_tool"))}) ] spids: [250 264] ) (AndOr children: [(C {(read)} {(ans)}) (ControlFlow token:)] op_id: Op_DPipe ) (If arms: [ (if_arm cond: [(C {(test)} {(DQ ($ VSub_Name "$ans"))} {(Lit_Other "=")} {(n)})] action: [(ControlFlow token:)] spids: [-1 289] ) ] spids: [-1 295] ) ] spids: [-1 203] ) ] spids: [-1 298] ) (If arms: [ (if_arm cond: [(C {(use_ext_cmd)})] action: [ (C {(export)} {(BASE)}) (C {(eval)} {($ VSub_Name "$GIT_DIFFTOOL_EXTCMD")} {(SQ <"\"$LOCAL\"">)} {(SQ <"\"$REMOTE\"">)} ) ] spids: [-1 307] ) ] else_action: [(C {(run_merge_tool)} {(DQ ($ VSub_Name "$merge_tool"))})] spids: [328 338] ) ] spids: [146] ) spids: [141 145] ) (If arms: [ (if_arm cond: [(Pipeline children:[(C {(use_ext_cmd)})] negated:True)] action: [ (If arms: [ (if_arm cond: [(C {(test)} {(-n)} {(DQ ($ VSub_Name "$GIT_DIFF_TOOL"))})] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:merge_tool) op: Equal rhs: {(DQ ($ VSub_Name "$GIT_DIFF_TOOL"))} spids: [366] ) ] spids: [366] ) ] spids: [-1 363] ) ] else_action: [ (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:merge_tool) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children:[(C {(get_merge_tool)})]) left_token: spids: [377 379] ) ) } spids: [375] ) ] spids: [375] ) (C {(exit)}) ] op_id: Op_DPipe ) ] spids: [372 387] ) ] spids: [-1 349] ) ] spids: [-1 389] ) (If arms: [ (if_arm cond: [(C {(test)} {(-n)} {(DQ ($ VSub_Name "$GIT_DIFFTOOL_DIRDIFF"))})] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:LOCAL) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [405] ) ] spids: [405] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:REMOTE) op: Equal rhs: {(DQ ($ VSub_Number "$2"))} spids: [411] ) ] spids: [411] ) (C {(run_merge_tool)} {(DQ ($ VSub_Name "$merge_tool"))} {(false)}) ] spids: [-1 402] ) ] else_action: [ (While cond: [(C {(test)} {($ VSub_Pound "$#")} {(-gt)} {(6)})] body: (DoGroup children: [ (C {(launch_merge_tool)} {(DQ ($ VSub_Number "$1"))} {(DQ ($ VSub_Number "$2"))} {(DQ ($ VSub_Number "$5"))} ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:status) op: Equal rhs: {($ VSub_QMark "$?")} spids: [461] ) ] spids: [461] ) (If arms: [ (if_arm cond: [(C {(test)} {($ VSub_Name "$status")} {(-ge)} {(126)})] action: [(C {(exit)} {($ VSub_Name "$status")})] spids: [-1 476] ) ] spids: [-1 492] ) (If arms: [ (if_arm cond: [ (AndOr children: [ (C {(test)} {(DQ ($ VSub_Name "$status"))} {(KW_Bang "!") (Lit_Other "=")} {(0)} ) (C {(test)} {(DQ ($ VSub_Name "$GIT_DIFFTOOL_TRUST_EXIT_CODE"))} {(Lit_Other "=")} {(true)} ) ] op_id: Op_DAmp ) ] action: [(C {(exit)} {($ VSub_Name "$status")})] spids: [-1 523] ) ] spids: [-1 531] ) (C {(shift)} {(7)}) ] spids: [443 539] ) ) ] spids: [425 541] ) (C {(exit)} {(0)}) ] )