Skip to content

Commit 4066bd6

Browse files
peffgitster
authored andcommitted
add--interactive: ignore unmerged entries in patch mode
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4961210 commit 4066bd6

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

git-add--interactive.perl

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ sub get_empty_tree {
268268
# FILE: is file different from index?
269269
# INDEX_ADDDEL: is it add/delete between HEAD and index?
270270
# FILE_ADDDEL: is it add/delete between index and file?
271+
# UNMERGED: is the path unmerged
271272

272273
sub list_modified {
273274
my ($only) = @_;
@@ -318,16 +319,10 @@ sub list_modified {
318319
}
319320
}
320321

321-
for (run_cmd_pipe(qw(git diff-files --numstat --summary --), @tracked)) {
322+
for (run_cmd_pipe(qw(git diff-files --numstat --summary --raw --), @tracked)) {
322323
if (($add, $del, $file) =
323324
/^([-\d]+) ([-\d]+) (.*)/) {
324325
$file = unquote_path($file);
325-
if (!exists $data{$file}) {
326-
$data{$file} = +{
327-
INDEX => 'unchanged',
328-
BINARY => 0,
329-
};
330-
}
331326
my ($change, $bin);
332327
if ($add eq '-' && $del eq '-') {
333328
$change = 'binary';
@@ -346,6 +341,18 @@ sub list_modified {
346341
$file = unquote_path($file);
347342
$data{$file}{FILE_ADDDEL} = $adddel;
348343
}
344+
elsif (/^:[0-7]+ [0-7]+ [0-9a-f]+ [0-9a-f]+ (.) (.*)$/) {
345+
$file = unquote_path($2);
346+
if (!exists $data{$file}) {
347+
$data{$file} = +{
348+
INDEX => 'unchanged',
349+
BINARY => 0,
350+
};
351+
}
352+
if ($1 eq 'U') {
353+
$data{$file}{UNMERGED} = 1;
354+
}
355+
}
349356
}
350357

351358
for (sort keys %data) {
@@ -1190,6 +1197,10 @@ sub apply_patch_for_checkout_commit {
11901197

11911198
sub patch_update_cmd {
11921199
my @all_mods = list_modified($patch_mode_flavour{FILTER});
1200+
error_msg "ignoring unmerged: $_->{VALUE}\n"
1201+
for grep { $_->{UNMERGED} } @all_mods;
1202+
@all_mods = grep { !$_->{UNMERGED} } @all_mods;
1203+
11931204
my @mods = grep { !($_->{BINARY}) } @all_mods;
11941205
my @them;
11951206

t/t3701-add-interactive.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,4 +330,30 @@ test_expect_success PERL 'split hunk "add -p (edit)"' '
330330
! grep "^+15" actual
331331
'
332332

333+
test_expect_success 'patch mode ignores unmerged entries' '
334+
git reset --hard &&
335+
test_commit conflict &&
336+
test_commit non-conflict &&
337+
git checkout -b side &&
338+
test_commit side conflict.t &&
339+
git checkout master &&
340+
test_commit master conflict.t &&
341+
test_must_fail git merge side &&
342+
echo changed >non-conflict.t &&
343+
echo y | git add -p >output &&
344+
! grep a/conflict.t output &&
345+
cat >expected <<-\EOF &&
346+
* Unmerged path conflict.t
347+
diff --git a/non-conflict.t b/non-conflict.t
348+
index f766221..5ea2ed4 100644
349+
--- a/non-conflict.t
350+
+++ b/non-conflict.t
351+
@@ -1 +1 @@
352+
-non-conflict
353+
+changed
354+
EOF
355+
git diff --cached >diff &&
356+
test_cmp expected diff
357+
'
358+
333359
test_done

0 commit comments

Comments
 (0)