From: John Keeping <john@keeping.me.uk>
To: Matt McClure <matthewlmcclure@gmail.com>
Cc: Junio C Hamano <gitster@pobox.com>,
git@vger.kernel.org, Johannes Sixt <j.sixt@viscovery.net>,
David Aguilar <davvid@gmail.com>,
Sitaram Chamarty <sitaramc@gmail.com>,
Jonathan Nieder <jrnieder@gmail.com>
Subject: Re: [PATCH v2 2/3] t7800: fix tests when difftool uses --no-symlinks
Date: Sun, 24 Mar 2013 15:15:57 +0000 [thread overview]
Message-ID: <20130324151557.GB2286@serenity.lan> (raw)
In-Reply-To: <CAJELnLEhcY4Oc-EB=Mi7PKBQQF+EiVpW_dNH6G-abjZj0MAdNw@mail.gmail.com>
On Sun, Mar 24, 2013 at 09:31:45AM -0400, Matt McClure wrote:
> On Sun, Mar 24, 2013 at 8:36 AM, John Keeping <john@keeping.me.uk> wrote:
> > In the
> > non-symlink case I think a user might find it surprising if the
> > (unmodified) file used by their diff tool were suddenly copied over the
> > working tree wiping out the changes they have just made.
>
> That's exactly what I was describing here:
> http://thread.gmane.org/gmane.comp.version-control.git/217979/focus=218006
Ahh, I guess I didn't fully register the impact of that at the time and
had to rediscover the problem for myself ;-)
How about doing this (on top of jk/difftool-dir-diff-edit-fix)?
-- >8 --
Subject: [PATCH] difftool: don't overwrite modified files
After running the user's diff tool, git-difftool will copy any files
that differ between the working tree and the temporary tree. This is
useful when the user edits the file in their diff tool but is wrong if
they edit the working tree file while examining the diff.
Instead of copying unconditionally when the files differ, store the
initial hash of the working tree file and only copy the temporary file
back if it was modified and the working tree file was not. If both
files have been modified, print a warning and exit with an error.
Signed-off-by: John Keeping <john@keeping.me.uk>
---
git-difftool.perl | 35 +++++++++++++++++++++--------------
t/t7800-difftool.sh | 26 ++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 14 deletions(-)
diff --git a/git-difftool.perl b/git-difftool.perl
index c433e86..be82b5a 100755
--- a/git-difftool.perl
+++ b/git-difftool.perl
@@ -15,7 +15,6 @@ use strict;
use warnings;
use File::Basename qw(dirname);
use File::Copy;
-use File::Compare;
use File::Find;
use File::stat;
use File::Path qw(mkpath rmtree);
@@ -123,7 +122,7 @@ sub setup_dir_diff
my $rindex = '';
my %submodule;
my %symlink;
- my @working_tree = ();
+ my %working_tree;
my @rawdiff = split('\0', $diffrtn);
my $i = 0;
@@ -175,7 +174,9 @@ EOF
if ($rmode ne $null_mode) {
if (use_wt_file($repo, $workdir, $dst_path, $rsha1, $symlinks)) {
- push(@working_tree, $dst_path);
+ $working_tree{$dst_path} =
+ $repo->command_oneline('hash-object',
+ "$workdir/$dst_path");
} else {
$rindex .= "$rmode $rsha1\t$dst_path\0";
}
@@ -227,7 +228,7 @@ EOF
# not part of the index. Remove any trailing slash from $workdir
# before starting to avoid double slashes in symlink targets.
$workdir =~ s|/$||;
- for my $file (@working_tree) {
+ for my $file (keys %working_tree) {
my $dir = dirname($file);
unless (-d "$rdir/$dir") {
mkpath("$rdir/$dir") or
@@ -278,7 +279,7 @@ EOF
exit_cleanup($tmpdir, 1) if not $ok;
}
- return ($ldir, $rdir, $tmpdir, @working_tree);
+ return ($ldir, $rdir, $tmpdir, %working_tree);
}
sub write_to_file
@@ -376,7 +377,7 @@ sub dir_diff
my $error = 0;
my $repo = Git->repository();
my $workdir = find_worktree($repo);
- my ($a, $b, $tmpdir, @worktree) =
+ my ($a, $b, $tmpdir, %worktree) =
setup_dir_diff($repo, $workdir, $symlinks);
if (defined($extcmd)) {
@@ -390,19 +391,25 @@ sub dir_diff
# 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) {
+ for my $file (keys %worktree) {
next if $symlinks && -l "$b/$file";
next if ! -f "$b/$file";
- my $diff = compare("$b/$file", "$workdir/$file");
- if ($diff == 0) {
- next;
- } elsif ($diff == -1) {
- my $errmsg = "warning: Could not compare ";
- $errmsg += "'$b/$file' with '$workdir/$file'\n";
+ my $wt_hash = $repo->command_oneline('hash-object',
+ "$workdir/$file");
+ my $tmp_hash = $repo->command_oneline('hash-object',
+ "$b/$file");
+ my $wt_modified = $wt_hash ne $worktree{$file};
+ my $tmp_modified = $tmp_hash ne $worktree{$file};
+
+ if ($wt_modified and $tmp_modified) {
+ my $errmsg = "warning: Both files modified: ";
+ $errmsg .= "'$workdir/$file' and '$b/$file'.\n";
+ $errmsg .= "warning: Working tree file has been left.\n";
+ $errmsg .= "warning:\n";
warn $errmsg;
$error = 1;
- } elsif ($diff == 1) {
+ } elsif ($tmp_modified) {
my $mode = stat("$b/$file")->mode;
copy("$b/$file", "$workdir/$file") or
exit_cleanup($tmpdir, 1);
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index db3d3d6..be2042d 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -407,4 +407,30 @@ test_expect_success PERL 'difftool --dir-diff from subdirectory' '
)
'
+write_script modify-file <<\EOF
+echo "new content" >file
+EOF
+
+test_expect_success PERL 'difftool --no-symlinks does not overwrite working tree file ' '
+ echo "orig content" >file &&
+ git difftool --dir-diff --no-symlinks --extcmd "$(pwd)/modify-file" branch &&
+ echo "new content" >expect &&
+ test_cmp expect file
+'
+
+write_script modify-both-files <<\EOF
+echo "wt content" >file &&
+echo "tmp content" >"$2/file" &&
+echo "$2" >tmpdir
+EOF
+
+test_expect_success PERL 'difftool --no-symlinks detects conflict ' '
+ echo "orig content" >file &&
+ test_must_fail git difftool --dir-diff --no-symlinks --extcmd "$(pwd)/modify-both-files" branch &&
+ echo "wt content" >expect &&
+ test_cmp expect file &&
+ echo "tmp content" >expect &&
+ test_cmp expect "$(cat tmpdir)/file"
+'
+
test_done
--
1.8.2.411.g65a544e
next prev parent reply other threads:[~2013-03-24 15:16 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-21 4:03 [PATCH v3 1/4] difftool: silence uninitialized variable warning David Aguilar
2013-02-21 4:03 ` [PATCH 2/4] t7800: update copyright notice David Aguilar
2013-02-21 4:03 ` [PATCH v3 3/4] t7800: modernize tests David Aguilar
2013-02-21 4:03 ` [PATCH v3 4/4] t7800: "defaults" is no longer a builtin tool name David Aguilar
2013-02-21 4:55 ` Junio C Hamano
2013-02-21 5:00 ` Junio C Hamano
2013-02-21 23:31 ` David Aguilar
2013-03-20 9:48 ` [PATCH v3 3/4] t7800: modernize tests Johannes Sixt
2013-03-20 22:59 ` David Aguilar
2013-03-21 7:41 ` Johannes Sixt
2013-03-22 7:13 ` Johannes Sixt
2013-03-22 10:00 ` John Keeping
2013-03-22 11:14 ` Johannes Sixt
2013-03-22 11:53 ` John Keeping
2013-03-22 19:36 ` [PATCH 0/3] Improve difftool --dir-diff tests John Keeping
2013-03-22 19:36 ` [PATCH 1/3] t7800: don't hide grep output John Keeping
2013-03-22 22:32 ` Johannes Sixt
2013-03-22 22:45 ` Junio C Hamano
2013-03-22 19:36 ` [PATCH 2/3] t7800: fix tests when difftool uses --no-symlinks John Keeping
2013-03-22 22:27 ` Johannes Sixt
2013-03-22 22:53 ` Junio C Hamano
2013-03-22 23:05 ` John Keeping
2013-03-23 3:24 ` David Aguilar
2013-03-22 19:36 ` [PATCH 3/3] t7800: run --dir-diff tests with and without symlinks John Keeping
2013-03-22 21:05 ` [PATCH 3/3 v2] " John Keeping
2013-03-23 13:31 ` [PATCH v2 0/3] difftool --dir-diff test improvements John Keeping
2013-03-23 13:31 ` [PATCH v2 1/3] t7800: don't hide grep output John Keeping
2013-03-23 13:31 ` [PATCH v2 2/3] t7800: fix tests when difftool uses --no-symlinks John Keeping
2013-03-24 5:19 ` Junio C Hamano
2013-03-24 12:36 ` John Keeping
2013-03-24 13:31 ` Matt McClure
2013-03-24 15:15 ` John Keeping [this message]
2013-03-25 7:41 ` Johannes Sixt
2013-03-25 10:42 ` John Keeping
2013-03-25 21:44 ` [PATCH v2] difftool: don't overwrite modified files John Keeping
2013-03-26 8:38 ` Johannes Sixt
2013-03-26 8:47 ` Johannes Sixt
2013-03-26 9:31 ` John Keeping
2013-03-26 9:53 ` Johannes Sixt
2013-03-26 19:34 ` John Keeping
2013-03-26 20:52 ` Matt McClure
2013-03-26 21:01 ` John Keeping
2013-03-25 16:15 ` [PATCH v2 2/3] t7800: fix tests when difftool uses --no-symlinks Junio C Hamano
2013-03-24 21:29 ` David Aguilar
2013-03-25 10:57 ` John Keeping
2013-03-25 14:54 ` Junio C Hamano
2013-03-24 13:24 ` Matt McClure
2013-03-24 6:20 ` Eric Sunshine
2013-03-23 13:31 ` [PATCH v2 3/3] t7800: run --dir-diff tests with and without symlinks John Keeping
2013-03-25 7:26 ` Johannes Sixt
2013-03-25 10:35 ` John Keeping
2013-03-25 10:59 ` Johannes Sixt
2013-03-25 11:02 ` John Keeping
2013-03-25 21:50 ` Junio C Hamano
2013-03-26 9:22 ` John Keeping
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=20130324151557.GB2286@serenity.lan \
--to=john@keeping.me.uk \
--cc=davvid@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=j.sixt@viscovery.net \
--cc=jrnieder@gmail.com \
--cc=matthewlmcclure@gmail.com \
--cc=sitaramc@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).