6 void init_log_tree_opt(struct log_tree_opt
*opt
)
8 memset(opt
, 0, sizeof *opt
);
9 opt
->ignore_merges
= 1;
10 opt
->header_prefix
= "";
11 opt
->commit_format
= CMIT_FMT_RAW
;
12 diff_setup(&opt
->diffopt
);
15 int log_tree_opt_parse(struct log_tree_opt
*opt
, const char **av
, int ac
)
18 int cnt
= diff_opt_parse(&opt
->diffopt
, av
, ac
);
22 if (!strcmp(arg
, "-r"))
23 opt
->diffopt
.recursive
= 1;
24 else if (!strcmp(arg
, "-t")) {
25 opt
->diffopt
.recursive
= 1;
26 opt
->diffopt
.tree_in_recursive
= 1;
28 else if (!strcmp(arg
, "-m"))
29 opt
->ignore_merges
= 0;
30 else if (!strcmp(arg
, "-c"))
31 opt
->combine_merges
= 1;
32 else if (!strcmp(arg
, "--cc")) {
33 opt
->dense_combined_merges
= 1;
34 opt
->combine_merges
= 1;
36 else if (!strcmp(arg
, "-v")) {
37 opt
->verbose_header
= 1;
38 opt
->header_prefix
= "diff-tree ";
40 else if (!strncmp(arg
, "--pretty", 8)) {
41 opt
->verbose_header
= 1;
42 opt
->header_prefix
= "diff-tree ";
43 opt
->commit_format
= get_commit_format(arg
+8);
45 else if (!strcmp(arg
, "--root"))
46 opt
->show_root_diff
= 1;
47 else if (!strcmp(arg
, "--no-commit-id"))
48 opt
->no_commit_id
= 1;
49 else if (!strcmp(arg
, "--always"))
50 opt
->always_show_header
= 1;
56 int log_tree_diff_flush(struct log_tree_opt
*opt
)
58 diffcore_std(&opt
->diffopt
);
59 if (diff_queue_is_empty()) {
60 int saved_fmt
= opt
->diffopt
.output_format
;
61 opt
->diffopt
.output_format
= DIFF_FORMAT_NO_OUTPUT
;
62 diff_flush(&opt
->diffopt
);
63 opt
->diffopt
.output_format
= saved_fmt
;
67 if (!opt
->no_commit_id
)
68 printf("%s%c", opt
->header
,
69 opt
->diffopt
.line_termination
);
72 diff_flush(&opt
->diffopt
);
76 static int diff_root_tree(struct log_tree_opt
*opt
,
77 const unsigned char *new, const char *base
)
81 struct tree_desc empty
, real
;
83 tree
= read_object_with_reference(new, tree_type
, &real
.size
, NULL
);
85 die("unable to read root tree (%s)", sha1_to_hex(new));
90 retval
= diff_tree(&empty
, &real
, base
, &opt
->diffopt
);
92 log_tree_diff_flush(opt
);
96 static const char *generate_header(struct log_tree_opt
*opt
,
97 const unsigned char *commit_sha1
,
98 const unsigned char *parent_sha1
,
99 const struct commit
*commit
)
101 static char this_header
[16384];
104 int abbrev
= opt
->diffopt
.abbrev
;
105 const char *msg
= commit
->buffer
;
107 if (!opt
->verbose_header
)
108 return sha1_to_hex(commit_sha1
);
112 offset
= sprintf(this_header
, "%s%s ",
114 diff_unique_abbrev(commit_sha1
, abbrev
));
115 if (commit_sha1
!= parent_sha1
)
116 offset
+= sprintf(this_header
+ offset
, "(from %s)\n",
118 ? diff_unique_abbrev(parent_sha1
, abbrev
)
121 offset
+= sprintf(this_header
+ offset
, "(from parents)\n");
122 offset
+= pretty_print_commit(opt
->commit_format
, commit
, len
,
123 this_header
+ offset
,
124 sizeof(this_header
) - offset
, abbrev
);
125 if (opt
->always_show_header
) {
132 static int do_diff_combined(struct log_tree_opt
*opt
, struct commit
*commit
)
134 unsigned const char *sha1
= commit
->object
.sha1
;
136 opt
->header
= generate_header(opt
, sha1
, sha1
, commit
);
137 opt
->header
= diff_tree_combined_merge(sha1
, opt
->header
,
138 opt
->dense_combined_merges
,
140 if (!opt
->header
&& opt
->verbose_header
)
141 opt
->header_prefix
= "\ndiff-tree ";
145 int log_tree_commit(struct log_tree_opt
*opt
, struct commit
*commit
)
147 struct commit_list
*parents
;
148 unsigned const char *sha1
= commit
->object
.sha1
;
151 if (opt
->show_root_diff
&& !commit
->parents
) {
152 opt
->header
= generate_header(opt
, sha1
, NULL
, commit
);
153 diff_root_tree(opt
, sha1
, "");
156 /* More than one parent? */
157 if (commit
->parents
&& commit
->parents
->next
) {
158 if (opt
->ignore_merges
)
160 else if (opt
->combine_merges
)
161 return do_diff_combined(opt
, commit
);
164 for (parents
= commit
->parents
; parents
; parents
= parents
->next
) {
165 struct commit
*parent
= parents
->item
;
166 unsigned const char *psha1
= parent
->object
.sha1
;
167 opt
->header
= generate_header(opt
, sha1
, psha1
, commit
);
168 diff_tree_sha1(psha1
, sha1
, "", &opt
->diffopt
);
169 log_tree_diff_flush(opt
);
171 if (!opt
->header
&& opt
->verbose_header
)
172 opt
->header_prefix
= "\ndiff-tree ";
177 int parse_whatchanged_opt(int ac
, const char **av
, struct whatchanged_opt
*wcopt
)
179 struct rev_info
*rev
= &wcopt
->revopt
;
180 struct log_tree_opt
*opt
= &wcopt
->logopt
;
181 const char **unrecognized
= av
+1;
184 ac
= setup_revisions(ac
, av
, rev
, "HEAD");
185 if (!strcmp(av
[0], "show"))
188 const char *arg
= av
[1];
189 if (!strncmp(arg
, "--pretty", 8)) {
190 opt
->commit_format
= get_commit_format(arg
+ 8);
192 else if (!strcmp(arg
, "--no-abbrev")) {
195 else if (!strcmp(arg
, "--abbrev")) {
196 wcopt
->abbrev
= DEFAULT_ABBREV
;
198 else if (!strcmp(arg
, "--abbrev-commit")) {
199 wcopt
->abbrev_commit
= 1;
201 else if (!strncmp(arg
, "--abbrev=", 9)) {
202 wcopt
->abbrev
= strtoul(arg
+ 9, NULL
, 10);
203 if (wcopt
->abbrev
&& wcopt
->abbrev
< MINIMUM_ABBREV
)
204 wcopt
->abbrev
= MINIMUM_ABBREV
;
205 else if (40 < wcopt
->abbrev
)
208 else if (!strcmp(arg
, "--full-diff")) {
210 wcopt
->full_diff
= 1;
213 int cnt
= log_tree_opt_parse(opt
, av
+1, ac
-1);
220 *unrecognized
++ = arg
;
226 if (wcopt
->do_diff
) {
227 opt
->diffopt
.abbrev
= wcopt
->abbrev
;
228 opt
->verbose_header
= 0;
229 opt
->always_show_header
= 0;
230 opt
->no_commit_id
= 1;
231 if (opt
->combine_merges
)
232 opt
->ignore_merges
= 0;
233 if (opt
->dense_combined_merges
)
234 opt
->diffopt
.output_format
= DIFF_FORMAT_PATCH
;
235 if (opt
->diffopt
.output_format
== DIFF_FORMAT_PATCH
)
236 opt
->diffopt
.recursive
= 1;
237 if (!wcopt
->full_diff
&& rev
->prune_data
)
238 diff_tree_setup_paths(rev
->prune_data
, &opt
->diffopt
);
239 diff_setup_done(&opt
->diffopt
);