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