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