http: avoid disconnecting on 404s for loose objects
[gitweb.git] / git-difftool.perl
index 9a1054a2bb9d72d10aeb88c6bdf1d47b0fde1a75..ebd13baa6e06cf7007fdd5c48713f06cf511721d 100755 (executable)
@@ -47,13 +47,9 @@ sub find_worktree
 
 sub print_tool_help
 {
-       my $cmd = 'TOOL_MODE=diff';
-       $cmd .= ' && . "$(git --exec-path)/git-mergetool--lib"';
-       $cmd .= ' && show_tool_help';
-
        # See the comment at the bottom of file_diff() for the reason behind
        # using system() followed by exit() instead of exec().
-       my $rc = system('sh', '-c', $cmd);
+       my $rc = system(qw(git mergetool --tool-help=diff));
        exit($rc | ($rc >> 8));
 }
 
@@ -74,9 +70,7 @@ sub use_wt_file
        my ($repo, $workdir, $file, $sha1) = @_;
        my $null_sha1 = '0' x 40;
 
-       if (! -e "$workdir/$file") {
-               # If the file doesn't exist in the working tree, we cannot
-               # use it.
+       if (-l "$workdir/$file" || ! -e _) {
                return (0, $null_sha1);
        }
 
@@ -144,6 +138,7 @@ sub setup_dir_diff
        my %submodule;
        my %symlink;
        my @working_tree = ();
+       my %working_tree_dups = ();
        my @rawdiff = split('\0', $diffrtn);
 
        my $i = 0;
@@ -194,6 +189,10 @@ sub setup_dir_diff
                }
 
                if ($rmode ne $null_mode) {
+                       # Avoid duplicate working_tree entries
+                       if ($working_tree_dups{$dst_path}++) {
+                               next;
+                       }
                        my ($use, $wt_sha1) = use_wt_file($repo, $workdir,
                                                          $dst_path, $rsha1);
                        if ($use) {
@@ -279,7 +278,7 @@ sub setup_dir_diff
        # temporary file to both the left and right directories to show the
        # change in the recorded SHA1 for the submodule.
        for my $path (keys %submodule) {
-               my $ok;
+               my $ok = 0;
                if (defined($submodule{$path}{left})) {
                        $ok = write_to_file("$ldir/$path",
                                "Subproject commit $submodule{$path}{left}");
@@ -295,7 +294,7 @@ sub setup_dir_diff
        # shows only the link itself, not the contents of the link target.
        # This loop replicates that behavior.
        for my $path (keys %symlink) {
-               my $ok;
+               my $ok = 0;
                if (defined($symlink{$path}{left})) {
                        $ok = write_to_file("$ldir/$path",
                                        $symlink{$path}{left});