From: Junio C Hamano Date: Tue, 21 Oct 2014 20:28:42 +0000 (-0700) Subject: Merge branch 'da/mergetool-temporary-directory' X-Git-Tag: v2.2.0-rc0~28 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/a46af5946c3ec125e0c2fee889610485eb4a6e14?ds=inline;hp=-c Merge branch 'da/mergetool-temporary-directory' Allow a temporary directory specified to be used while running "git mergetool" backend. * da/mergetool-temporary-directory: t7610-mergetool: add test cases for mergetool.writeToTemp mergetool: add an option for writing to a temporary directory --- a46af5946c3ec125e0c2fee889610485eb4a6e14 diff --combined Documentation/config.txt index 04a1e2f37e,c305aff660..be6cf35c02 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@@ -381,7 -381,7 +381,7 @@@ false), while all other repositories ar core.worktree:: Set the path to the root of the working tree. This can be overridden by the GIT_WORK_TREE environment - variable and the '--work-tree' command line option. + variable and the '--work-tree' command-line option. The value can be an absolute path or relative to the path to the .git directory, which is either specified by --git-dir or GIT_DIR, or automatically discovered. @@@ -489,7 -489,7 +489,7 @@@ core.deltaBaseCacheLimit: to avoid unpacking and decompressing frequently used base objects multiple times. + -Default is 16 MiB on all platforms. This should be reasonable +Default is 96 MiB on all platforms. This should be reasonable for all users/operating systems, except on the largest projects. You probably do not need to adjust this value. + @@@ -499,8 -499,7 +499,8 @@@ core.bigFileThreshold: Files larger than this size are stored deflated, without attempting delta compression. Storing large files without delta compression avoids excessive memory usage, at the - slight expense of increased disk usage. + slight expense of increased disk usage. Additionally files + larger than this size are always treated as binary. + Default is 512 MiB on all platforms. This should be reasonable for most projects as source code and other text files can still @@@ -524,7 -523,7 +524,7 @@@ core.askpass: environment variable. If not set, fall back to the value of the 'SSH_ASKPASS' environment variable or, failing that, a simple password prompt. The external program shall be given a suitable prompt as - command line argument and write the password on its STDOUT. + command-line argument and write the password on its STDOUT. core.attributesfile:: In addition to '.gitattributes' (per-directory) and @@@ -545,9 -544,6 +545,9 @@@ core.commentchar: messages consider a line that begins with this character commented, and removes them after the editor returns (default '#'). ++ +If set to "auto", `git-commit` would select a character that is not +the beginning character of any line in existing commit messages. sequence.editor:: Text editor used by `git rebase -i` for editing the rebase instruction file. @@@ -562,19 -558,14 +562,19 @@@ core.pager: configuration, then `$PAGER`, and then the default chosen at compile time (usually 'less'). + -When the `LESS` environment variable is unset, Git sets it to `FRSX` +When the `LESS` environment variable is unset, Git sets it to `FRX` (if `LESS` environment variable is set, Git does not change it at all). If you want to selectively override Git's default setting -for `LESS`, you can set `core.pager` to e.g. `less -+S`. This will +for `LESS`, you can set `core.pager` to e.g. `less -S`. This will be passed to the shell by Git, which will translate the final -command to `LESS=FRSX less -+S`. The environment tells the command -to set the `S` option to chop long lines but the command line -resets it to the default to fold long lines. +command to `LESS=FRX less -S`. The environment does not set the +`S` option but the command line does, instructing less to truncate +long lines. Similarly, setting `core.pager` to `less -+F` will +deactivate the `F` option specified by the environment from the +command-line, deactivating the "quit if one screen" behavior of +`less`. One can specifically activate some flags for particular +commands: for example, setting `pager.blame` to `less -S` enables +line truncation only for `git blame`. + Likewise, when the `LV` environment variable is unset, Git sets it to `-c`. You can override this setting by exporting `LV` with @@@ -622,9 -613,9 +622,9 @@@ core.preloadindex: + This can speed up operations like 'git diff' and 'git status' especially on filesystems like NFS that have weak caching semantics and thus -relatively high IO latencies. With this set to 'true', Git will do the +relatively high IO latencies. When enabled, Git will do the index comparison to the filesystem data in parallel, allowing -overlapping IO's. +overlapping IO's. Defaults to true. core.createObject:: You can set this to 'link', in which case a hardlink followed by @@@ -1123,10 -1114,6 +1123,10 @@@ format.signature: Set this variable to the empty string ("") to suppress signature generation. +format.signaturefile:: + Works just like format.signature except the contents of the + file specified by this variable will be used as the signature. + format.suffix:: The default for format-patch is to output files with the suffix `.patch`. Use this variable to change that suffix (make sure to @@@ -1337,7 -1324,7 +1337,7 @@@ grep.extendedRegexp: gpg.program:: Use this custom program instead of "gpg" found on $PATH when making or verifying a PGP signature. The program must support the - same command line interface as GPG, namely, to verify a detached + same command-line interface as GPG, namely, to verify a detached signature, "gpg --verify $file - <$signature" is run, and the program is expected to signal a good signature by exiting with code 0, and to generate an ascii-armored detached signature, the @@@ -1768,6 -1755,12 +1768,12 @@@ mergetool.keepTemporaries: preserved, otherwise they will be removed after the tool has exited. Defaults to `false`. + mergetool.writeToTemp:: + Git writes temporary 'BASE', 'LOCAL', and 'REMOTE' versions of + conflicting files in the worktree by default. Git will attempt + to use a temporary directory for these files when set `true`. + Defaults to `false`. + mergetool.prompt:: Prompt before each invocation of the merge resolution program. @@@ -1906,7 -1899,12 +1912,7 @@@ pack.useBitmaps: you are debugging pack bitmaps. pack.writebitmaps:: - When true, git will write a bitmap index when packing all - objects to disk (e.g., when `git repack -a` is run). This - index can speed up the "counting objects" phase of subsequent - packs created for clones and fetches, at the cost of some disk - space and extra time spent on the initial repack. Defaults to - false. + This is a deprecated synonym for `repack.writeBitmaps`. pack.writeBitmapHashCache:: When true, git will include a "hash cache" section in the bitmap @@@ -2044,25 -2042,6 +2050,25 @@@ receive.autogc: receiving data from git-push and updating refs. You can stop it by setting this variable to false. +receive.certnonceseed:: + By setting this variable to a string, `git receive-pack` + will accept a `git push --signed` and verifies it by using + a "nonce" protected by HMAC using this string as a secret + key. + +receive.certnonceslop:: + When a `git push --signed` sent a push certificate with a + "nonce" that was issued by a receive-pack serving the same + repository within this many seconds, export the "nonce" + found in the certificate to `GIT_PUSH_CERT_NONCE` to the + hooks (instead of what the receive-pack asked the sending + side to include). This may allow writing checks in + `pre-receive` and `post-receive` a bit easier. Instead of + checking `GIT_PUSH_CERT_NONCE_SLOP` environment variable + that records by how many seconds the nonce is stale to + decide if they want to accept the certificate, they only + can check `GIT_PUSH_CERT_NONCE_STATUS` is `OK`. + receive.fsckObjects:: If it is set to true, git-receive-pack will check all received objects. It will abort in the case of a malformed object or a @@@ -2202,15 -2181,7 +2208,15 @@@ repack.packKeptObjects: `--pack-kept-objects` was passed. See linkgit:git-repack[1] for details. Defaults to `false` normally, but `true` if a bitmap index is being written (either via `--write-bitmap-index` or - `pack.writeBitmaps`). + `repack.writeBitmaps`). + +repack.writeBitmaps:: + When true, git will write a bitmap index when packing all + objects to disk (e.g., when `git repack -a` is run). This + index can speed up the "counting objects" phase of subsequent + packs created for clones and fetches, at the cost of some disk + space and extra time spent on the initial repack. Defaults to + false. rerere.autoupdate:: When set to true, `git-rerere` updates the index with the @@@ -2332,7 -2303,7 +2338,7 @@@ status.submodulesummary: exception to that rule is that status and commit will show staged submodule changes. To also view the summary for ignored submodules you can either use - the --ignore-submodules=dirty command line option or the 'git + the --ignore-submodules=dirty command-line option or the 'git submodule summary' command, which shows a similar output but does not honor these settings. @@@ -2354,7 -2325,7 +2360,7 @@@ submodule..branch: submodule..fetchRecurseSubmodules:: This option can be used to control recursive fetching of this submodule. It can be overridden by using the --[no-]recurse-submodules - command line option to "git fetch" and "git pull". + command-line option to "git fetch" and "git pull". This setting will override that from in the linkgit:gitmodules[5] file. @@@ -2374,11 -2345,6 +2380,11 @@@ submodule..ignore: "--ignore-submodules" option. The 'git submodule' commands are not affected by this setting. +tag.sort:: + This variable controls the sort ordering of tags when displayed by + linkgit:git-tag[1]. Without the "--sort=" option provided, the + value of this variable will be used as the default. + tar.umask:: This variable can be used to restrict the permission bits of tar archive entries. The default is 0002, which turns off the diff --combined git-mergetool.sh index ec644d542d,83863f2288..ff050e58ff --- a/git-mergetool.sh +++ b/git-mergetool.sh @@@ -10,11 -10,11 +10,11 @@@ USAGE='[--tool=tool] [--tool-help] [-y|--no-prompt|--prompt] [file to merge] ...' SUBDIRECTORY_OK=Yes +NONGIT_OK=Yes OPTIONS_SPEC= TOOL_MODE=merge . git-sh-setup . git-mergetool--lib -require_work_tree # Returns true if the mode reflects a symlink is_symlink () { @@@ -37,6 -37,19 +37,19 @@@ base_present () test -n "$base_mode" } + mergetool_tmpdir_init () { + if test "$(git config --bool mergetool.writeToTemp)" != true + then + MERGETOOL_TMPDIR=. + return 0 + fi + if MERGETOOL_TMPDIR=$(mktemp -d -t "git-mergetool-XXXXXX" 2>/dev/null) + then + return 0 + fi + die "error: mktemp is needed when 'mergetool.writeToTemp' is true" + } + cleanup_temp_files () { if test "$1" = --save-backup then @@@ -46,6 -59,10 +59,10 @@@ else rm -f -- "$LOCAL" "$REMOTE" "$BASE" "$BACKUP" fi + if test "$MERGETOOL_TMPDIR" != "." + then + rmdir "$MERGETOOL_TMPDIR" + fi } describe_file () { @@@ -205,7 -222,7 +222,7 @@@ checkout_staged_file () "$(git checkout-index --temp --stage="$1" "$2" 2>/dev/null)" \ : '\([^ ]*\) ') - if test $? -eq 0 -a -n "$tmpfile" + if test $? -eq 0 && test -n "$tmpfile" then mv -- "$(git rev-parse --show-cdup)$tmpfile" "$3" else @@@ -235,10 -252,20 +252,20 @@@ merge_file () BASE=$MERGED ext= fi - BACKUP="./${BASE}_BACKUP_$$$ext" - LOCAL="./${BASE}_LOCAL_$$$ext" - REMOTE="./${BASE}_REMOTE_$$$ext" - BASE="./${BASE}_BASE_$$$ext" + + mergetool_tmpdir_init + + if test "$MERGETOOL_TMPDIR" != "." + then + # If we're using a temporary directory then write to the + # top-level of that directory. + BASE=${BASE##*/} + fi + + BACKUP="$MERGETOOL_TMPDIR/${BASE}_BACKUP_$$$ext" + LOCAL="$MERGETOOL_TMPDIR/${BASE}_LOCAL_$$$ext" + REMOTE="$MERGETOOL_TMPDIR/${BASE}_REMOTE_$$$ext" + BASE="$MERGETOOL_TMPDIR/${BASE}_BASE_$$$ext" base_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==1) print $1;}') local_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}') @@@ -262,7 -289,7 +289,7 @@@ checkout_staged_file 2 "$MERGED" "$LOCAL" checkout_staged_file 3 "$MERGED" "$REMOTE" - if test -z "$local_mode" -o -z "$remote_mode" + if test -z "$local_mode" || test -z "$remote_mode" then echo "Deleted merge conflict for '$MERGED':" describe_file "$local_mode" "local" "$LOCAL" @@@ -283,7 -310,7 +310,7 @@@ echo "Normal merge conflict for '$MERGED':" describe_file "$local_mode" "local" "$LOCAL" describe_file "$remote_mode" "remote" "$REMOTE" - if "$prompt" = true + if test "$guessed_merge_tool" = true || test "$prompt" = true then printf "Hit return to start merge resolution tool (%s): " "$merge_tool" read ans || return 1 @@@ -321,16 -348,11 +348,16 @@@ return 0 } -prompt=$(git config --bool mergetool.prompt || echo true) +prompt=$(git config --bool mergetool.prompt) +guessed_merge_tool=false while test $# != 0 do case "$1" in + --tool-help=*) + TOOL_MODE=${1#--tool-help=} + show_tool_help + ;; --tool-help) show_tool_help ;; @@@ -382,19 -404,9 +409,19 @@@ prompt_after_failed_merge () done } +git_dir_init +require_work_tree + if test -z "$merge_tool" then - merge_tool=$(get_merge_tool "$merge_tool") || exit + # Check if a merge tool has been configured + merge_tool=$(get_configured_merge_tool) + # Try to guess an appropriate merge tool if no tool has been set. + if test -z "$merge_tool" + then + merge_tool=$(guess_merge_tool) || exit + guessed_merge_tool=true + fi fi merge_keep_backup="$(git config --bool mergetool.keepBackup || echo true)" merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)" diff --combined t/t7610-mergetool.sh index 3502ec9fe5,4fec633f8a..7eeb207b32 --- a/t/t7610-mergetool.sh +++ b/t/t7610-mergetool.sh @@@ -14,7 -14,7 +14,7 @@@ Testing basic merge tool invocation # running mergetool test_expect_success 'setup' ' - git config rerere.enabled true && + test_config rerere.enabled true && echo master >file1 && echo master spaced >"spaced name" && echo master file11 >file11 && @@@ -129,7 -129,7 +129,7 @@@ test_expect_success 'mergetool crlf' git submodule update -N && test "$(cat submod/bar)" = "master submodule" && git commit -m "branch1 resolved with mergetool - autocrlf" && - git config core.autocrlf false && + test_config core.autocrlf false && git reset --hard ' @@@ -176,7 -176,7 +176,7 @@@ test_expect_success 'mergetool skips au test_expect_success 'mergetool merges all from subdir' ' ( cd subdir && - git config rerere.enabled false && + test_config rerere.enabled false && test_must_fail git merge master && ( yes "r" | git mergetool ../submod ) && ( yes "d" "d" | git mergetool --no-prompt ) && @@@ -190,7 -190,7 +190,7 @@@ ' test_expect_success 'mergetool skips resolved paths when rerere is active' ' - git config rerere.enabled true && + test_config rerere.enabled true && rm -rf .git/rr-cache && git checkout -b test5 branch1 && git submodule update -N && @@@ -204,7 -204,7 +204,7 @@@ ' test_expect_success 'conflicted stash sets up rerere' ' - git config rerere.enabled true && + test_config rerere.enabled true && git checkout stash1 && echo "Conflicting stash content" >file11 && git stash && @@@ -232,7 -232,7 +232,7 @@@ test_expect_success 'mergetool takes partial path' ' git reset --hard && - git config rerere.enabled false && + test_config rerere.enabled false && git checkout -b test12 branch1 && git submodule update -N && test_must_fail git merge master && @@@ -514,4 -514,27 +514,27 @@@ test_expect_success 'custom commands ov git reset --hard master >/dev/null 2>&1 ' + test_expect_success 'filenames seen by tools start with ./' ' + git checkout -b test15 branch1 && + test_config mergetool.writeToTemp false && + test_config mergetool.myecho.cmd "echo \"\$LOCAL\"" && + test_config mergetool.myecho.trustExitCode true && + test_must_fail git merge master && + git mergetool --no-prompt --tool myecho -- both >actual && + grep ^\./both_LOCAL_ actual >/dev/null && + git reset --hard master >/dev/null 2>&1 + ' + + test_expect_success 'temporary filenames are used with mergetool.writeToTemp' ' + git checkout -b test16 branch1 && + test_config mergetool.writeToTemp true && + test_config mergetool.myecho.cmd "echo \"\$LOCAL\"" && + test_config mergetool.myecho.trustExitCode true && + test_must_fail git merge master && + git mergetool --no-prompt --tool myecho -- both >actual && + test_must_fail grep ^\./both_LOCAL_ actual >/dev/null && + grep /both_LOCAL_ actual >/dev/null && + git reset --hard master >/dev/null 2>&1 + ' + test_done