Merge branch 'jk/difftool-in-subdir'
Even though an fix was attempted in Git 2.9.3 days, but running "git difftool --dir-diff" from a subdirectory never worked. This has been fixed. * jk/difftool-in-subdir: difftool: rename variables for consistency difftool: chdir as early as possible difftool: sanitize $workdir as early as possible difftool: fix dir-diff index creation when in a subdirectory
This commit is contained in:
commit
5a5d3f1f12
@ -60,14 +60,14 @@ sub exit_cleanup
|
|||||||
|
|
||||||
sub use_wt_file
|
sub use_wt_file
|
||||||
{
|
{
|
||||||
my ($workdir, $file, $sha1) = @_;
|
my ($file, $sha1) = @_;
|
||||||
my $null_sha1 = '0' x 40;
|
my $null_sha1 = '0' x 40;
|
||||||
|
|
||||||
if (-l "$workdir/$file" || ! -e _) {
|
if (-l $file || ! -e _) {
|
||||||
return (0, $null_sha1);
|
return (0, $null_sha1);
|
||||||
}
|
}
|
||||||
|
|
||||||
my $wt_sha1 = Git::command_oneline('hash-object', "$workdir/$file");
|
my $wt_sha1 = Git::command_oneline('hash-object', $file);
|
||||||
my $use = ($sha1 eq $null_sha1) || ($sha1 eq $wt_sha1);
|
my $use = ($sha1 eq $null_sha1) || ($sha1 eq $wt_sha1);
|
||||||
return ($use, $wt_sha1);
|
return ($use, $wt_sha1);
|
||||||
}
|
}
|
||||||
@ -101,11 +101,17 @@ sub changed_files
|
|||||||
|
|
||||||
sub setup_dir_diff
|
sub setup_dir_diff
|
||||||
{
|
{
|
||||||
my ($workdir, $symlinks) = @_;
|
my ($worktree, $symlinks) = @_;
|
||||||
my @gitargs = ('diff', '--raw', '--no-abbrev', '-z', @ARGV);
|
my @gitargs = ('diff', '--raw', '--no-abbrev', '-z', @ARGV);
|
||||||
my $diffrtn = Git::command_oneline(@gitargs);
|
my $diffrtn = Git::command_oneline(@gitargs);
|
||||||
exit(0) unless defined($diffrtn);
|
exit(0) unless defined($diffrtn);
|
||||||
|
|
||||||
|
# Go to the root of the worktree now that we've captured the list of
|
||||||
|
# changed files. The paths returned by diff --raw are relative to the
|
||||||
|
# top-level of the repository, but we defer changing directories so
|
||||||
|
# that @ARGV can perform pathspec limiting in the current directory.
|
||||||
|
chdir($worktree);
|
||||||
|
|
||||||
# Build index info for left and right sides of the diff
|
# Build index info for left and right sides of the diff
|
||||||
my $submodule_mode = '160000';
|
my $submodule_mode = '160000';
|
||||||
my $symlink_mode = '120000';
|
my $symlink_mode = '120000';
|
||||||
@ -116,7 +122,7 @@ sub setup_dir_diff
|
|||||||
my $wtindex = '';
|
my $wtindex = '';
|
||||||
my %submodule;
|
my %submodule;
|
||||||
my %symlink;
|
my %symlink;
|
||||||
my @working_tree = ();
|
my @files = ();
|
||||||
my %working_tree_dups = ();
|
my %working_tree_dups = ();
|
||||||
my @rawdiff = split('\0', $diffrtn);
|
my @rawdiff = split('\0', $diffrtn);
|
||||||
|
|
||||||
@ -168,14 +174,14 @@ EOF
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($rmode ne $null_mode) {
|
if ($rmode ne $null_mode) {
|
||||||
# Avoid duplicate working_tree entries
|
# Avoid duplicate entries
|
||||||
if ($working_tree_dups{$dst_path}++) {
|
if ($working_tree_dups{$dst_path}++) {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
my ($use, $wt_sha1) =
|
my ($use, $wt_sha1) =
|
||||||
use_wt_file($workdir, $dst_path, $rsha1);
|
use_wt_file($dst_path, $rsha1);
|
||||||
if ($use) {
|
if ($use) {
|
||||||
push @working_tree, $dst_path;
|
push @files, $dst_path;
|
||||||
$wtindex .= "$rmode $wt_sha1\t$dst_path\0";
|
$wtindex .= "$rmode $wt_sha1\t$dst_path\0";
|
||||||
} else {
|
} else {
|
||||||
$rindex .= "$rmode $rsha1\t$dst_path\0";
|
$rindex .= "$rmode $rsha1\t$dst_path\0";
|
||||||
@ -185,7 +191,7 @@ EOF
|
|||||||
|
|
||||||
# Go to the root of the worktree so that the left index files
|
# Go to the root of the worktree so that the left index files
|
||||||
# are properly setup -- the index is toplevel-relative.
|
# are properly setup -- the index is toplevel-relative.
|
||||||
chdir($workdir);
|
chdir($worktree);
|
||||||
|
|
||||||
# Setup temp directories
|
# Setup temp directories
|
||||||
my $tmpdir = tempdir('git-difftool.XXXXX', CLEANUP => 0, TMPDIR => 1);
|
my $tmpdir = tempdir('git-difftool.XXXXX', CLEANUP => 0, TMPDIR => 1);
|
||||||
@ -225,23 +231,21 @@ EOF
|
|||||||
delete($ENV{GIT_INDEX_FILE});
|
delete($ENV{GIT_INDEX_FILE});
|
||||||
|
|
||||||
# Changes in the working tree need special treatment since they are
|
# Changes in the working tree need special treatment since they are
|
||||||
# not part of the index. Remove any trailing slash from $workdir
|
# not part of the index.
|
||||||
# before starting to avoid double slashes in symlink targets.
|
for my $file (@files) {
|
||||||
$workdir =~ s|/$||;
|
|
||||||
for my $file (@working_tree) {
|
|
||||||
my $dir = dirname($file);
|
my $dir = dirname($file);
|
||||||
unless (-d "$rdir/$dir") {
|
unless (-d "$rdir/$dir") {
|
||||||
mkpath("$rdir/$dir") or
|
mkpath("$rdir/$dir") or
|
||||||
exit_cleanup($tmpdir, 1);
|
exit_cleanup($tmpdir, 1);
|
||||||
}
|
}
|
||||||
if ($symlinks) {
|
if ($symlinks) {
|
||||||
symlink("$workdir/$file", "$rdir/$file") or
|
symlink("$worktree/$file", "$rdir/$file") or
|
||||||
exit_cleanup($tmpdir, 1);
|
exit_cleanup($tmpdir, 1);
|
||||||
} else {
|
} else {
|
||||||
copy("$workdir/$file", "$rdir/$file") or
|
copy($file, "$rdir/$file") or
|
||||||
exit_cleanup($tmpdir, 1);
|
exit_cleanup($tmpdir, 1);
|
||||||
|
|
||||||
my $mode = stat("$workdir/$file")->mode;
|
my $mode = stat($file)->mode;
|
||||||
chmod($mode, "$rdir/$file") or
|
chmod($mode, "$rdir/$file") or
|
||||||
exit_cleanup($tmpdir, 1);
|
exit_cleanup($tmpdir, 1);
|
||||||
}
|
}
|
||||||
@ -279,7 +283,7 @@ EOF
|
|||||||
exit_cleanup($tmpdir, 1) if not $ok;
|
exit_cleanup($tmpdir, 1) if not $ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ($ldir, $rdir, $tmpdir, @working_tree);
|
return ($ldir, $rdir, $tmpdir, @files);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub write_to_file
|
sub write_to_file
|
||||||
@ -389,8 +393,9 @@ sub dir_diff
|
|||||||
my $error = 0;
|
my $error = 0;
|
||||||
my $repo = Git->repository();
|
my $repo = Git->repository();
|
||||||
my $repo_path = $repo->repo_path();
|
my $repo_path = $repo->repo_path();
|
||||||
my $workdir = $repo->wc_path();
|
my $worktree = $repo->wc_path();
|
||||||
my ($a, $b, $tmpdir, @worktree) = setup_dir_diff($workdir, $symlinks);
|
$worktree =~ s|/$||; # Avoid double slashes in symlink targets
|
||||||
|
my ($a, $b, $tmpdir, @files) = setup_dir_diff($worktree, $symlinks);
|
||||||
|
|
||||||
if (defined($extcmd)) {
|
if (defined($extcmd)) {
|
||||||
$rc = system($extcmd, $a, $b);
|
$rc = system($extcmd, $a, $b);
|
||||||
@ -411,13 +416,13 @@ sub dir_diff
|
|||||||
my %tmp_modified;
|
my %tmp_modified;
|
||||||
my $indices_loaded = 0;
|
my $indices_loaded = 0;
|
||||||
|
|
||||||
for my $file (@worktree) {
|
for my $file (@files) {
|
||||||
next if $symlinks && -l "$b/$file";
|
next if $symlinks && -l "$b/$file";
|
||||||
next if ! -f "$b/$file";
|
next if ! -f "$b/$file";
|
||||||
|
|
||||||
if (!$indices_loaded) {
|
if (!$indices_loaded) {
|
||||||
%wt_modified = changed_files(
|
%wt_modified = changed_files(
|
||||||
$repo_path, "$tmpdir/wtindex", $workdir);
|
$repo_path, "$tmpdir/wtindex", $worktree);
|
||||||
%tmp_modified = changed_files(
|
%tmp_modified = changed_files(
|
||||||
$repo_path, "$tmpdir/wtindex", $b);
|
$repo_path, "$tmpdir/wtindex", $b);
|
||||||
$indices_loaded = 1;
|
$indices_loaded = 1;
|
||||||
@ -428,14 +433,14 @@ sub dir_diff
|
|||||||
"warning: Both files modified:\n" .
|
"warning: Both files modified:\n" .
|
||||||
"'%s/%s' and '%s/%s'.\n" .
|
"'%s/%s' and '%s/%s'.\n" .
|
||||||
"warning: Working tree file has been left.\n" .
|
"warning: Working tree file has been left.\n" .
|
||||||
"warning:\n"), $workdir, $file, $b, $file);
|
"warning:\n"), $worktree, $file, $b, $file);
|
||||||
$error = 1;
|
$error = 1;
|
||||||
} elsif (exists $tmp_modified{$file}) {
|
} elsif (exists $tmp_modified{$file}) {
|
||||||
my $mode = stat("$b/$file")->mode;
|
my $mode = stat("$b/$file")->mode;
|
||||||
copy("$b/$file", "$workdir/$file") or
|
copy("$b/$file", $file) or
|
||||||
exit_cleanup($tmpdir, 1);
|
exit_cleanup($tmpdir, 1);
|
||||||
|
|
||||||
chmod($mode, "$workdir/$file") or
|
chmod($mode, $file) or
|
||||||
exit_cleanup($tmpdir, 1);
|
exit_cleanup($tmpdir, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user