Fix up docs where "--" isn't displayed correctly.
[git] / commit.c
1 #include "cache.h"
2 #include "tag.h"
3 #include "commit.h"
4
5 int save_commit_buffer = 1;
6
7 struct sort_node
8 {
9         /*
10          * the number of children of the associated commit
11          * that also occur in the list being sorted.
12          */
13         unsigned int indegree;
14
15         /*
16          * reference to original list item that we will re-use
17          * on output.
18          */
19         struct commit_list * list_item;
20
21 };
22
23 const char *commit_type = "commit";
24
25 enum cmit_fmt get_commit_format(const char *arg)
26 {
27         if (!*arg)
28                 return CMIT_FMT_DEFAULT;
29         if (!strcmp(arg, "=raw"))
30                 return CMIT_FMT_RAW;
31         if (!strcmp(arg, "=medium"))
32                 return CMIT_FMT_MEDIUM;
33         if (!strcmp(arg, "=short"))
34                 return CMIT_FMT_SHORT;
35         if (!strcmp(arg, "=full"))
36                 return CMIT_FMT_FULL;
37         if (!strcmp(arg, "=fuller"))
38                 return CMIT_FMT_FULLER;
39         if (!strcmp(arg, "=oneline"))
40                 return CMIT_FMT_ONELINE;
41         die("invalid --pretty format");
42 }
43
44 static struct commit *check_commit(struct object *obj,
45                                    const unsigned char *sha1,
46                                    int quiet)
47 {
48         if (obj->type != commit_type) {
49                 if (!quiet)
50                         error("Object %s is a %s, not a commit",
51                               sha1_to_hex(sha1), obj->type);
52                 return NULL;
53         }
54         return (struct commit *) obj;
55 }
56
57 struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
58                                               int quiet)
59 {
60         struct object *obj = deref_tag(parse_object(sha1), NULL, 0);
61
62         if (!obj)
63                 return NULL;
64         return check_commit(obj, sha1, quiet);
65 }
66
67 struct commit *lookup_commit_reference(const unsigned char *sha1)
68 {
69         return lookup_commit_reference_gently(sha1, 0);
70 }
71
72 struct commit *lookup_commit(const unsigned char *sha1)
73 {
74         struct object *obj = lookup_object(sha1);
75         if (!obj) {
76                 struct commit *ret = xcalloc(1, sizeof(struct commit));
77                 created_object(sha1, &ret->object);
78                 ret->object.type = commit_type;
79                 return ret;
80         }
81         if (!obj->type)
82                 obj->type = commit_type;
83         return check_commit(obj, sha1, 0);
84 }
85
86 static unsigned long parse_commit_date(const char *buf)
87 {
88         unsigned long date;
89
90         if (memcmp(buf, "author", 6))
91                 return 0;
92         while (*buf++ != '\n')
93                 /* nada */;
94         if (memcmp(buf, "committer", 9))
95                 return 0;
96         while (*buf++ != '>')
97                 /* nada */;
98         date = strtoul(buf, NULL, 10);
99         if (date == ULONG_MAX)
100                 date = 0;
101         return date;
102 }
103
104 static struct commit_graft **commit_graft;
105 static int commit_graft_alloc, commit_graft_nr;
106
107 static int commit_graft_pos(const unsigned char *sha1)
108 {
109         int lo, hi;
110         lo = 0;
111         hi = commit_graft_nr;
112         while (lo < hi) {
113                 int mi = (lo + hi) / 2;
114                 struct commit_graft *graft = commit_graft[mi];
115                 int cmp = memcmp(sha1, graft->sha1, 20);
116                 if (!cmp)
117                         return mi;
118                 if (cmp < 0)
119                         hi = mi;
120                 else
121                         lo = mi + 1;
122         }
123         return -lo - 1;
124 }
125
126 int register_commit_graft(struct commit_graft *graft, int ignore_dups)
127 {
128         int pos = commit_graft_pos(graft->sha1);
129         
130         if (0 <= pos) {
131                 if (ignore_dups)
132                         free(graft);
133                 else {
134                         free(commit_graft[pos]);
135                         commit_graft[pos] = graft;
136                 }
137                 return 1;
138         }
139         pos = -pos - 1;
140         if (commit_graft_alloc <= ++commit_graft_nr) {
141                 commit_graft_alloc = alloc_nr(commit_graft_alloc);
142                 commit_graft = xrealloc(commit_graft,
143                                         sizeof(*commit_graft) *
144                                         commit_graft_alloc);
145         }
146         if (pos < commit_graft_nr)
147                 memmove(commit_graft + pos + 1,
148                         commit_graft + pos,
149                         (commit_graft_nr - pos - 1) *
150                         sizeof(*commit_graft));
151         commit_graft[pos] = graft;
152         return 0;
153 }
154
155 struct commit_graft *read_graft_line(char *buf, int len)
156 {
157         /* The format is just "Commit Parent1 Parent2 ...\n" */
158         int i;
159         struct commit_graft *graft = NULL;
160
161         if (buf[len-1] == '\n')
162                 buf[--len] = 0;
163         if (buf[0] == '#' || buf[0] == '\0')
164                 return NULL;
165         if ((len + 1) % 41) {
166         bad_graft_data:
167                 error("bad graft data: %s", buf);
168                 free(graft);
169                 return NULL;
170         }
171         i = (len + 1) / 41 - 1;
172         graft = xmalloc(sizeof(*graft) + 20 * i);
173         graft->nr_parent = i;
174         if (get_sha1_hex(buf, graft->sha1))
175                 goto bad_graft_data;
176         for (i = 40; i < len; i += 41) {
177                 if (buf[i] != ' ')
178                         goto bad_graft_data;
179                 if (get_sha1_hex(buf + i + 1, graft->parent[i/41]))
180                         goto bad_graft_data;
181         }
182         return graft;
183 }
184
185 int read_graft_file(const char *graft_file)
186 {
187         FILE *fp = fopen(graft_file, "r");
188         char buf[1024];
189         if (!fp)
190                 return -1;
191         while (fgets(buf, sizeof(buf), fp)) {
192                 /* The format is just "Commit Parent1 Parent2 ...\n" */
193                 int len = strlen(buf);
194                 struct commit_graft *graft = read_graft_line(buf, len);
195                 if (!graft)
196                         continue;
197                 if (register_commit_graft(graft, 1))
198                         error("duplicate graft data: %s", buf);
199         }
200         fclose(fp);
201         return 0;
202 }
203
204 static void prepare_commit_graft(void)
205 {
206         static int commit_graft_prepared;
207         char *graft_file;
208
209         if (commit_graft_prepared)
210                 return;
211         graft_file = get_graft_file();
212         read_graft_file(graft_file);
213         commit_graft_prepared = 1;
214 }
215
216 static struct commit_graft *lookup_commit_graft(const unsigned char *sha1)
217 {
218         int pos;
219         prepare_commit_graft();
220         pos = commit_graft_pos(sha1);
221         if (pos < 0)
222                 return NULL;
223         return commit_graft[pos];
224 }
225
226 int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
227 {
228         char *bufptr = buffer;
229         unsigned char parent[20];
230         struct commit_list **pptr;
231         struct commit_graft *graft;
232         unsigned n_refs = 0;
233
234         if (item->object.parsed)
235                 return 0;
236         item->object.parsed = 1;
237         if (memcmp(bufptr, "tree ", 5))
238                 return error("bogus commit object %s", sha1_to_hex(item->object.sha1));
239         if (get_sha1_hex(bufptr + 5, parent) < 0)
240                 return error("bad tree pointer in commit %s",
241                              sha1_to_hex(item->object.sha1));
242         item->tree = lookup_tree(parent);
243         if (item->tree)
244                 n_refs++;
245         bufptr += 46; /* "tree " + "hex sha1" + "\n" */
246         pptr = &item->parents;
247
248         graft = lookup_commit_graft(item->object.sha1);
249         while (!memcmp(bufptr, "parent ", 7)) {
250                 struct commit *new_parent;
251
252                 if (get_sha1_hex(bufptr + 7, parent) || bufptr[47] != '\n')
253                         return error("bad parents in commit %s", sha1_to_hex(item->object.sha1));
254                 bufptr += 48;
255                 if (graft)
256                         continue;
257                 new_parent = lookup_commit(parent);
258                 if (new_parent) {
259                         pptr = &commit_list_insert(new_parent, pptr)->next;
260                         n_refs++;
261                 }
262         }
263         if (graft) {
264                 int i;
265                 struct commit *new_parent;
266                 for (i = 0; i < graft->nr_parent; i++) {
267                         new_parent = lookup_commit(graft->parent[i]);
268                         if (!new_parent)
269                                 continue;
270                         pptr = &commit_list_insert(new_parent, pptr)->next;
271                         n_refs++;
272                 }
273         }
274         item->date = parse_commit_date(bufptr);
275
276         if (track_object_refs) {
277                 unsigned i = 0;
278                 struct commit_list *p;
279                 struct object_refs *refs = alloc_object_refs(n_refs);
280                 if (item->tree)
281                         refs->ref[i++] = &item->tree->object;
282                 for (p = item->parents; p; p = p->next)
283                         refs->ref[i++] = &p->item->object;
284                 set_object_refs(&item->object, refs);
285         }
286
287         return 0;
288 }
289
290 int parse_commit(struct commit *item)
291 {
292         char type[20];
293         void *buffer;
294         unsigned long size;
295         int ret;
296
297         if (item->object.parsed)
298                 return 0;
299         buffer = read_sha1_file(item->object.sha1, type, &size);
300         if (!buffer)
301                 return error("Could not read %s",
302                              sha1_to_hex(item->object.sha1));
303         if (strcmp(type, commit_type)) {
304                 free(buffer);
305                 return error("Object %s not a commit",
306                              sha1_to_hex(item->object.sha1));
307         }
308         ret = parse_commit_buffer(item, buffer, size);
309         if (save_commit_buffer && !ret) {
310                 item->buffer = buffer;
311                 return 0;
312         }
313         free(buffer);
314         return ret;
315 }
316
317 struct commit_list *commit_list_insert(struct commit *item, struct commit_list **list_p)
318 {
319         struct commit_list *new_list = xmalloc(sizeof(struct commit_list));
320         new_list->item = item;
321         new_list->next = *list_p;
322         *list_p = new_list;
323         return new_list;
324 }
325
326 void free_commit_list(struct commit_list *list)
327 {
328         while (list) {
329                 struct commit_list *temp = list;
330                 list = temp->next;
331                 free(temp);
332         }
333 }
334
335 struct commit_list * insert_by_date(struct commit *item, struct commit_list **list)
336 {
337         struct commit_list **pp = list;
338         struct commit_list *p;
339         while ((p = *pp) != NULL) {
340                 if (p->item->date < item->date) {
341                         break;
342                 }
343                 pp = &p->next;
344         }
345         return commit_list_insert(item, pp);
346 }
347
348         
349 void sort_by_date(struct commit_list **list)
350 {
351         struct commit_list *ret = NULL;
352         while (*list) {
353                 insert_by_date((*list)->item, &ret);
354                 *list = (*list)->next;
355         }
356         *list = ret;
357 }
358
359 struct commit *pop_most_recent_commit(struct commit_list **list,
360                                       unsigned int mark)
361 {
362         struct commit *ret = (*list)->item;
363         struct commit_list *parents = ret->parents;
364         struct commit_list *old = *list;
365
366         *list = (*list)->next;
367         free(old);
368
369         while (parents) {
370                 struct commit *commit = parents->item;
371                 parse_commit(commit);
372                 if (!(commit->object.flags & mark)) {
373                         commit->object.flags |= mark;
374                         insert_by_date(commit, list);
375                 }
376                 parents = parents->next;
377         }
378         return ret;
379 }
380
381 void clear_commit_marks(struct commit *commit, unsigned int mark)
382 {
383         struct commit_list *parents;
384
385         parents = commit->parents;
386         commit->object.flags &= ~mark;
387         while (parents) {
388                 struct commit *parent = parents->item;
389                 if (parent && parent->object.parsed &&
390                     (parent->object.flags & mark))
391                         clear_commit_marks(parent, mark);
392                 parents = parents->next;
393         }
394 }
395
396 /*
397  * Generic support for pretty-printing the header
398  */
399 static int get_one_line(const char *msg, unsigned long len)
400 {
401         int ret = 0;
402
403         while (len--) {
404                 char c = *msg++;
405                 if (!c)
406                         break;
407                 ret++;
408                 if (c == '\n')
409                         break;
410         }
411         return ret;
412 }
413
414 static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf, const char *line)
415 {
416         char *date;
417         int namelen;
418         unsigned long time;
419         int tz, ret;
420         const char *filler = "    ";
421
422         if (fmt == CMIT_FMT_ONELINE)
423                 return 0;
424         date = strchr(line, '>');
425         if (!date)
426                 return 0;
427         namelen = ++date - line;
428         time = strtoul(date, &date, 10);
429         tz = strtol(date, NULL, 10);
430
431         ret = sprintf(buf, "%s: %.*s%.*s\n", what,
432                       (fmt == CMIT_FMT_FULLER) ? 4 : 0,
433                       filler, namelen, line);
434         switch (fmt) {
435         case CMIT_FMT_MEDIUM:
436                 ret += sprintf(buf + ret, "Date:   %s\n", show_date(time, tz));
437                 break;
438         case CMIT_FMT_FULLER:
439                 ret += sprintf(buf + ret, "%sDate: %s\n", what, show_date(time, tz));
440                 break;
441         default:
442                 /* notin' */
443                 break;
444         }
445         return ret;
446 }
447
448 static int is_empty_line(const char *line, int len)
449 {
450         while (len && isspace(line[len-1]))
451                 len--;
452         return !len;
453 }
454
455 static int add_merge_info(enum cmit_fmt fmt, char *buf, const struct commit *commit, int abbrev)
456 {
457         struct commit_list *parent = commit->parents;
458         int offset;
459
460         if ((fmt == CMIT_FMT_ONELINE) || !parent || !parent->next)
461                 return 0;
462
463         offset = sprintf(buf, "Merge:");
464
465         while (parent) {
466                 struct commit *p = parent->item;
467                 const char *hex = abbrev
468                         ? find_unique_abbrev(p->object.sha1, abbrev)
469                         : sha1_to_hex(p->object.sha1);
470                 char *dots = (abbrev && strlen(hex) != 40) ? "..." : "";
471                 parent = parent->next;
472
473                 offset += sprintf(buf + offset, " %s%s", hex, dots);
474         }
475         buf[offset++] = '\n';
476         return offset;
477 }
478
479 unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit, unsigned long len, char *buf, unsigned long space, int abbrev)
480 {
481         int hdr = 1, body = 0;
482         unsigned long offset = 0;
483         int indent = (fmt == CMIT_FMT_ONELINE) ? 0 : 4;
484         int parents_shown = 0;
485         const char *msg = commit->buffer;
486
487         for (;;) {
488                 const char *line = msg;
489                 int linelen = get_one_line(msg, len);
490
491                 if (!linelen)
492                         break;
493
494                 /*
495                  * We want some slop for indentation and a possible
496                  * final "...". Thus the "+ 20".
497                  */
498                 if (offset + linelen + 20 > space) {
499                         memcpy(buf + offset, "    ...\n", 8);
500                         offset += 8;
501                         break;
502                 }
503
504                 msg += linelen;
505                 len -= linelen;
506                 if (hdr) {
507                         if (linelen == 1) {
508                                 hdr = 0;
509                                 if (fmt != CMIT_FMT_ONELINE)
510                                         buf[offset++] = '\n';
511                                 continue;
512                         }
513                         if (fmt == CMIT_FMT_RAW) {
514                                 memcpy(buf + offset, line, linelen);
515                                 offset += linelen;
516                                 continue;
517                         }
518                         if (!memcmp(line, "parent ", 7)) {
519                                 if (linelen != 48)
520                                         die("bad parent line in commit");
521                                 continue;
522                         }
523
524                         if (!parents_shown) {
525                                 offset += add_merge_info(fmt, buf + offset,
526                                                          commit, abbrev);
527                                 parents_shown = 1;
528                                 continue;
529                         }
530                         /*
531                          * MEDIUM == DEFAULT shows only author with dates.
532                          * FULL shows both authors but not dates.
533                          * FULLER shows both authors and dates.
534                          */
535                         if (!memcmp(line, "author ", 7))
536                                 offset += add_user_info("Author", fmt,
537                                                         buf + offset,
538                                                         line + 7);
539                         if (!memcmp(line, "committer ", 10) &&
540                             (fmt == CMIT_FMT_FULL || fmt == CMIT_FMT_FULLER))
541                                 offset += add_user_info("Commit", fmt,
542                                                         buf + offset,
543                                                         line + 10);
544                         continue;
545                 }
546
547                 if (is_empty_line(line, linelen)) {
548                         if (!body)
549                                 continue;
550                         if (fmt == CMIT_FMT_SHORT)
551                                 break;
552                 } else {
553                         body = 1;
554                 }
555
556                 memset(buf + offset, ' ', indent);
557                 memcpy(buf + offset + indent, line, linelen);
558                 offset += linelen + indent;
559                 if (fmt == CMIT_FMT_ONELINE)
560                         break;
561         }
562         while (offset && isspace(buf[offset-1]))
563                 offset--;
564         /* Make sure there is an EOLN for the non-oneline case */
565         if (fmt != CMIT_FMT_ONELINE)
566                 buf[offset++] = '\n';
567         buf[offset] = '\0';
568         return offset;
569 }
570
571 struct commit *pop_commit(struct commit_list **stack)
572 {
573         struct commit_list *top = *stack;
574         struct commit *item = top ? top->item : NULL;
575
576         if (top) {
577                 *stack = top->next;
578                 free(top);
579         }
580         return item;
581 }
582
583 int count_parents(struct commit * commit)
584 {
585         int count = 0;
586         struct commit_list * parents = commit->parents;
587         for (count=0;parents; parents=parents->next,count++)
588           ;
589         return count;
590 }
591
592 void topo_sort_default_setter(struct commit *c, void *data)
593 {
594         c->object.util = data;
595 }
596
597 void *topo_sort_default_getter(struct commit *c)
598 {
599         return c->object.util;
600 }
601
602 /*
603  * Performs an in-place topological sort on the list supplied.
604  */
605 void sort_in_topological_order(struct commit_list ** list, int lifo)
606 {
607         sort_in_topological_order_fn(list, lifo, topo_sort_default_setter,
608                                      topo_sort_default_getter);
609 }
610
611 void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
612                                   topo_sort_set_fn_t setter,
613                                   topo_sort_get_fn_t getter)
614 {
615         struct commit_list * next = *list;
616         struct commit_list * work = NULL, **insert;
617         struct commit_list ** pptr = list;
618         struct sort_node * nodes;
619         struct sort_node * next_nodes;
620         int count = 0;
621
622         /* determine the size of the list */
623         while (next) {
624                 next = next->next;
625                 count++;
626         }
627         
628         if (!count)
629                 return;
630         /* allocate an array to help sort the list */
631         nodes = xcalloc(count, sizeof(*nodes));
632         /* link the list to the array */
633         next_nodes = nodes;
634         next=*list;
635         while (next) {
636                 next_nodes->list_item = next;
637                 setter(next->item, next_nodes);
638                 next_nodes++;
639                 next = next->next;
640         }
641         /* update the indegree */
642         next=*list;
643         while (next) {
644                 struct commit_list * parents = next->item->parents;
645                 while (parents) {
646                         struct commit * parent=parents->item;
647                         struct sort_node * pn = (struct sort_node *) getter(parent);
648
649                         if (pn)
650                                 pn->indegree++;
651                         parents=parents->next;
652                 }
653                 next=next->next;
654         }
655         /* 
656          * find the tips
657          *
658          * tips are nodes not reachable from any other node in the list 
659          * 
660          * the tips serve as a starting set for the work queue.
661          */
662         next=*list;
663         insert = &work;
664         while (next) {
665                 struct sort_node * node = (struct sort_node *) getter(next->item);
666
667                 if (node->indegree == 0) {
668                         insert = &commit_list_insert(next->item, insert)->next;
669                 }
670                 next=next->next;
671         }
672
673         /* process the list in topological order */
674         if (!lifo)
675                 sort_by_date(&work);
676         while (work) {
677                 struct commit * work_item = pop_commit(&work);
678                 struct sort_node * work_node = (struct sort_node *) getter(work_item);
679                 struct commit_list * parents = work_item->parents;
680
681                 while (parents) {
682                         struct commit * parent=parents->item;
683                         struct sort_node * pn = (struct sort_node *) getter(parent);
684
685                         if (pn) {
686                                 /*
687                                  * parents are only enqueued for emission 
688                                  * when all their children have been emitted thereby
689                                  * guaranteeing topological order.
690                                  */
691                                 pn->indegree--;
692                                 if (!pn->indegree) {
693                                         if (!lifo)
694                                                 insert_by_date(parent, &work);
695                                         else
696                                                 commit_list_insert(parent, &work);
697                                 }
698                         }
699                         parents=parents->next;
700                 }
701                 /*
702                  * work_item is a commit all of whose children
703                  * have already been emitted. we can emit it now.
704                  */
705                 *pptr = work_node->list_item;
706                 pptr = &(*pptr)->next;
707                 *pptr = NULL;
708                 setter(work_item, NULL);
709         }
710         free(nodes);
711 }