Skip to content

Commit 827e7a4

Browse files
committed
fixup! built-in add -p: coalesce hunks after splitting them
Phillip Wood pointed out, long ago, that `temp` -> `merged` would make it easier to read this code. Somehow, this change only made it into gitgitgadget#173 but not into Git for Windows' `master`. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent ca06a95 commit 827e7a4

File tree

1 file changed

+33
-26
lines changed

1 file changed

+33
-26
lines changed

add-patch.c

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -658,37 +658,44 @@ static void render_diff_header(struct add_p_state *s,
658658

659659
/* Coalesce hunks again that were split */
660660
static int merge_hunks(struct add_p_state *s, struct file_diff *file_diff,
661-
size_t *hunk_index, int use_all, struct hunk *temp)
661+
size_t *hunk_index, int use_all, struct hunk *merged)
662662
{
663663
size_t i = *hunk_index, delta;
664664
struct hunk *hunk = file_diff->hunk + i;
665-
struct hunk_header *header = &temp->header, *next;
665+
/* `header` corresponds to the merged hunk */
666+
struct hunk_header *header = &merged->header, *next;
666667

667668
if (!use_all && hunk->use != USE_HUNK)
668669
return 0;
669670

670-
memcpy(temp, hunk, sizeof(*temp));
671+
*merged = *hunk;
671672
/* We simply skip the colored part (if any) when merging hunks */
672-
temp->colored_start = temp->colored_end = 0;
673+
merged->colored_start = merged->colored_end = 0;
673674

674675
for (; i + 1 < file_diff->hunk_nr; i++) {
675676
hunk++;
676677
next = &hunk->header;
677678

679+
/*
680+
* Stop merging hunks when:
681+
*
682+
* - the hunk is not selected for use, or
683+
* - the hunk does not overlap with the already-merged hunk(s)
684+
*/
678685
if ((!use_all && hunk->use != USE_HUNK) ||
679-
header->new_offset >= next->new_offset + temp->delta ||
686+
header->new_offset >= next->new_offset + merged->delta ||
680687
header->new_offset + header->new_count
681-
< next->new_offset + temp->delta)
688+
< next->new_offset + merged->delta)
682689
break;
683690

684-
if (temp->start < hunk->start && temp->end > hunk->start) {
685-
temp->end = hunk->end;
686-
temp->colored_end = hunk->colored_end;
691+
if (merged->start < hunk->start && merged->end > hunk->start) {
692+
merged->end = hunk->end;
693+
merged->colored_end = hunk->colored_end;
687694
delta = 0;
688695
} else {
689696
const char *plain = s->plain.buf;
690697
size_t overlapping_line_count = header->new_offset
691-
+ header->new_count - temp->delta
698+
+ header->new_count - merged->delta
692699
- next->new_offset;
693700
size_t overlap_end = hunk->start;
694701
size_t overlap_start = overlap_end;
@@ -725,13 +732,13 @@ static int merge_hunks(struct add_p_state *s, struct file_diff *file_diff,
725732
}
726733
len = overlap_end - overlap_start;
727734

728-
if (len > temp->end - temp->start ||
729-
memcmp(plain + temp->end - len,
735+
if (len > merged->end - merged->start ||
736+
memcmp(plain + merged->end - len,
730737
plain + overlap_start, len))
731738
return error(_("hunks do not overlap:\n%.*s\n"
732739
"\tdoes not end with:\n%.*s"),
733-
(int)(temp->end - temp->start),
734-
plain + temp->start,
740+
(int)(merged->end - merged->start),
741+
plain + merged->start,
735742
(int)len, plain + overlap_start);
736743

737744
/*
@@ -740,23 +747,23 @@ static int merge_hunks(struct add_p_state *s, struct file_diff *file_diff,
740747
* address that, we temporarily append the union of the
741748
* lines to the `plain` strbuf.
742749
*/
743-
if (temp->end != s->plain.len) {
750+
if (merged->end != s->plain.len) {
744751
size_t start = s->plain.len;
745752

746-
strbuf_add(&s->plain, plain + temp->start,
747-
temp->end - temp->start);
753+
strbuf_add(&s->plain, plain + merged->start,
754+
merged->end - merged->start);
748755
plain = s->plain.buf;
749-
temp->start = start;
750-
temp->end = s->plain.len;
756+
merged->start = start;
757+
merged->end = s->plain.len;
751758
}
752759

753760
strbuf_add(&s->plain,
754761
plain + overlap_end,
755762
hunk->end - overlap_end);
756-
temp->end = s->plain.len;
757-
temp->splittable_into += hunk->splittable_into;
758-
delta = temp->delta;
759-
temp->delta += hunk->delta;
763+
merged->end = s->plain.len;
764+
merged->splittable_into += hunk->splittable_into;
765+
delta = merged->delta;
766+
merged->delta += hunk->delta;
760767
}
761768

762769
header->old_count = next->old_offset + next->old_count
@@ -783,16 +790,16 @@ static void reassemble_patch(struct add_p_state *s,
783790
render_diff_header(s, file_diff, 0, out);
784791

785792
for (i = file_diff->mode_change; i < file_diff->hunk_nr; i++) {
786-
struct hunk temp = { 0 };
793+
struct hunk merged = { 0 };
787794

788795
hunk = file_diff->hunk + i;
789796
if (!use_all && hunk->use != USE_HUNK)
790797
delta += hunk->header.old_count
791798
- hunk->header.new_count;
792799
else {
793800
/* merge overlapping hunks into a temporary hunk */
794-
if (merge_hunks(s, file_diff, &i, use_all, &temp))
795-
hunk = &temp;
801+
if (merge_hunks(s, file_diff, &i, use_all, &merged))
802+
hunk = &merged;
796803

797804
render_hunk(s, hunk, delta, 0, out);
798805

0 commit comments

Comments
 (0)