From: David Aguilar <davvid@gmail.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: Tim Henigan <tim.henigan@gmail.com>, git@vger.kernel.org
Subject: [PATCH v3 4/5] difftool: Use symlinks when diffing against the worktree
Date: Sun, 22 Jul 2012 23:05:30 -0700 [thread overview]
Message-ID: <1343023530-31463-1-git-send-email-davvid@gmail.com> (raw)
In-Reply-To: <7vzk6rnkgq.fsf@alter.siamese.dyndns.org>
Teach difftool's --dir-diff mode to use symlinks to represent
files from the working copy, and make it the default behavior
for the non-Windows platforms.
Using symlinks is simpler and safer since we do not need to
worry about copying files back into the worktree.
The old behavior is still available as --no-symlinks.
Signed-off-by: David Aguilar <davvid@gmail.com>
---
Handles the case where an editor unlinks the original symlink,
replacing it with a file.
Documentation/git-difftool.txt | 8 ++++++++
git-difftool.perl | 33 +++++++++++++++++++++++----------
2 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt
index 31fc2e3..313d54e 100644
--- a/Documentation/git-difftool.txt
+++ b/Documentation/git-difftool.txt
@@ -66,6 +66,14 @@ of the diff post-image. `$MERGED` is the name of the file which is
being compared. `$BASE` is provided for compatibility
with custom merge tool commands and has the same value as `$MERGED`.
+--symlinks::
+--no-symlinks::
+ 'git difftool''s default behavior is create symlinks to the
+ working tree when run in `--dir-diff` mode.
++
+ Specifying `--no-symlinks` instructs 'git difftool' to create
+ copies instead. `--no-symlinks` is the default on Windows.
+
--tool-help::
Print a list of diff tools that may be used with `--tool`.
diff --git a/git-difftool.perl b/git-difftool.perl
index 2ae344c..a5b371f 100755
--- a/git-difftool.perl
+++ b/git-difftool.perl
@@ -92,7 +92,7 @@ sub print_tool_help
sub setup_dir_diff
{
- my ($repo, $workdir) = @_;
+ my ($repo, $workdir, $symlinks) = @_;
# Run the diff; exit immediately if no diff found
# 'Repository' and 'WorkingCopy' must be explicitly set to insure that
@@ -209,8 +209,13 @@ sub setup_dir_diff
unless (-d "$rdir/$dir") {
mkpath("$rdir/$dir") or die $!;
}
- copy("$workdir/$file", "$rdir/$file") or die $!;
- chmod(stat("$workdir/$file")->mode, "$rdir/$file") or die $!;
+ if ($symlinks) {
+ symlink("$workdir/$file", "$rdir/$file") or die $!;
+ } else {
+ copy("$workdir/$file", "$rdir/$file") or die $!;
+ my $mode = stat("$workdir/$file")->mode;
+ chmod($mode, "$rdir/$file") or die $!;
+ }
}
# Changes to submodules require special treatment. This loop writes a
@@ -271,6 +276,7 @@ sub main
gui => undef,
help => undef,
prompt => undef,
+ symlinks => $^O ne 'MSWin32' && $^O ne 'msys',
tool_help => undef,
);
GetOptions('g|gui!' => \$opts{gui},
@@ -278,6 +284,8 @@ sub main
'h' => \$opts{help},
'prompt!' => \$opts{prompt},
'y' => sub { $opts{prompt} = 0; },
+ 'symlinks' => \$opts{symlinks},
+ 'no-symlinks' => sub { $opts{symlinks} = 0; },
't|tool:s' => \$opts{difftool_cmd},
'tool-help' => \$opts{tool_help},
'x|extcmd:s' => \$opts{extcmd});
@@ -316,7 +324,7 @@ sub main
# will invoke a separate instance of 'git-difftool--helper' for
# each file that changed.
if (defined($opts{dirdiff})) {
- dir_diff($opts{extcmd});
+ dir_diff($opts{extcmd}, $opts{symlinks});
} else {
file_diff($opts{prompt});
}
@@ -324,13 +332,13 @@ sub main
sub dir_diff
{
- my ($extcmd) = @_;
+ my ($extcmd, $symlinks) = @_;
my $rc;
my $repo = Git->repository();
my $workdir = find_worktree($repo);
- my ($a, $b, @working_tree) = setup_dir_diff($repo, $workdir);
+ my ($a, $b, @worktree) = setup_dir_diff($repo, $workdir, $symlinks);
if (defined($extcmd)) {
$rc = system($extcmd, $a, $b);
} else {
@@ -342,13 +350,18 @@ sub dir_diff
# If the diff including working copy files and those
# files were modified during the diff, then the changes
- # should be copied back to the working tree
- for my $file (@working_tree) {
- if (-e "$b/$file" && compare("$b/$file", "$workdir/$file")) {
+ # should be copied back to the working tree.
+ # Do not copy back files when symlinks are used and the
+ # external tool did not replace the original link with a file.
+ for my $file (@worktree) {
+ next if $symlinks && -l "$b/$file";
+ if (-f "$b/$file" && compare("$b/$file", "$workdir/$file")) {
copy("$b/$file", "$workdir/$file") or die $!;
- chmod(stat("$b/$file")->mode, "$workdir/$file") or die $!;
+ my $mode = stat("$b/$file")->mode;
+ chmod($mode, "$workdir/$file") or die $!;
}
}
+ exit(0);
}
sub file_diff
--
1.7.7.2.448.gee6df
next prev parent reply other threads:[~2012-07-23 6:05 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-23 3:57 [PATCH v2 0/5] difftool: Use symlinks in dir-diff mode David Aguilar
2012-07-23 3:57 ` [PATCH v2 1/5] difftool: Simplify print_tool_help() David Aguilar
2012-07-23 3:57 ` [PATCH 2/5] difftool: Eliminate global variables David Aguilar
2012-07-23 3:57 ` [PATCH 3/5] difftool: Move option values into a hash David Aguilar
2012-07-23 3:57 ` [PATCH 4/5] difftool: Call the temp directory "git-difftool" David Aguilar
2012-07-23 3:57 ` [PATCH 5/5] difftool: Use symlinks when diffing against the worktree David Aguilar
2012-07-23 4:57 ` Junio C Hamano
2012-07-23 6:05 ` David Aguilar [this message]
2012-07-23 16:38 ` [PATCH v3 4/5] " Junio C Hamano
2012-07-24 13:35 ` Tim Henigan
2012-07-24 15:57 ` Junio C Hamano
2012-07-23 5:14 ` [PATCH v2 0/5] difftool: Use symlinks in dir-diff mode Junio C Hamano
2012-07-23 5:34 ` David Aguilar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1343023530-31463-1-git-send-email-davvid@gmail.com \
--to=davvid@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=tim.henigan@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.