mergetool: add an option for writing to a temporary directory

Teach mergetool to write files in a temporary directory when 'mergetool.writeToTemp' is true. This is helpful for tools such as Eclipse which cannot cope with multiple copies of the same file in the worktree. Suggested-by: Charles Bailey <charles@hashpling.org> Signed-off-by: David Aguilar <davvid@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

David Aguilar committed Oct 11, 2014 at 10:04 UTC 8f0cb41da26c1e20cfbcfded030d6539464b132e
2 files changed +37 -4
Documentation/config.txt
+6
@@ -1755,6 +1755,12 @@ mergetool.keepTemporaries::
1755 preserved, otherwise they will be removed after the tool has
1756 exited. Defaults to `false`.
1757
1758 +mergetool.writeToTemp::
1759 + Git writes temporary 'BASE', 'LOCAL', and 'REMOTE' versions of
1760 + conflicting files in the worktree by default. Git will attempt
1761 + to use a temporary directory for these files when set `true`.
1762 + Defaults to `false`.
1763 +
1764 mergetool.prompt::
1765 Prompt before each invocation of the merge resolution program.
1766
git-mergetool.sh
+31 -4
@@ -37,6 +37,19 @@ base_present () {
37 test -n "$base_mode"
38 }
39
40 +mergetool_tmpdir_init () {
41 + if test "$(git config --bool mergetool.writeToTemp)" != true
42 + then
43 + MERGETOOL_TMPDIR=.
44 + return 0
45 + fi
46 + if MERGETOOL_TMPDIR=$(mktemp -d -t "git-mergetool-XXXXXX" 2>/dev/null)
47 + then
48 + return 0
49 + fi
50 + die "error: mktemp is needed when 'mergetool.writeToTemp' is true"
51 +}
52 +
53 cleanup_temp_files () {
54 if test "$1" = --save-backup
55 then
@@ -46,6 +59,10 @@ cleanup_temp_files () {
59 else
60 rm -f -- "$LOCAL" "$REMOTE" "$BASE" "$BACKUP"
61 fi
62 + if test "$MERGETOOL_TMPDIR" != "."
63 + then
64 + rmdir "$MERGETOOL_TMPDIR"
65 + fi
66 }
67
68 describe_file () {
@@ -235,10 +252,20 @@ merge_file () {
252 BASE=$MERGED
253 ext=
254 fi
238 - BACKUP="./${BASE}_BACKUP_$$$ext"
239 - LOCAL="./${BASE}_LOCAL_$$$ext"
240 - REMOTE="./${BASE}_REMOTE_$$$ext"
241 - BASE="./${BASE}_BASE_$$$ext"
255 +
256 + mergetool_tmpdir_init
257 +
258 + if test "$MERGETOOL_TMPDIR" != "."
259 + then
260 + # If we're using a temporary directory then write to the
261 + # top-level of that directory.
262 + BASE=${BASE##*/}
263 + fi
264 +
265 + BACKUP="$MERGETOOL_TMPDIR/${BASE}_BACKUP_$$$ext"
266 + LOCAL="$MERGETOOL_TMPDIR/${BASE}_LOCAL_$$$ext"
267 + REMOTE="$MERGETOOL_TMPDIR/${BASE}_REMOTE_$$$ext"
268 + BASE="$MERGETOOL_TMPDIR/${BASE}_BASE_$$$ext"
269
270 base_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==1) print $1;}')
271 local_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}')