Merge branch 'pw/add-p-hunk-splitting-fix'

Marking a hunk 'selected' in "git add -p" and then splitting made
all the split pieces 'selected'; this has been changed to make them
all 'undecided', which gives better end-user experience.

* pw/add-p-hunk-splitting-fix:
  add-patch: update hunk splitability after editing
  add -p: mark split hunks as undecided
This commit is contained in:
Junio C Hamano
2025-10-14 12:56:08 -07:00
2 changed files with 44 additions and 2 deletions

View File

@@ -956,6 +956,7 @@ static int split_hunk(struct add_p_state *s, struct file_diff *file_diff,
* sizeof(*hunk)); * sizeof(*hunk));
hunk = file_diff->hunk + hunk_index; hunk = file_diff->hunk + hunk_index;
hunk->splittable_into = 1; hunk->splittable_into = 1;
hunk->use = UNDECIDED_HUNK;
memset(hunk + 1, 0, (splittable_into - 1) * sizeof(*hunk)); memset(hunk + 1, 0, (splittable_into - 1) * sizeof(*hunk));
header = &hunk->header; header = &hunk->header;
@@ -1057,7 +1058,7 @@ next_hunk_line:
hunk++; hunk++;
hunk->splittable_into = 1; hunk->splittable_into = 1;
hunk->use = hunk[-1].use; hunk->use = UNDECIDED_HUNK;
header = &hunk->header; header = &hunk->header;
header->old_count = header->new_count = context_line_count; header->old_count = header->new_count = context_line_count;
@@ -1184,19 +1185,29 @@ static ssize_t recount_edited_hunk(struct add_p_state *s, struct hunk *hunk,
{ {
struct hunk_header *header = &hunk->header; struct hunk_header *header = &hunk->header;
size_t i; size_t i;
char ch, marker = ' ';
hunk->splittable_into = 0;
header->old_count = header->new_count = 0; header->old_count = header->new_count = 0;
for (i = hunk->start; i < hunk->end; ) { for (i = hunk->start; i < hunk->end; ) {
switch(normalize_marker(&s->plain.buf[i])) { ch = normalize_marker(&s->plain.buf[i]);
switch (ch) {
case '-': case '-':
header->old_count++; header->old_count++;
if (marker == ' ')
hunk->splittable_into++;
marker = ch;
break; break;
case '+': case '+':
header->new_count++; header->new_count++;
if (marker == ' ')
hunk->splittable_into++;
marker = ch;
break; break;
case ' ': case ' ':
header->old_count++; header->old_count++;
header->new_count++; header->new_count++;
marker = ch;
break; break;
} }

View File

@@ -1354,4 +1354,35 @@ do
' '
done done
test_expect_success 'splitting previous hunk marks split hunks as undecided' '
test_write_lines a " " b c d e f g h i j k >file &&
git add file &&
test_write_lines x " " b y d e f g h i j x >file &&
test_write_lines n K s n y q | git add -p file &&
git cat-file blob :file >actual &&
test_write_lines a " " b y d e f g h i j k >expect &&
test_cmp expect actual
'
test_expect_success 'splitting edited hunk' '
# Before the first hunk is edited it can be split into two
# hunks, after editing it can be split into three hunks.
write_script fake-editor.sh <<-\EOF &&
sed "s/^ c/-c/" "$1" >"$1.tmp" &&
mv "$1.tmp" "$1"
EOF
test_write_lines a b c d e f g h i j k l m n >file &&
git add file &&
test_write_lines A b c d E f g h i j k l M n >file &&
(
test_set_editor "$(pwd)/fake-editor.sh" &&
test_write_lines e K s j y n y q | git add -p file
) &&
git cat-file blob :file >actual &&
test_write_lines a b d e f g h i j k l M n >expect &&
test_cmp expect actual
'
test_done test_done