git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 2/2] difftool: allow running outside Git worktrees with --no-index

From
Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com>
Date
Mar 13, 2019, 19:20 UTC
Message-ID
<9f6eb60eeeccf920af83652899c5bc2d40e2092f.1552504812.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.163.git.gitgitgadget@gmail.com>
From: Johannes Schindelin <johannes.schindelin@gmx.de>

As far as this developer can tell, the conversion from a Perl script to a built-in caused the regression in the difftool that it no longer runs outside of a Git worktree (with `--no-index`, of course).

It is a bit embarrassing that it took over two years after retiring the Perl version to discover this regression, but at least we now know, and can do something, about it.

This fixes https://github.com/git-for-windows/git/issues/2123
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/difftool.c  | 20 +++++++++++++++++---
 git.c               |  2 +-
 t/t7800-difftool.sh | 10 ++++++++++
 3 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/builtin/difftool.c b/builtin/difftool.c
index 31eece0c8d..d08ef31f04 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -690,7 +690,7 @@ static int run_file_diff(int prompt, const char *prefix,
 int cmd_difftool(int argc, const char **argv, const char *prefix)
 {
 	int use_gui_tool = 0, dir_diff = 0, prompt = -1, symlinks = 0,
-	    tool_help = 0;
+	    tool_help = 0, i, no_index = 0;
 	static char *difftool_cmd = NULL, *extcmd = NULL;
 	struct option builtin_difftool_options[] = {
 		OPT_BOOL('g', "gui", &use_gui_tool,
@@ -727,8 +727,22 @@ int cmd_difftool(int argc, const char **argv, const char *prefix)
 	if (tool_help)
 		return print_tool_help();
 
-	setenv(GIT_DIR_ENVIRONMENT, absolute_path(get_git_dir()), 1);
-	setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(get_git_work_tree()), 1);
+	for (i = 0; i < argc; i++)
+		if (!strcmp(argv[i], "--"))
+			break;
+		else if (!strcmp(argv[i], "--no-index")) {
+			no_index = 1;
+			break;
+		}
+
+	if (!no_index && !startup_info->have_repository)
+		die(_("difftool requires worktree or --no-index"));
+
+	if (!no_index){
+		setup_work_tree();
+		setenv(GIT_DIR_ENVIRONMENT, absolute_path(get_git_dir()), 1);
+		setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(get_git_work_tree()), 1);
+	}
 
 	if (use_gui_tool && diff_gui_tool && *diff_gui_tool)
 		setenv("GIT_DIFF_TOOL", diff_gui_tool, 1);
diff --git a/git.c b/git.c
index 2014aab6b8..46365ed86a 100644
--- a/git.c
+++ b/git.c
@@ -491,7 +491,7 @@ static struct cmd_struct commands[] = {
 	{ "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
 	{ "diff-index", cmd_diff_index, RUN_SETUP | NO_PARSEOPT },
 	{ "diff-tree", cmd_diff_tree, RUN_SETUP | NO_PARSEOPT },
-	{ "difftool", cmd_difftool, RUN_SETUP | NEED_WORK_TREE },
+	{ "difftool", cmd_difftool, RUN_SETUP_GENTLY },
 	{ "fast-export", cmd_fast_export, RUN_SETUP },
 	{ "fetch", cmd_fetch, RUN_SETUP },
 	{ "fetch-pack", cmd_fetch_pack, RUN_SETUP | NO_PARSEOPT },
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index bb9a7f4ff9..4907627656 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -705,4 +705,14 @@ test_expect_success SYMLINKS 'difftool --dir-diff handles modified symlinks' '
 	test_cmp expect actual
 '
 
+test_expect_success 'outside worktree' '
+	mkdir outside &&
+	echo 1 >outside/1 &&
+	echo 2 >outside/2 &&
+	test_expect_code 1 env GIT_CEILING_DIRECTORIES="$(pwd)" git \
+		-c diff.tool=echo -c difftool.echo.cmd="echo \$LOCAL \$REMOTE" \
+		-C outside difftool --no-prompt --no-index 1 2 >out &&
+	test "1 2" = "$(cat out)"
+'
+
 test_done
-- 
gitgitgadget
Previous: Johannes Schindelin via GitGitGadgetNext: Jeff King
Message 2 of 17 in “Allow difftool to be run outside of Git worktrees”
  1. 0/2 Allow difftool to be run outside of Git worktreesJohannes Schindelin via GitGitGadget, Mar 13, 2019
  2. 2/2 difftool: allow running outside Git worktrees with --no-indexJohannes Schindelin via GitGitGadget, Mar 13, 2019
  3. Jeff KingMar 13, 2019
  4. Johannes SchindelinMar 14, 2019
  5. Jeff KingMar 15, 2019
  6. 1/2 difftool: remove obsolete (and misleading) commentJohannes Schindelin via GitGitGadget, Mar 13, 2019
  7. 0/3 Allow difftool to be run outside of Git worktreesJohannes Schindelin via GitGitGadget, Mar 14, 2019
  8. 1/3 difftool: remove obsolete (and misleading) commentJohannes Schindelin via GitGitGadget, Mar 14, 2019
  9. 2/3 parse-options: make OPT_ARGUMENT() more usefulJohannes Schindelin via GitGitGadget, Mar 14, 2019
  10. Jeff KingMar 15, 2019
  11. Johannes SchindelinMar 15, 2019
  12. Junio C HamanoMar 18, 2019
  13. Jeff KingMar 18, 2019
  14. Junio C HamanoMar 19, 2019
  15. 3/3 difftool: allow running outside Git worktrees with --no-indexJohannes Schindelin via GitGitGadget, Mar 14, 2019
  16. Jeff KingMar 15, 2019
  17. Johannes SchindelinMar 15, 2019

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.