Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 1 | #include "cache.h" |
| 2 | #include "diff.h" |
| 3 | #include "commit.h" |
| 4 | #include "log-tree.h" |
Johannes Schindelin | 8860fd4 | 2007-01-11 11:47:48 +0100 | [diff] [blame] | 5 | #include "reflog-walk.h" |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 6 | |
Linus Torvalds | c8c893c | 2006-05-03 07:59:00 -0700 | [diff] [blame] | 7 | static void show_parents(struct commit *commit, int abbrev) |
| 8 | { |
| 9 | struct commit_list *p; |
| 10 | for (p = commit->parents; p ; p = p->next) { |
| 11 | struct commit *parent = p->item; |
| 12 | printf(" %s", diff_unique_abbrev(parent->object.sha1, abbrev)); |
| 13 | } |
| 14 | } |
| 15 | |
Franck Bui-Huu | fc1c75e | 2006-08-29 13:37:06 +0200 | [diff] [blame] | 16 | /* |
| 17 | * Search for "^[-A-Za-z]+: [^@]+@" pattern. It usually matches |
| 18 | * Signed-off-by: and Acked-by: lines. |
| 19 | */ |
| 20 | static int detect_any_signoff(char *letter, int size) |
| 21 | { |
| 22 | char ch, *cp; |
| 23 | int seen_colon = 0; |
| 24 | int seen_at = 0; |
| 25 | int seen_name = 0; |
| 26 | int seen_head = 0; |
| 27 | |
| 28 | cp = letter + size; |
| 29 | while (letter <= --cp && (ch = *cp) == '\n') |
| 30 | continue; |
| 31 | |
| 32 | while (letter <= cp) { |
| 33 | ch = *cp--; |
| 34 | if (ch == '\n') |
| 35 | break; |
| 36 | |
| 37 | if (!seen_at) { |
| 38 | if (ch == '@') |
| 39 | seen_at = 1; |
| 40 | continue; |
| 41 | } |
| 42 | if (!seen_colon) { |
| 43 | if (ch == '@') |
| 44 | return 0; |
| 45 | else if (ch == ':') |
| 46 | seen_colon = 1; |
| 47 | else |
| 48 | seen_name = 1; |
| 49 | continue; |
| 50 | } |
| 51 | if (('A' <= ch && ch <= 'Z') || |
| 52 | ('a' <= ch && ch <= 'z') || |
| 53 | ch == '-') { |
| 54 | seen_head = 1; |
| 55 | continue; |
| 56 | } |
| 57 | /* no empty last line doesn't match */ |
| 58 | return 0; |
| 59 | } |
| 60 | return seen_head && seen_name; |
| 61 | } |
| 62 | |
Junio C Hamano | cf2251b | 2006-05-31 15:11:49 -0700 | [diff] [blame] | 63 | static int append_signoff(char *buf, int buf_sz, int at, const char *signoff) |
| 64 | { |
Junio C Hamano | cf2251b | 2006-05-31 15:11:49 -0700 | [diff] [blame] | 65 | static const char signed_off_by[] = "Signed-off-by: "; |
Franck Bui-Huu | fc1c75e | 2006-08-29 13:37:06 +0200 | [diff] [blame] | 66 | int signoff_len = strlen(signoff); |
| 67 | int has_signoff = 0; |
Junio C Hamano | cf2251b | 2006-05-31 15:11:49 -0700 | [diff] [blame] | 68 | char *cp = buf; |
| 69 | |
| 70 | /* Do we have enough space to add it? */ |
Franck Bui-Huu | c35f4c3 | 2006-08-13 11:30:27 -0700 | [diff] [blame] | 71 | if (buf_sz - at <= strlen(signed_off_by) + signoff_len + 3) |
Junio C Hamano | cf2251b | 2006-05-31 15:11:49 -0700 | [diff] [blame] | 72 | return at; |
| 73 | |
| 74 | /* First see if we already have the sign-off by the signer */ |
Franck Bui-Huu | fc1c75e | 2006-08-29 13:37:06 +0200 | [diff] [blame] | 75 | while ((cp = strstr(cp, signed_off_by))) { |
| 76 | |
| 77 | has_signoff = 1; |
| 78 | |
Junio C Hamano | cf2251b | 2006-05-31 15:11:49 -0700 | [diff] [blame] | 79 | cp += strlen(signed_off_by); |
Franck Bui-Huu | fc1c75e | 2006-08-29 13:37:06 +0200 | [diff] [blame] | 80 | if (cp + signoff_len >= buf + at) |
| 81 | break; |
| 82 | if (strncmp(cp, signoff, signoff_len)) |
| 83 | continue; |
| 84 | if (!isspace(cp[signoff_len])) |
| 85 | continue; |
| 86 | /* we already have him */ |
| 87 | return at; |
Junio C Hamano | cf2251b | 2006-05-31 15:11:49 -0700 | [diff] [blame] | 88 | } |
| 89 | |
Franck Bui-Huu | fc1c75e | 2006-08-29 13:37:06 +0200 | [diff] [blame] | 90 | if (!has_signoff) |
| 91 | has_signoff = detect_any_signoff(buf, at); |
| 92 | |
| 93 | if (!has_signoff) |
| 94 | buf[at++] = '\n'; |
Franck Bui-Huu | c35f4c3 | 2006-08-13 11:30:27 -0700 | [diff] [blame] | 95 | |
Junio C Hamano | cf2251b | 2006-05-31 15:11:49 -0700 | [diff] [blame] | 96 | strcpy(buf + at, signed_off_by); |
| 97 | at += strlen(signed_off_by); |
| 98 | strcpy(buf + at, signoff); |
| 99 | at += signoff_len; |
| 100 | buf[at++] = '\n'; |
| 101 | buf[at] = 0; |
| 102 | return at; |
| 103 | } |
| 104 | |
Johannes Schindelin | e00de24 | 2007-02-09 01:43:54 +0100 | [diff] [blame] | 105 | static unsigned int digits_in_number(unsigned int number) |
| 106 | { |
| 107 | unsigned int i = 10, result = 1; |
| 108 | while (i <= number) { |
| 109 | i *= 10; |
| 110 | result++; |
| 111 | } |
| 112 | return result; |
| 113 | } |
| 114 | |
Timo Hirvonen | 39bc9a6 | 2006-06-25 13:54:14 +0300 | [diff] [blame] | 115 | void show_log(struct rev_info *opt, const char *sep) |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 116 | { |
| 117 | static char this_header[16384]; |
Timo Hirvonen | 39bc9a6 | 2006-06-25 13:54:14 +0300 | [diff] [blame] | 118 | struct log_info *log = opt->loginfo; |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 119 | struct commit *commit = log->commit, *parent = log->parent; |
| 120 | int abbrev = opt->diffopt.abbrev; |
| 121 | int abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40; |
Linus Torvalds | a4d34e2 | 2006-04-17 17:43:40 -0700 | [diff] [blame] | 122 | const char *extra; |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 123 | int len; |
Johannes Schindelin | 20ff068 | 2006-06-02 15:21:17 +0200 | [diff] [blame] | 124 | const char *subject = NULL, *extra_headers = opt->extra_headers; |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 125 | |
| 126 | opt->loginfo = NULL; |
| 127 | if (!opt->verbose_header) { |
Junio C Hamano | 74bd902 | 2006-12-16 15:31:25 -0800 | [diff] [blame] | 128 | if (opt->left_right) { |
| 129 | if (commit->object.flags & BOUNDARY) |
| 130 | putchar('-'); |
| 131 | else if (commit->object.flags & SYMMETRIC_LEFT) |
| 132 | putchar('<'); |
| 133 | else |
| 134 | putchar('>'); |
| 135 | } |
Linus Torvalds | c8c893c | 2006-05-03 07:59:00 -0700 | [diff] [blame] | 136 | fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout); |
| 137 | if (opt->parents) |
| 138 | show_parents(commit, abbrev_commit); |
Ryan Anderson | 1dcb692 | 2006-08-07 05:11:23 -0700 | [diff] [blame] | 139 | putchar(opt->diffopt.line_termination); |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 140 | return; |
| 141 | } |
| 142 | |
| 143 | /* |
Linus Torvalds | a4d34e2 | 2006-04-17 17:43:40 -0700 | [diff] [blame] | 144 | * The "oneline" format has several special cases: |
| 145 | * - The pretty-printed commit lacks a newline at the end |
| 146 | * of the buffer, but we do want to make sure that we |
| 147 | * have a newline there. If the separator isn't already |
| 148 | * a newline, add an extra one. |
| 149 | * - unlike other log messages, the one-line format does |
| 150 | * not have an empty line between entries. |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 151 | */ |
Linus Torvalds | a4d34e2 | 2006-04-17 17:43:40 -0700 | [diff] [blame] | 152 | extra = ""; |
| 153 | if (*sep != '\n' && opt->commit_format == CMIT_FMT_ONELINE) |
| 154 | extra = "\n"; |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 155 | if (opt->shown_one && opt->commit_format != CMIT_FMT_ONELINE) |
Linus Torvalds | abd4e22 | 2007-02-07 11:49:56 -0800 | [diff] [blame] | 156 | putchar(opt->diffopt.line_termination); |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 157 | opt->shown_one = 1; |
| 158 | |
| 159 | /* |
| 160 | * Print header line of header.. |
| 161 | */ |
Junio C Hamano | 3eefc18 | 2006-04-18 16:45:27 -0700 | [diff] [blame] | 162 | |
Johannes Schindelin | 596524b | 2006-05-05 04:30:52 +0200 | [diff] [blame] | 163 | if (opt->commit_format == CMIT_FMT_EMAIL) { |
Johannes Schindelin | 698ce6f | 2006-05-20 15:40:29 +0200 | [diff] [blame] | 164 | char *sha1 = sha1_to_hex(commit->object.sha1); |
Johannes Schindelin | 596524b | 2006-05-05 04:30:52 +0200 | [diff] [blame] | 165 | if (opt->total > 0) { |
| 166 | static char buffer[64]; |
| 167 | snprintf(buffer, sizeof(buffer), |
Johannes Schindelin | e00de24 | 2007-02-09 01:43:54 +0100 | [diff] [blame] | 168 | "Subject: [PATCH %0*d/%d] ", |
| 169 | digits_in_number(opt->total), |
Johannes Schindelin | 596524b | 2006-05-05 04:30:52 +0200 | [diff] [blame] | 170 | opt->nr, opt->total); |
| 171 | subject = buffer; |
Johannes Schindelin | 8ac80a5 | 2006-05-05 04:31:29 +0200 | [diff] [blame] | 172 | } else if (opt->total == 0) |
Johannes Schindelin | 596524b | 2006-05-05 04:30:52 +0200 | [diff] [blame] | 173 | subject = "Subject: [PATCH] "; |
Johannes Schindelin | 8ac80a5 | 2006-05-05 04:31:29 +0200 | [diff] [blame] | 174 | else |
| 175 | subject = "Subject: "; |
| 176 | |
Johannes Schindelin | 698ce6f | 2006-05-20 15:40:29 +0200 | [diff] [blame] | 177 | printf("From %s Mon Sep 17 00:00:00 2001\n", sha1); |
Josh Triplett | d1566f7 | 2006-07-14 17:48:51 -0700 | [diff] [blame] | 178 | if (opt->message_id) |
| 179 | printf("Message-Id: <%s>\n", opt->message_id); |
| 180 | if (opt->ref_message_id) |
| 181 | printf("In-Reply-To: <%s>\nReferences: <%s>\n", |
| 182 | opt->ref_message_id, opt->ref_message_id); |
Johannes Schindelin | 698ce6f | 2006-05-20 15:40:29 +0200 | [diff] [blame] | 183 | if (opt->mime_boundary) { |
| 184 | static char subject_buffer[1024]; |
| 185 | static char buffer[1024]; |
| 186 | snprintf(subject_buffer, sizeof(subject_buffer) - 1, |
Johannes Schindelin | 20ff068 | 2006-06-02 15:21:17 +0200 | [diff] [blame] | 187 | "%s" |
Johannes Schindelin | 698ce6f | 2006-05-20 15:40:29 +0200 | [diff] [blame] | 188 | "MIME-Version: 1.0\n" |
Junio C Hamano | 33ee4cf | 2007-03-04 16:08:04 -0800 | [diff] [blame] | 189 | "Content-Type: multipart/mixed;" |
Johannes Schindelin | 698ce6f | 2006-05-20 15:40:29 +0200 | [diff] [blame] | 190 | " boundary=\"%s%s\"\n" |
| 191 | "\n" |
| 192 | "This is a multi-part message in MIME " |
| 193 | "format.\n" |
| 194 | "--%s%s\n" |
| 195 | "Content-Type: text/plain; " |
| 196 | "charset=UTF-8; format=fixed\n" |
| 197 | "Content-Transfer-Encoding: 8bit\n\n", |
Johannes Schindelin | 20ff068 | 2006-06-02 15:21:17 +0200 | [diff] [blame] | 198 | extra_headers ? extra_headers : "", |
Johannes Schindelin | 698ce6f | 2006-05-20 15:40:29 +0200 | [diff] [blame] | 199 | mime_boundary_leader, opt->mime_boundary, |
| 200 | mime_boundary_leader, opt->mime_boundary); |
Johannes Schindelin | 20ff068 | 2006-06-02 15:21:17 +0200 | [diff] [blame] | 201 | extra_headers = subject_buffer; |
Johannes Schindelin | 698ce6f | 2006-05-20 15:40:29 +0200 | [diff] [blame] | 202 | |
| 203 | snprintf(buffer, sizeof(buffer) - 1, |
| 204 | "--%s%s\n" |
Junio C Hamano | 33ee4cf | 2007-03-04 16:08:04 -0800 | [diff] [blame] | 205 | "Content-Type: text/x-patch;" |
Johannes Schindelin | 698ce6f | 2006-05-20 15:40:29 +0200 | [diff] [blame] | 206 | " name=\"%s.diff\"\n" |
| 207 | "Content-Transfer-Encoding: 8bit\n" |
Junio C Hamano | 33ee4cf | 2007-03-04 16:08:04 -0800 | [diff] [blame] | 208 | "Content-Disposition: %s;" |
Johannes Schindelin | 698ce6f | 2006-05-20 15:40:29 +0200 | [diff] [blame] | 209 | " filename=\"%s.diff\"\n\n", |
| 210 | mime_boundary_leader, opt->mime_boundary, |
Johannes Schindelin | c112f68 | 2007-03-04 00:12:06 +0100 | [diff] [blame] | 211 | sha1, |
| 212 | opt->no_inline ? "attachment" : "inline", |
| 213 | sha1); |
Johannes Schindelin | 698ce6f | 2006-05-20 15:40:29 +0200 | [diff] [blame] | 214 | opt->diffopt.stat_sep = buffer; |
| 215 | } |
Johannes Schindelin | e52a5de | 2007-02-23 01:35:03 +0100 | [diff] [blame] | 216 | } else if (opt->commit_format != CMIT_FMT_USERFORMAT) { |
Junio C Hamano | 74bd902 | 2006-12-16 15:31:25 -0800 | [diff] [blame] | 217 | fputs(diff_get_color(opt->diffopt.color_diff, DIFF_COMMIT), |
| 218 | stdout); |
| 219 | if (opt->commit_format != CMIT_FMT_ONELINE) |
| 220 | fputs("commit ", stdout); |
| 221 | if (opt->left_right) { |
| 222 | if (commit->object.flags & BOUNDARY) |
| 223 | putchar('-'); |
| 224 | else if (commit->object.flags & SYMMETRIC_LEFT) |
| 225 | putchar('<'); |
| 226 | else |
| 227 | putchar('>'); |
| 228 | } |
| 229 | fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), |
| 230 | stdout); |
Junio C Hamano | c66b6c0 | 2006-05-06 14:42:08 -0700 | [diff] [blame] | 231 | if (opt->parents) |
| 232 | show_parents(commit, abbrev_commit); |
Junio C Hamano | 73f0a15 | 2006-05-24 12:19:47 -0700 | [diff] [blame] | 233 | if (parent) |
Junio C Hamano | 3eefc18 | 2006-04-18 16:45:27 -0700 | [diff] [blame] | 234 | printf(" (from %s)", |
| 235 | diff_unique_abbrev(parent->object.sha1, |
| 236 | abbrev_commit)); |
Jeff King | ce43697 | 2006-07-23 05:24:18 -0400 | [diff] [blame] | 237 | printf("%s", |
| 238 | diff_get_color(opt->diffopt.color_diff, DIFF_RESET)); |
Johannes Schindelin | e557667 | 2006-07-24 14:41:41 +0200 | [diff] [blame] | 239 | putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n'); |
Nicolas Pitre | 903b45f | 2007-01-27 22:40:36 -0500 | [diff] [blame] | 240 | if (opt->reflog_info) { |
Junio C Hamano | 4d12a47 | 2007-01-20 00:51:41 -0800 | [diff] [blame] | 241 | show_reflog_message(opt->reflog_info, |
Johannes Schindelin | 4e244cb | 2007-02-08 21:58:33 +0100 | [diff] [blame] | 242 | opt->commit_format == CMIT_FMT_ONELINE, |
| 243 | opt->relative_date); |
Nicolas Pitre | 903b45f | 2007-01-27 22:40:36 -0500 | [diff] [blame] | 244 | if (opt->commit_format == CMIT_FMT_ONELINE) { |
| 245 | printf("%s", sep); |
| 246 | return; |
| 247 | } |
| 248 | } |
Junio C Hamano | 3eefc18 | 2006-04-18 16:45:27 -0700 | [diff] [blame] | 249 | } |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 250 | |
| 251 | /* |
| 252 | * And then the pretty-printed message itself |
| 253 | */ |
Jonas Fonseca | 3dfb927 | 2006-08-28 15:52:13 +0200 | [diff] [blame] | 254 | len = pretty_print_commit(opt->commit_format, commit, ~0u, this_header, |
| 255 | sizeof(this_header), abbrev, subject, |
| 256 | extra_headers, opt->relative_date); |
Junio C Hamano | cf2251b | 2006-05-31 15:11:49 -0700 | [diff] [blame] | 257 | |
| 258 | if (opt->add_signoff) |
| 259 | len = append_signoff(this_header, sizeof(this_header), len, |
| 260 | opt->add_signoff); |
Linus Torvalds | a4d34e2 | 2006-04-17 17:43:40 -0700 | [diff] [blame] | 261 | printf("%s%s%s", this_header, extra, sep); |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 262 | } |
| 263 | |
Linus Torvalds | cd2bdc5 | 2006-04-14 16:52:13 -0700 | [diff] [blame] | 264 | int log_tree_diff_flush(struct rev_info *opt) |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 265 | { |
| 266 | diffcore_std(&opt->diffopt); |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 267 | |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 268 | if (diff_queue_is_empty()) { |
| 269 | int saved_fmt = opt->diffopt.output_format; |
| 270 | opt->diffopt.output_format = DIFF_FORMAT_NO_OUTPUT; |
| 271 | diff_flush(&opt->diffopt); |
| 272 | opt->diffopt.output_format = saved_fmt; |
| 273 | return 0; |
| 274 | } |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 275 | |
Junio C Hamano | 3969cf7 | 2006-06-27 15:08:19 -0700 | [diff] [blame] | 276 | if (opt->loginfo && !opt->no_commit_id) { |
| 277 | /* When showing a verbose header (i.e. log message), |
| 278 | * and not in --pretty=oneline format, we would want |
| 279 | * an extra newline between the end of log and the |
| 280 | * output for readability. |
| 281 | */ |
Timo Hirvonen | 39bc9a6 | 2006-06-25 13:54:14 +0300 | [diff] [blame] | 282 | show_log(opt, opt->diffopt.msg_sep); |
Junio C Hamano | 3969cf7 | 2006-06-27 15:08:19 -0700 | [diff] [blame] | 283 | if (opt->verbose_header && |
| 284 | opt->commit_format != CMIT_FMT_ONELINE) { |
| 285 | int pch = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_PATCH; |
| 286 | if ((pch & opt->diffopt.output_format) == pch) |
Linus Torvalds | abd4e22 | 2007-02-07 11:49:56 -0800 | [diff] [blame] | 287 | printf("---"); |
| 288 | putchar('\n'); |
Junio C Hamano | 3969cf7 | 2006-06-27 15:08:19 -0700 | [diff] [blame] | 289 | } |
| 290 | } |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 291 | diff_flush(&opt->diffopt); |
| 292 | return 1; |
| 293 | } |
| 294 | |
Linus Torvalds | cd2bdc5 | 2006-04-14 16:52:13 -0700 | [diff] [blame] | 295 | static int do_diff_combined(struct rev_info *opt, struct commit *commit) |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 296 | { |
| 297 | unsigned const char *sha1 = commit->object.sha1; |
| 298 | |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 299 | diff_tree_combined_merge(sha1, opt->dense_combined_merges, opt); |
| 300 | return !opt->loginfo; |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 301 | } |
| 302 | |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 303 | /* |
| 304 | * Show the diff of a commit. |
| 305 | * |
| 306 | * Return true if we printed any log info messages |
| 307 | */ |
| 308 | static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log_info *log) |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 309 | { |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 310 | int showed_log; |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 311 | struct commit_list *parents; |
| 312 | unsigned const char *sha1 = commit->object.sha1; |
| 313 | |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 314 | if (!opt->diff) |
| 315 | return 0; |
| 316 | |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 317 | /* Root commit? */ |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 318 | parents = commit->parents; |
| 319 | if (!parents) { |
Rene Scharfe | 2b60356 | 2006-10-26 18:52:39 +0200 | [diff] [blame] | 320 | if (opt->show_root_diff) { |
| 321 | diff_root_tree_sha1(sha1, "", &opt->diffopt); |
| 322 | log_tree_diff_flush(opt); |
| 323 | } |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 324 | return !opt->loginfo; |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 325 | } |
| 326 | |
| 327 | /* More than one parent? */ |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 328 | if (parents && parents->next) { |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 329 | if (opt->ignore_merges) |
| 330 | return 0; |
| 331 | else if (opt->combine_merges) |
| 332 | return do_diff_combined(opt, commit); |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 333 | |
| 334 | /* If we show individual diffs, show the parent info */ |
| 335 | log->parent = parents->item; |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 336 | } |
| 337 | |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 338 | showed_log = 0; |
| 339 | for (;;) { |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 340 | struct commit *parent = parents->item; |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 341 | |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 342 | diff_tree_sha1(parent->object.sha1, sha1, "", &opt->diffopt); |
| 343 | log_tree_diff_flush(opt); |
| 344 | |
| 345 | showed_log |= !opt->loginfo; |
| 346 | |
| 347 | /* Set up the log info for the next parent, if any.. */ |
| 348 | parents = parents->next; |
| 349 | if (!parents) |
| 350 | break; |
| 351 | log->parent = parents->item; |
| 352 | opt->loginfo = log; |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 353 | } |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 354 | return showed_log; |
| 355 | } |
| 356 | |
| 357 | int log_tree_commit(struct rev_info *opt, struct commit *commit) |
| 358 | { |
| 359 | struct log_info log; |
Junio C Hamano | 3eefc18 | 2006-04-18 16:45:27 -0700 | [diff] [blame] | 360 | int shown; |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 361 | |
| 362 | log.commit = commit; |
| 363 | log.parent = NULL; |
| 364 | opt->loginfo = &log; |
| 365 | |
Junio C Hamano | 3eefc18 | 2006-04-18 16:45:27 -0700 | [diff] [blame] | 366 | shown = log_tree_diff(opt, commit, &log); |
| 367 | if (!shown && opt->loginfo && opt->always_show_header) { |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 368 | log.parent = NULL; |
Timo Hirvonen | 39bc9a6 | 2006-06-25 13:54:14 +0300 | [diff] [blame] | 369 | show_log(opt, ""); |
Junio C Hamano | 3eefc18 | 2006-04-18 16:45:27 -0700 | [diff] [blame] | 370 | shown = 1; |
Linus Torvalds | 9153983 | 2006-04-17 11:59:32 -0700 | [diff] [blame] | 371 | } |
| 372 | opt->loginfo = NULL; |
Junio C Hamano | 3eefc18 | 2006-04-18 16:45:27 -0700 | [diff] [blame] | 373 | return shown; |
Junio C Hamano | 5f1c3f0 | 2006-04-09 01:11:11 -0700 | [diff] [blame] | 374 | } |