difftool: support repositories with .git-files

Modern versions of "git submodule" use .git-files to setup the submodule directory. When run in a "git submodule"-created repository "git difftool --dir-diff" dies with the following error: $ git difftool -d HEAD~ fatal: This operation must be run in a work tree diff --raw --no-abbrev -z HEAD~: command returned error: 128 core.worktree is relative to the .git directory but the logic in find_worktree() does not account for it. Use `git rev-parse --show-toplevel` to find the worktree so that the dir-diff feature works inside a submodule. Reported-by: Gábor Lipták <gabor.liptak@gmail.com> Helped-by: Jens Lehmann <jens.lehmann@web.de> Helped-by: John Keeping <john@keeping.me.uk> Signed-off-by: David Aguilar <davvid@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

David Aguilar committed Feb 23, 2014 at 19:12 UTC 94eaa806519498de2ca59a424b013812d72d21c5
1 file changed +2 -16
git-difftool.perl
+2 -16
@@ -39,24 +39,10 @@ USAGE
39
40 sub find_worktree
41 {
42 - my ($repo) = @_;
43 -
42 # Git->repository->wc_path() does not honor changes to the working
43 # tree location made by $ENV{GIT_WORK_TREE} or the 'core.worktree'
44 # config variable.
47 - my $worktree;
48 - my $env_worktree = $ENV{GIT_WORK_TREE};
49 - my $core_worktree = Git::config('core.worktree');
50 -
51 - if (defined($env_worktree) and (length($env_worktree) > 0)) {
52 - $worktree = $env_worktree;
53 - } elsif (defined($core_worktree) and (length($core_worktree) > 0)) {
54 - $worktree = $core_worktree;
55 - } else {
56 - $worktree = $repo->wc_path();
57 - }
58 -
59 - return $worktree;
45 + return Git::command_oneline('rev-parse', '--show-toplevel');
46 }
47
48 sub print_tool_help
@@ -418,7 +404,7 @@ sub dir_diff
404 my $rc;
405 my $error = 0;
406 my $repo = Git->repository();
421 - my $workdir = find_worktree($repo);
407 + my $workdir = find_worktree();
408 my ($a, $b, $tmpdir, @worktree) =
409 setup_dir_diff($repo, $workdir, $symlinks);
410