Skip to content

Commit

Permalink
add--interactive: ignore unmerged entries in patch mode
Browse files Browse the repository at this point in the history
When "add -p" sees an unmerged entry, it shows the combined
diff and then immediately skips the hunk. This can be
confusing in a variety of ways, depending on whether there
are other changes to stage (in which case you get the
superfluous combined diff output in between other hunks) or
not (in which case you get the combined diff and the program
exits immediately, rather than seeing "No changes").

The current behavior was not planned, and is just what the
implementation happens to do. Instead, let's explicitly
remove unmerged entries from our list of modified files, and
print a warning that we are ignoring them.

We can cheaply find which entries are unmerged by adding
"--raw" output to the "diff-files --numstat" we already run.
There is one non-obvious thing we must change when parsing
this combined output. Before this patch, when we saw a
numstat line for a file that did not have index changes, we
would create a new record with 'unchanged' in the 'INDEX'
field.  Because "--raw" comes before "--numstat", we must
move this special-case down to the raw-line case (and it is
sufficient to move it rather than handle it in both places,
since any file which has a --numstat will also have a --raw
entry).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jeff King authored and Junio C Hamano committed Apr 5, 2012
1 parent 4961210 commit 4066bd6
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 7 deletions.
25 changes: 18 additions & 7 deletions git-add--interactive.perl
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ sub get_empty_tree {
# FILE: is file different from index?
# INDEX_ADDDEL: is it add/delete between HEAD and index?
# FILE_ADDDEL: is it add/delete between index and file?
# UNMERGED: is the path unmerged

sub list_modified {
my ($only) = @_;
Expand Down Expand Up @@ -318,16 +319,10 @@ sub list_modified {
}
}

for (run_cmd_pipe(qw(git diff-files --numstat --summary --), @tracked)) {
for (run_cmd_pipe(qw(git diff-files --numstat --summary --raw --), @tracked)) {
if (($add, $del, $file) =
/^([-\d]+) ([-\d]+) (.*)/) {
$file = unquote_path($file);
if (!exists $data{$file}) {
$data{$file} = +{
INDEX => 'unchanged',
BINARY => 0,
};
}
my ($change, $bin);
if ($add eq '-' && $del eq '-') {
$change = 'binary';
Expand All @@ -346,6 +341,18 @@ sub list_modified {
$file = unquote_path($file);
$data{$file}{FILE_ADDDEL} = $adddel;
}
elsif (/^:[0-7]+ [0-7]+ [0-9a-f]+ [0-9a-f]+ (.) (.*)$/) {
$file = unquote_path($2);
if (!exists $data{$file}) {
$data{$file} = +{
INDEX => 'unchanged',
BINARY => 0,
};
}
if ($1 eq 'U') {
$data{$file}{UNMERGED} = 1;
}
}
}

for (sort keys %data) {
Expand Down Expand Up @@ -1190,6 +1197,10 @@ sub apply_patch_for_checkout_commit {

sub patch_update_cmd {
my @all_mods = list_modified($patch_mode_flavour{FILTER});
error_msg "ignoring unmerged: $_->{VALUE}\n"
for grep { $_->{UNMERGED} } @all_mods;
@all_mods = grep { !$_->{UNMERGED} } @all_mods;

my @mods = grep { !($_->{BINARY}) } @all_mods;
my @them;

Expand Down
26 changes: 26 additions & 0 deletions t/t3701-add-interactive.sh
Original file line number Diff line number Diff line change
Expand Up @@ -330,4 +330,30 @@ test_expect_success PERL 'split hunk "add -p (edit)"' '
! grep "^+15" actual
'

test_expect_success 'patch mode ignores unmerged entries' '
git reset --hard &&
test_commit conflict &&
test_commit non-conflict &&
git checkout -b side &&
test_commit side conflict.t &&
git checkout master &&
test_commit master conflict.t &&
test_must_fail git merge side &&
echo changed >non-conflict.t &&
echo y | git add -p >output &&
! grep a/conflict.t output &&
cat >expected <<-\EOF &&
* Unmerged path conflict.t
diff --git a/non-conflict.t b/non-conflict.t
index f766221..5ea2ed4 100644
--- a/non-conflict.t
+++ b/non-conflict.t
@@ -1 +1 @@
-non-conflict
+changed
EOF
git diff --cached >diff &&
test_cmp expected diff
'

test_done

0 comments on commit 4066bd6

Please sign in to comment.