Skip to content

Commit 3f6726e

Browse files
author
Junio C Hamano
committed
Merge branch 'lt/diff-tree'
* lt/diff-tree: combine-diff: Record diff status a bit more faithfully find_unique_abbrev() simplification. combine-diff: move formatting logic to show_combined_diff() combined-diff: use diffcore before intersecting paths. diff-tree -c raw output
2 parents 9ae6be8 + d416df8 commit 3f6726e

File tree

6 files changed

+144
-52
lines changed

6 files changed

+144
-52
lines changed

combine-diff.c

Lines changed: 116 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
3939
p->mode = q->queue[i]->two->mode;
4040
memcpy(p->parent[n].sha1, q->queue[i]->one->sha1, 20);
4141
p->parent[n].mode = q->queue[i]->one->mode;
42+
p->parent[n].status = q->queue[i]->status;
4243
*tail = p;
4344
tail = &p->next;
4445
}
@@ -62,6 +63,7 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
6263
memcpy(p->parent[n].sha1,
6364
q->queue[i]->one->sha1, 20);
6465
p->parent[n].mode = q->queue[i]->one->mode;
66+
p->parent[n].status = q->queue[i]->status;
6567
break;
6668
}
6769
}
@@ -618,8 +620,8 @@ static void reuse_combine_diff(struct sline *sline, unsigned long cnt,
618620
sline->p_lno[i] = sline->p_lno[j];
619621
}
620622

621-
int show_combined_diff(struct combine_diff_path *elem, int num_parent,
622-
int dense, const char *header)
623+
static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
624+
int dense, const char *header)
623625
{
624626
unsigned long size, cnt, lno;
625627
char *result, *cp, *ep;
@@ -716,10 +718,7 @@ int show_combined_diff(struct combine_diff_path *elem, int num_parent,
716718

717719
if (show_hunks || mode_differs) {
718720
const char *abb;
719-
char null_abb[DEFAULT_ABBREV + 1];
720721

721-
memset(null_abb, '0', DEFAULT_ABBREV);
722-
null_abb[DEFAULT_ABBREV] = 0;
723722
if (header) {
724723
shown_header++;
725724
puts(header);
@@ -734,26 +733,33 @@ int show_combined_diff(struct combine_diff_path *elem, int num_parent,
734733
for (i = 0; i < num_parent; i++) {
735734
if (elem->parent[i].mode != elem->mode)
736735
mode_differs = 1;
737-
if (memcmp(elem->parent[i].sha1, null_sha1, 20))
738-
abb = find_unique_abbrev(elem->parent[i].sha1,
739-
DEFAULT_ABBREV);
740-
else
741-
abb = null_abb;
736+
abb = find_unique_abbrev(elem->parent[i].sha1,
737+
DEFAULT_ABBREV);
742738
printf("%s%s", i ? "," : "", abb);
743739
}
744-
if (memcmp(elem->sha1, null_sha1, 20))
745-
abb = find_unique_abbrev(elem->sha1, DEFAULT_ABBREV);
746-
else
747-
abb = null_abb;
740+
abb = find_unique_abbrev(elem->sha1, DEFAULT_ABBREV);
748741
printf("..%s\n", abb);
749742

750743
if (mode_differs) {
751-
printf("mode ");
752-
for (i = 0; i < num_parent; i++) {
753-
printf("%s%06o", i ? "," : "",
754-
elem->parent[i].mode);
744+
int added = !!elem->mode;
745+
for (i = 0; added && i < num_parent; i++)
746+
if (elem->parent[i].status !=
747+
DIFF_STATUS_ADDED)
748+
added = 0;
749+
if (added)
750+
printf("new file mode %06o", elem->mode);
751+
else {
752+
if (!elem->mode)
753+
printf("deleted file ");
754+
printf("mode ");
755+
for (i = 0; i < num_parent; i++) {
756+
printf("%s%06o", i ? "," : "",
757+
elem->parent[i].mode);
758+
}
759+
if (elem->mode)
760+
printf("..%06o", elem->mode);
755761
}
756-
printf("..%06o\n", elem->mode);
762+
putchar('\n');
757763
}
758764
dump_sline(sline, cnt, num_parent);
759765
}
@@ -776,16 +782,100 @@ int show_combined_diff(struct combine_diff_path *elem, int num_parent,
776782
return shown_header;
777783
}
778784

779-
int diff_tree_combined_merge(const unsigned char *sha1,
780-
const char *header, int dense)
785+
#define COLONS "::::::::::::::::::::::::::::::::"
786+
787+
static void show_raw_diff(struct combine_diff_path *p, int num_parent, const char *header, struct diff_options *opt)
788+
{
789+
int i, offset, mod_type = 'A';
790+
const char *prefix;
791+
int line_termination, inter_name_termination;
792+
793+
line_termination = opt->line_termination;
794+
inter_name_termination = '\t';
795+
if (!line_termination)
796+
inter_name_termination = 0;
797+
798+
if (header)
799+
puts(header);
800+
801+
for (i = 0; i < num_parent; i++) {
802+
if (p->parent[i].mode)
803+
mod_type = 'M';
804+
}
805+
if (!p->mode)
806+
mod_type = 'D';
807+
808+
if (opt->output_format == DIFF_FORMAT_RAW) {
809+
offset = strlen(COLONS) - num_parent;
810+
if (offset < 0)
811+
offset = 0;
812+
prefix = COLONS + offset;
813+
814+
/* Show the modes */
815+
for (i = 0; i < num_parent; i++) {
816+
printf("%s%06o", prefix, p->parent[i].mode);
817+
prefix = " ";
818+
}
819+
printf("%s%06o", prefix, p->mode);
820+
821+
/* Show sha1's */
822+
for (i = 0; i < num_parent; i++)
823+
printf(" %s", diff_unique_abbrev(p->parent[i].sha1,
824+
opt->abbrev));
825+
printf(" %s ", diff_unique_abbrev(p->sha1, opt->abbrev));
826+
}
827+
828+
if (opt->output_format == DIFF_FORMAT_RAW ||
829+
opt->output_format == DIFF_FORMAT_NAME_STATUS) {
830+
for (i = 0; i < num_parent; i++)
831+
putchar(p->parent[i].status);
832+
putchar(inter_name_termination);
833+
}
834+
835+
if (line_termination) {
836+
if (quote_c_style(p->path, NULL, NULL, 0))
837+
quote_c_style(p->path, NULL, stdout, 0);
838+
else
839+
printf("%s", p->path);
840+
putchar(line_termination);
841+
}
842+
else {
843+
printf("%s%c", p->path, line_termination);
844+
}
845+
}
846+
847+
int show_combined_diff(struct combine_diff_path *p,
848+
int num_parent,
849+
int dense,
850+
const char *header,
851+
struct diff_options *opt)
852+
{
853+
if (!p->len)
854+
return 0;
855+
switch (opt->output_format) {
856+
case DIFF_FORMAT_RAW:
857+
case DIFF_FORMAT_NAME_STATUS:
858+
case DIFF_FORMAT_NAME:
859+
show_raw_diff(p, num_parent, header, opt);
860+
return 1;
861+
862+
default:
863+
case DIFF_FORMAT_PATCH:
864+
return show_patch_diff(p, num_parent, dense, header);
865+
}
866+
}
867+
868+
const char *diff_tree_combined_merge(const unsigned char *sha1,
869+
const char *header, int dense,
870+
struct diff_options *opt)
781871
{
782872
struct commit *commit = lookup_commit(sha1);
783873
struct diff_options diffopts;
784874
struct commit_list *parents;
785875
struct combine_diff_path *p, *paths = NULL;
786876
int num_parent, i, num_paths;
787877

788-
diff_setup(&diffopts);
878+
diffopts = *opt;
789879
diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
790880
diffopts.recursive = 1;
791881

@@ -802,6 +892,7 @@ int diff_tree_combined_merge(const unsigned char *sha1,
802892
struct commit *parent = parents->item;
803893
diff_tree_sha1(parent->object.sha1, commit->object.sha1, "",
804894
&diffopts);
895+
diffcore_std(&diffopts);
805896
paths = intersect_paths(paths, i, num_parent);
806897
diff_flush(&diffopts);
807898
}
@@ -813,9 +904,8 @@ int diff_tree_combined_merge(const unsigned char *sha1,
813904
}
814905
if (num_paths) {
815906
for (p = paths; p; p = p->next) {
816-
if (!p->len)
817-
continue;
818-
if (show_combined_diff(p, num_parent, dense, header))
907+
if (show_combined_diff(p, num_parent, dense,
908+
header, opt))
819909
header = NULL;
820910
}
821911
}
@@ -826,5 +916,5 @@ int diff_tree_combined_merge(const unsigned char *sha1,
826916
paths = paths->next;
827917
free(tmp);
828918
}
829-
return 0;
919+
return header;
830920
}

diff-files.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,8 @@ int main(int argc, const char **argv)
8888
}
8989
argv++; argc--;
9090
}
91-
if (combine_merges) {
91+
if (dense_combined_merges)
9292
diff_options.output_format = DIFF_FORMAT_PATCH;
93-
}
9493

9594
/* Find the directory, and set up the pathspec */
9695
pathspec = get_pathspec(prefix, argv + 1);
@@ -166,7 +165,8 @@ int main(int argc, const char **argv)
166165
if (combine_merges && num_compare_stages == 2) {
167166
show_combined_diff(&combine.p, 2,
168167
dense_combined_merges,
169-
NULL);
168+
NULL,
169+
&diff_options);
170170
free(combine.p.path);
171171
continue;
172172
}

diff-tree.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ static int show_root_diff = 0;
66
static int no_commit_id = 0;
77
static int verbose_header = 0;
88
static int ignore_merges = 1;
9-
static int combine_merges = 0;
9+
static int combine_merges = 1;
1010
static int dense_combined_merges = 0;
1111
static int read_stdin = 0;
1212
static int always_show_header = 0;
@@ -117,8 +117,12 @@ static int diff_tree_commit(struct commit *commit)
117117
return 0;
118118
else if (combine_merges) {
119119
header = generate_header(sha1, sha1, commit);
120-
return diff_tree_combined_merge(sha1, header,
121-
dense_combined_merges);
120+
header = diff_tree_combined_merge(sha1, header,
121+
dense_combined_merges,
122+
&diff_options);
123+
if (!header && verbose_header)
124+
header_prefix = "\ndiff-tree ";
125+
return 0;
122126
}
123127
}
124128

@@ -244,7 +248,7 @@ int main(int argc, const char **argv)
244248
continue;
245249
}
246250
if (!strcmp(arg, "-m")) {
247-
ignore_merges = 0;
251+
combine_merges = ignore_merges = 0;
248252
continue;
249253
}
250254
if (!strcmp(arg, "-c")) {
@@ -285,10 +289,12 @@ int main(int argc, const char **argv)
285289
usage(diff_tree_usage);
286290
}
287291

288-
if (combine_merges) {
289-
diff_options.output_format = DIFF_FORMAT_PATCH;
292+
if (combine_merges)
290293
ignore_merges = 0;
291-
}
294+
295+
/* We can only do dense combined merges with diff output */
296+
if (dense_combined_merges)
297+
diff_options.output_format = DIFF_FORMAT_PATCH;
292298

293299
if (diff_options.output_format == DIFF_FORMAT_PATCH)
294300
diff_options.recursive = 1;

diff.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,7 @@ void diff_free_filepair(struct diff_filepair *p)
963963
}
964964

965965
/* This is different from find_unique_abbrev() in that
966-
* it needs to deal with 0{40} SHA1.
966+
* it stuffs the result with dots for alignment.
967967
*/
968968
const char *diff_unique_abbrev(const unsigned char *sha1, int len)
969969
{
@@ -973,16 +973,8 @@ const char *diff_unique_abbrev(const unsigned char *sha1, int len)
973973
return sha1_to_hex(sha1);
974974

975975
abbrev = find_unique_abbrev(sha1, len);
976-
if (!abbrev) {
977-
if (!memcmp(sha1, null_sha1, 20)) {
978-
char *buf = sha1_to_hex(null_sha1);
979-
if (len < 37)
980-
strcpy(buf + len, "...");
981-
return buf;
982-
}
983-
else
984-
return sha1_to_hex(sha1);
985-
}
976+
if (!abbrev)
977+
return sha1_to_hex(sha1);
986978
abblen = strlen(abbrev);
987979
if (abblen < 37) {
988980
static char hex[41];

diff.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ struct combine_diff_path {
6666
unsigned int mode;
6767
unsigned char sha1[20];
6868
struct combine_diff_parent {
69+
char status;
6970
unsigned int mode;
7071
unsigned char sha1[20];
7172
} parent[FLEX_ARRAY];
@@ -74,10 +75,11 @@ struct combine_diff_path {
7475
(sizeof(struct combine_diff_path) + \
7576
sizeof(struct combine_diff_parent) * (n) + (l) + 1)
7677

77-
int show_combined_diff(struct combine_diff_path *elem, int num_parent,
78-
int dense, const char *header);
78+
extern int show_combined_diff(struct combine_diff_path *elem, int num_parent,
79+
int dense, const char *header,
80+
struct diff_options *);
7981

80-
extern int diff_tree_combined_merge(const unsigned char *sha1, const char *, int);
82+
extern const char *diff_tree_combined_merge(const unsigned char *sha1, const char *, int, struct diff_options *opt);
8183

8284
extern void diff_addremove(struct diff_options *,
8385
int addremove,

sha1_name.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,16 +186,18 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1,
186186

187187
const char *find_unique_abbrev(const unsigned char *sha1, int len)
188188
{
189-
int status;
189+
int status, is_null;
190190
static char hex[41];
191191

192+
is_null = !memcmp(sha1, null_sha1, 20);
192193
memcpy(hex, sha1_to_hex(sha1), 40);
193194
if (len == 40)
194195
return hex;
195196
while (len < 40) {
196197
unsigned char sha1_ret[20];
197198
status = get_short_sha1(hex, len, sha1_ret, 1);
198-
if (!status) {
199+
if (!status ||
200+
(is_null && status != SHORT_NAME_AMBIGUOUS)) {
199201
hex[len] = 0;
200202
return hex;
201203
}

0 commit comments

Comments
 (0)