Naturally, prep_temp_blob() did not care about filenames. As a result, scripts that used GIT_EXTERNAL_DIFF or textconv ended up with filenames such as ".diff_XXXXXX". This modifies prep_temp_blob() to generate user-friendly filenames when creating temporary files. Diffing "name.ext" now generates "XXXXXX_name.ext". Signed-off-by: David Aguilar <davvid@xxxxxxxxx> Tested-by: Johannes Sixt <j6t@xxxxxxxx> (Windows) --- This includes Peff's suggestion to make this the default behavior. Peff mentioned that: "Switching to user-friendly temp filenames for textconv was on my todo list". This patch accomplishes exactly that for both textconv and GIT_EXTERNAL_DIFF. cache.h | 2 ++ diff.c | 19 ++++++++++++++++++- path.c | 16 ++++++++++++++++ t/t4020-diff-external.sh | 9 +++++++++ 4 files changed, 45 insertions(+), 1 deletions(-) diff --git a/cache.h b/cache.h index b8503ad..871c984 100644 --- a/cache.h +++ b/cache.h @@ -614,6 +614,8 @@ extern int is_empty_blob_sha1(const unsigned char *sha1); int git_mkstemp(char *path, size_t n, const char *template); +int git_mkstemps(char *path, size_t n, const char *template, int suffix_len); + /* * NOTE NOTE NOTE!! * diff --git a/diff.c b/diff.c index dcfbcb0..85503ce 100644 --- a/diff.c +++ b/diff.c @@ -1964,8 +1964,24 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp, { int fd; struct strbuf buf = STRBUF_INIT; + struct strbuf template = STRBUF_INIT; + char *basename = ((char*)path) + strlen(path) - 1; + + /* Windows lacks basename() */ + while(*basename && basename > path) { + basename--; + if (is_dir_sep(*basename)) { + basename++; + break; + } + } + + /* Generate "XXXXXX_basename.ext" */ + strbuf_addstr(&template, "XXXXXX_"); + strbuf_addstr(&template, basename); - fd = git_mkstemp(temp->tmp_path, PATH_MAX, ".diff_XXXXXX"); + fd = git_mkstemps(temp->tmp_path, PATH_MAX, template.buf, + strlen(basename) + 1); if (fd < 0) die("unable to create temp-file: %s", strerror(errno)); if (convert_to_working_tree(path, @@ -1981,6 +1997,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp, temp->hex[40] = 0; sprintf(temp->mode, "%06o", mode); strbuf_release(&buf); + strbuf_release(&template); } static struct diff_tempfile *prepare_temp_file(const char *name, diff --git a/path.c b/path.c index 8a0a674..047fdb0 100644 --- a/path.c +++ b/path.c @@ -139,6 +139,22 @@ int git_mkstemp(char *path, size_t len, const char *template) return mkstemp(path); } +/* git_mkstemps() - create tmp file with suffix honoring TMPDIR variable. */ +int git_mkstemps(char *path, size_t len, const char *template, int suffix_len) +{ + const char *tmp; + size_t n; + + tmp = getenv("TMPDIR"); + if (!tmp) + tmp = "/tmp"; + n = snprintf(path, len, "%s/%s", tmp, template); + if (len <= n) { + errno = ENAMETOOLONG; + return -1; + } + return mkstemps(path, suffix_len); +} int validate_headref(const char *path) { diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh index 0720001..4ea42e0 100755 --- a/t/t4020-diff-external.sh +++ b/t/t4020-diff-external.sh @@ -136,6 +136,15 @@ test_expect_success 'GIT_EXTERNAL_DIFF with more than one changed files' ' GIT_EXTERNAL_DIFF=echo git diff ' +test_expect_success 'GIT_EXTERNAL_DIFF generates pretty paths' ' + touch file.ext && + git add file.ext && + echo with extension > file.ext && + GIT_EXTERNAL_DIFF=echo git diff file.ext | grep ......_file\.ext && + git update-index --force-remove file.ext && + rm file.ext +' + echo "#!$SHELL_PATH" >fake-diff.sh cat >> fake-diff.sh <<\EOF cat $2 >> crlfed.txt -- 1.6.1.3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html