]>
Commit | Line | Data |
---|---|---|
5f1c3f07 JH |
1 | #include "cache.h" |
2 | #include "diff.h" | |
3 | #include "commit.h" | |
4 | #include "log-tree.h" | |
5 | ||
cd2bdc53 | 6 | int log_tree_diff_flush(struct rev_info *opt) |
5f1c3f07 JH |
7 | { |
8 | diffcore_std(&opt->diffopt); | |
9 | if (diff_queue_is_empty()) { | |
10 | int saved_fmt = opt->diffopt.output_format; | |
11 | opt->diffopt.output_format = DIFF_FORMAT_NO_OUTPUT; | |
12 | diff_flush(&opt->diffopt); | |
13 | opt->diffopt.output_format = saved_fmt; | |
14 | return 0; | |
15 | } | |
16 | if (opt->header) { | |
17 | if (!opt->no_commit_id) | |
18 | printf("%s%c", opt->header, | |
19 | opt->diffopt.line_termination); | |
20 | opt->header = NULL; | |
21 | } | |
22 | diff_flush(&opt->diffopt); | |
23 | return 1; | |
24 | } | |
25 | ||
cd2bdc53 | 26 | static int diff_root_tree(struct rev_info *opt, |
5f1c3f07 JH |
27 | const unsigned char *new, const char *base) |
28 | { | |
29 | int retval; | |
30 | void *tree; | |
31 | struct tree_desc empty, real; | |
32 | ||
33 | tree = read_object_with_reference(new, tree_type, &real.size, NULL); | |
34 | if (!tree) | |
35 | die("unable to read root tree (%s)", sha1_to_hex(new)); | |
36 | real.buf = tree; | |
37 | ||
38 | empty.buf = ""; | |
39 | empty.size = 0; | |
40 | retval = diff_tree(&empty, &real, base, &opt->diffopt); | |
41 | free(tree); | |
42 | log_tree_diff_flush(opt); | |
43 | return retval; | |
44 | } | |
45 | ||
cd2bdc53 | 46 | static const char *generate_header(struct rev_info *opt, |
5f1c3f07 JH |
47 | const unsigned char *commit_sha1, |
48 | const unsigned char *parent_sha1, | |
49 | const struct commit *commit) | |
50 | { | |
51 | static char this_header[16384]; | |
52 | int offset; | |
53 | unsigned long len; | |
54 | int abbrev = opt->diffopt.abbrev; | |
55 | const char *msg = commit->buffer; | |
56 | ||
57 | if (!opt->verbose_header) | |
58 | return sha1_to_hex(commit_sha1); | |
59 | ||
60 | len = strlen(msg); | |
61 | ||
62 | offset = sprintf(this_header, "%s%s ", | |
63 | opt->header_prefix, | |
64 | diff_unique_abbrev(commit_sha1, abbrev)); | |
65 | if (commit_sha1 != parent_sha1) | |
66 | offset += sprintf(this_header + offset, "(from %s)\n", | |
67 | parent_sha1 | |
68 | ? diff_unique_abbrev(parent_sha1, abbrev) | |
69 | : "root"); | |
70 | else | |
71 | offset += sprintf(this_header + offset, "(from parents)\n"); | |
72 | offset += pretty_print_commit(opt->commit_format, commit, len, | |
73 | this_header + offset, | |
74 | sizeof(this_header) - offset, abbrev); | |
75 | if (opt->always_show_header) { | |
76 | puts(this_header); | |
77 | return NULL; | |
78 | } | |
79 | return this_header; | |
80 | } | |
81 | ||
cd2bdc53 | 82 | static int do_diff_combined(struct rev_info *opt, struct commit *commit) |
5f1c3f07 JH |
83 | { |
84 | unsigned const char *sha1 = commit->object.sha1; | |
85 | ||
86 | opt->header = generate_header(opt, sha1, sha1, commit); | |
87 | opt->header = diff_tree_combined_merge(sha1, opt->header, | |
88 | opt->dense_combined_merges, | |
89 | &opt->diffopt); | |
90 | if (!opt->header && opt->verbose_header) | |
91 | opt->header_prefix = "\ndiff-tree "; | |
92 | return 0; | |
93 | } | |
94 | ||
cd2bdc53 | 95 | int log_tree_commit(struct rev_info *opt, struct commit *commit) |
5f1c3f07 JH |
96 | { |
97 | struct commit_list *parents; | |
98 | unsigned const char *sha1 = commit->object.sha1; | |
99 | ||
100 | /* Root commit? */ | |
101 | if (opt->show_root_diff && !commit->parents) { | |
102 | opt->header = generate_header(opt, sha1, NULL, commit); | |
103 | diff_root_tree(opt, sha1, ""); | |
104 | } | |
105 | ||
106 | /* More than one parent? */ | |
107 | if (commit->parents && commit->parents->next) { | |
108 | if (opt->ignore_merges) | |
109 | return 0; | |
110 | else if (opt->combine_merges) | |
111 | return do_diff_combined(opt, commit); | |
112 | } | |
113 | ||
114 | for (parents = commit->parents; parents; parents = parents->next) { | |
115 | struct commit *parent = parents->item; | |
116 | unsigned const char *psha1 = parent->object.sha1; | |
117 | opt->header = generate_header(opt, sha1, psha1, commit); | |
118 | diff_tree_sha1(psha1, sha1, "", &opt->diffopt); | |
119 | log_tree_diff_flush(opt); | |
120 | ||
121 | if (!opt->header && opt->verbose_header) | |
122 | opt->header_prefix = "\ndiff-tree "; | |
123 | } | |
124 | return 0; | |
125 | } |