cvsserver: add notes on how to get a checkout under Eclipse
[git.git] / rev-list.c
1 #include "cache.h"
2 #include "refs.h"
3 #include "tag.h"
4 #include "commit.h"
5 #include "tree.h"
6 #include "blob.h"
7 #include "epoch.h"
8 #include "diff.h"
9 #include "revision.h"
10
11 /* bits #0 and #1 in revision.h */
12
13 #define COUNTED         (1u << 2)
14 #define SHOWN           (1u << 3)
15 #define TREECHANGE      (1u << 4)
16 #define TMP_MARK        (1u << 5) /* for isolated cases; clean after use */
17
18 static const char rev_list_usage[] =
19 "git-rev-list [OPTION] <commit-id>... [ -- paths... ]\n"
20 "  limiting output:\n"
21 "    --max-count=nr\n"
22 "    --max-age=epoch\n"
23 "    --min-age=epoch\n"
24 "    --sparse\n"
25 "    --no-merges\n"
26 "    --remove-empty\n"
27 "    --all\n"
28 "  ordering output:\n"
29 "    --merge-order [ --show-breaks ]\n"
30 "    --topo-order\n"
31 "    --date-order\n"
32 "  formatting output:\n"
33 "    --parents\n"
34 "    --objects | --objects-edge\n"
35 "    --unpacked\n"
36 "    --header | --pretty\n"
37 "    --abbrev=nr | --no-abbrev\n"
38 "  special purpose:\n"
39 "    --bisect"
40 ;
41
42 struct rev_info revs;
43
44 static int bisect_list = 0;
45 static int verbose_header = 0;
46 static int abbrev = DEFAULT_ABBREV;
47 static int show_parents = 0;
48 static int hdr_termination = 0;
49 static const char *commit_prefix = "";
50 static enum cmit_fmt commit_format = CMIT_FMT_RAW;
51 static int merge_order = 0;
52 static int show_breaks = 0;
53 static int stop_traversal = 0;
54 static int no_merges = 0;
55
56 static void show_commit(struct commit *commit)
57 {
58         commit->object.flags |= SHOWN;
59         if (show_breaks) {
60                 commit_prefix = "| ";
61                 if (commit->object.flags & DISCONTINUITY) {
62                         commit_prefix = "^ ";     
63                 } else if (commit->object.flags & BOUNDARY) {
64                         commit_prefix = "= ";
65                 } 
66         }                       
67         printf("%s%s", commit_prefix, sha1_to_hex(commit->object.sha1));
68         if (show_parents) {
69                 struct commit_list *parents = commit->parents;
70                 while (parents) {
71                         struct object *o = &(parents->item->object);
72                         parents = parents->next;
73                         if (o->flags & TMP_MARK)
74                                 continue;
75                         printf(" %s", sha1_to_hex(o->sha1));
76                         o->flags |= TMP_MARK;
77                 }
78                 /* TMP_MARK is a general purpose flag that can
79                  * be used locally, but the user should clean
80                  * things up after it is done with them.
81                  */
82                 for (parents = commit->parents;
83                      parents;
84                      parents = parents->next)
85                         parents->item->object.flags &= ~TMP_MARK;
86         }
87         if (commit_format == CMIT_FMT_ONELINE)
88                 putchar(' ');
89         else
90                 putchar('\n');
91
92         if (verbose_header) {
93                 static char pretty_header[16384];
94                 pretty_print_commit(commit_format, commit, ~0, pretty_header, sizeof(pretty_header), abbrev);
95                 printf("%s%c", pretty_header, hdr_termination);
96         }
97         fflush(stdout);
98 }
99
100 static int rewrite_one(struct commit **pp)
101 {
102         for (;;) {
103                 struct commit *p = *pp;
104                 if (p->object.flags & (TREECHANGE | UNINTERESTING))
105                         return 0;
106                 if (!p->parents)
107                         return -1;
108                 *pp = p->parents->item;
109         }
110 }
111
112 static void rewrite_parents(struct commit *commit)
113 {
114         struct commit_list **pp = &commit->parents;
115         while (*pp) {
116                 struct commit_list *parent = *pp;
117                 if (rewrite_one(&parent->item) < 0) {
118                         *pp = parent->next;
119                         continue;
120                 }
121                 pp = &parent->next;
122         }
123 }
124
125 static int filter_commit(struct commit * commit)
126 {
127         if (stop_traversal && (commit->object.flags & BOUNDARY))
128                 return STOP;
129         if (commit->object.flags & (UNINTERESTING|SHOWN))
130                 return CONTINUE;
131         if (revs.min_age != -1 && (commit->date > revs.min_age))
132                 return CONTINUE;
133         if (revs.max_age != -1 && (commit->date < revs.max_age)) {
134                 stop_traversal=1;
135                 return CONTINUE;
136         }
137         if (no_merges && (commit->parents && commit->parents->next))
138                 return CONTINUE;
139         if (revs.paths && revs.dense) {
140                 if (!(commit->object.flags & TREECHANGE))
141                         return CONTINUE;
142                 rewrite_parents(commit);
143         }
144         return DO;
145 }
146
147 static int process_commit(struct commit * commit)
148 {
149         int action=filter_commit(commit);
150
151         if (action == STOP) {
152                 return STOP;
153         }
154
155         if (action == CONTINUE) {
156                 return CONTINUE;
157         }
158
159         if (revs.max_count != -1 && !revs.max_count--)
160                 return STOP;
161
162         show_commit(commit);
163
164         return CONTINUE;
165 }
166
167 static struct object_list **process_blob(struct blob *blob,
168                                          struct object_list **p,
169                                          struct name_path *path,
170                                          const char *name)
171 {
172         struct object *obj = &blob->object;
173
174         if (!revs.blob_objects)
175                 return p;
176         if (obj->flags & (UNINTERESTING | SEEN))
177                 return p;
178         obj->flags |= SEEN;
179         return add_object(obj, p, path, name);
180 }
181
182 static struct object_list **process_tree(struct tree *tree,
183                                          struct object_list **p,
184                                          struct name_path *path,
185                                          const char *name)
186 {
187         struct object *obj = &tree->object;
188         struct tree_entry_list *entry;
189         struct name_path me;
190
191         if (!revs.tree_objects)
192                 return p;
193         if (obj->flags & (UNINTERESTING | SEEN))
194                 return p;
195         if (parse_tree(tree) < 0)
196                 die("bad tree object %s", sha1_to_hex(obj->sha1));
197         obj->flags |= SEEN;
198         p = add_object(obj, p, path, name);
199         me.up = path;
200         me.elem = name;
201         me.elem_len = strlen(name);
202         entry = tree->entries;
203         tree->entries = NULL;
204         while (entry) {
205                 struct tree_entry_list *next = entry->next;
206                 if (entry->directory)
207                         p = process_tree(entry->item.tree, p, &me, entry->name);
208                 else
209                         p = process_blob(entry->item.blob, p, &me, entry->name);
210                 free(entry);
211                 entry = next;
212         }
213         return p;
214 }
215
216 static void show_commit_list(struct commit_list *list)
217 {
218         struct object_list *objects = NULL, **p = &objects, *pending;
219         while (list) {
220                 struct commit *commit = pop_most_recent_commit(&list, SEEN);
221
222                 p = process_tree(commit->tree, p, NULL, "");
223                 if (process_commit(commit) == STOP)
224                         break;
225         }
226         for (pending = revs.pending_objects; pending; pending = pending->next) {
227                 struct object *obj = pending->item;
228                 const char *name = pending->name;
229                 if (obj->flags & (UNINTERESTING | SEEN))
230                         continue;
231                 if (obj->type == tag_type) {
232                         obj->flags |= SEEN;
233                         p = add_object(obj, p, NULL, name);
234                         continue;
235                 }
236                 if (obj->type == tree_type) {
237                         p = process_tree((struct tree *)obj, p, NULL, name);
238                         continue;
239                 }
240                 if (obj->type == blob_type) {
241                         p = process_blob((struct blob *)obj, p, NULL, name);
242                         continue;
243                 }
244                 die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
245         }
246         while (objects) {
247                 /* An object with name "foo\n0000000..." can be used to
248                  * confuse downstream git-pack-objects very badly.
249                  */
250                 const char *ep = strchr(objects->name, '\n');
251                 if (ep) {
252                         printf("%s %.*s\n", sha1_to_hex(objects->item->sha1),
253                                (int) (ep - objects->name),
254                                objects->name);
255                 }
256                 else
257                         printf("%s %s\n", sha1_to_hex(objects->item->sha1), objects->name);
258                 objects = objects->next;
259         }
260 }
261
262 static int everybody_uninteresting(struct commit_list *orig)
263 {
264         struct commit_list *list = orig;
265         while (list) {
266                 struct commit *commit = list->item;
267                 list = list->next;
268                 if (commit->object.flags & UNINTERESTING)
269                         continue;
270                 return 0;
271         }
272         return 1;
273 }
274
275 /*
276  * This is a truly stupid algorithm, but it's only
277  * used for bisection, and we just don't care enough.
278  *
279  * We care just barely enough to avoid recursing for
280  * non-merge entries.
281  */
282 static int count_distance(struct commit_list *entry)
283 {
284         int nr = 0;
285
286         while (entry) {
287                 struct commit *commit = entry->item;
288                 struct commit_list *p;
289
290                 if (commit->object.flags & (UNINTERESTING | COUNTED))
291                         break;
292                 if (!revs.paths || (commit->object.flags & TREECHANGE))
293                         nr++;
294                 commit->object.flags |= COUNTED;
295                 p = commit->parents;
296                 entry = p;
297                 if (p) {
298                         p = p->next;
299                         while (p) {
300                                 nr += count_distance(p);
301                                 p = p->next;
302                         }
303                 }
304         }
305
306         return nr;
307 }
308
309 static void clear_distance(struct commit_list *list)
310 {
311         while (list) {
312                 struct commit *commit = list->item;
313                 commit->object.flags &= ~COUNTED;
314                 list = list->next;
315         }
316 }
317
318 static struct commit_list *find_bisection(struct commit_list *list)
319 {
320         int nr, closest;
321         struct commit_list *p, *best;
322
323         nr = 0;
324         p = list;
325         while (p) {
326                 if (!revs.paths || (p->item->object.flags & TREECHANGE))
327                         nr++;
328                 p = p->next;
329         }
330         closest = 0;
331         best = list;
332
333         for (p = list; p; p = p->next) {
334                 int distance;
335
336                 if (revs.paths && !(p->item->object.flags & TREECHANGE))
337                         continue;
338
339                 distance = count_distance(p);
340                 clear_distance(list);
341                 if (nr - distance < distance)
342                         distance = nr - distance;
343                 if (distance > closest) {
344                         best = p;
345                         closest = distance;
346                 }
347         }
348         if (best)
349                 best->next = NULL;
350         return best;
351 }
352
353 static void mark_edge_parents_uninteresting(struct commit *commit)
354 {
355         struct commit_list *parents;
356
357         for (parents = commit->parents; parents; parents = parents->next) {
358                 struct commit *parent = parents->item;
359                 if (!(parent->object.flags & UNINTERESTING))
360                         continue;
361                 mark_tree_uninteresting(parent->tree);
362                 if (revs.edge_hint && !(parent->object.flags & SHOWN)) {
363                         parent->object.flags |= SHOWN;
364                         printf("-%s\n", sha1_to_hex(parent->object.sha1));
365                 }
366         }
367 }
368
369 static void mark_edges_uninteresting(struct commit_list *list)
370 {
371         for ( ; list; list = list->next) {
372                 struct commit *commit = list->item;
373
374                 if (commit->object.flags & UNINTERESTING) {
375                         mark_tree_uninteresting(commit->tree);
376                         continue;
377                 }
378                 mark_edge_parents_uninteresting(commit);
379         }
380 }
381
382 #define TREE_SAME       0
383 #define TREE_NEW        1
384 #define TREE_DIFFERENT  2
385 static int tree_difference = TREE_SAME;
386
387 static void file_add_remove(struct diff_options *options,
388                     int addremove, unsigned mode,
389                     const unsigned char *sha1,
390                     const char *base, const char *path)
391 {
392         int diff = TREE_DIFFERENT;
393
394         /*
395          * Is it an add of a new file? It means that
396          * the old tree didn't have it at all, so we
397          * will turn "TREE_SAME" -> "TREE_NEW", but
398          * leave any "TREE_DIFFERENT" alone (and if
399          * it already was "TREE_NEW", we'll keep it
400          * "TREE_NEW" of course).
401          */
402         if (addremove == '+') {
403                 diff = tree_difference;
404                 if (diff != TREE_SAME)
405                         return;
406                 diff = TREE_NEW;
407         }
408         tree_difference = diff;
409 }
410
411 static void file_change(struct diff_options *options,
412                  unsigned old_mode, unsigned new_mode,
413                  const unsigned char *old_sha1,
414                  const unsigned char *new_sha1,
415                  const char *base, const char *path)
416 {
417         tree_difference = TREE_DIFFERENT;
418 }
419
420 static struct diff_options diff_opt = {
421         .recursive = 1,
422         .add_remove = file_add_remove,
423         .change = file_change,
424 };
425
426 static int compare_tree(struct tree *t1, struct tree *t2)
427 {
428         if (!t1)
429                 return TREE_NEW;
430         if (!t2)
431                 return TREE_DIFFERENT;
432         tree_difference = TREE_SAME;
433         if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "", &diff_opt) < 0)
434                 return TREE_DIFFERENT;
435         return tree_difference;
436 }
437
438 static int same_tree_as_empty(struct tree *t1)
439 {
440         int retval;
441         void *tree;
442         struct tree_desc empty, real;
443
444         if (!t1)
445                 return 0;
446
447         tree = read_object_with_reference(t1->object.sha1, "tree", &real.size, NULL);
448         if (!tree)
449                 return 0;
450         real.buf = tree;
451
452         empty.buf = "";
453         empty.size = 0;
454
455         tree_difference = 0;
456         retval = diff_tree(&empty, &real, "", &diff_opt);
457         free(tree);
458
459         return retval >= 0 && !tree_difference;
460 }
461
462 static void try_to_simplify_commit(struct commit *commit)
463 {
464         struct commit_list **pp, *parent;
465
466         if (!commit->tree)
467                 return;
468
469         if (!commit->parents) {
470                 if (!same_tree_as_empty(commit->tree))
471                         commit->object.flags |= TREECHANGE;
472                 return;
473         }
474
475         pp = &commit->parents;
476         while ((parent = *pp) != NULL) {
477                 struct commit *p = parent->item;
478
479                 if (p->object.flags & UNINTERESTING) {
480                         pp = &parent->next;
481                         continue;
482                 }
483
484                 parse_commit(p);
485                 switch (compare_tree(p->tree, commit->tree)) {
486                 case TREE_SAME:
487                         parent->next = NULL;
488                         commit->parents = parent;
489                         return;
490
491                 case TREE_NEW:
492                         if (revs.remove_empty_trees && same_tree_as_empty(p->tree)) {
493                                 *pp = parent->next;
494                                 continue;
495                         }
496                 /* fallthrough */
497                 case TREE_DIFFERENT:
498                         pp = &parent->next;
499                         continue;
500                 }
501                 die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1));
502         }
503         commit->object.flags |= TREECHANGE;
504 }
505
506 static void add_parents_to_list(struct commit *commit, struct commit_list **list)
507 {
508         struct commit_list *parent = commit->parents;
509
510         /*
511          * If the commit is uninteresting, don't try to
512          * prune parents - we want the maximal uninteresting
513          * set.
514          *
515          * Normally we haven't parsed the parent
516          * yet, so we won't have a parent of a parent
517          * here. However, it may turn out that we've
518          * reached this commit some other way (where it
519          * wasn't uninteresting), in which case we need
520          * to mark its parents recursively too..
521          */
522         if (commit->object.flags & UNINTERESTING) {
523                 while (parent) {
524                         struct commit *p = parent->item;
525                         parent = parent->next;
526                         parse_commit(p);
527                         p->object.flags |= UNINTERESTING;
528                         if (p->parents)
529                                 mark_parents_uninteresting(p);
530                         if (p->object.flags & SEEN)
531                                 continue;
532                         p->object.flags |= SEEN;
533                         insert_by_date(p, list);
534                 }
535                 return;
536         }
537
538         /*
539          * Ok, the commit wasn't uninteresting. Try to
540          * simplify the commit history and find the parent
541          * that has no differences in the path set if one exists.
542          */
543         if (revs.paths)
544                 try_to_simplify_commit(commit);
545
546         parent = commit->parents;
547         while (parent) {
548                 struct commit *p = parent->item;
549
550                 parent = parent->next;
551
552                 parse_commit(p);
553                 if (p->object.flags & SEEN)
554                         continue;
555                 p->object.flags |= SEEN;
556                 insert_by_date(p, list);
557         }
558 }
559
560 static struct commit_list *limit_list(struct commit_list *list)
561 {
562         struct commit_list *newlist = NULL;
563         struct commit_list **p = &newlist;
564         while (list) {
565                 struct commit_list *entry = list;
566                 struct commit *commit = list->item;
567                 struct object *obj = &commit->object;
568
569                 list = list->next;
570                 free(entry);
571
572                 if (revs.max_age != -1 && (commit->date < revs.max_age))
573                         obj->flags |= UNINTERESTING;
574                 if (revs.unpacked && has_sha1_pack(obj->sha1))
575                         obj->flags |= UNINTERESTING;
576                 add_parents_to_list(commit, &list);
577                 if (obj->flags & UNINTERESTING) {
578                         mark_parents_uninteresting(commit);
579                         if (everybody_uninteresting(list))
580                                 break;
581                         continue;
582                 }
583                 if (revs.min_age != -1 && (commit->date > revs.min_age))
584                         continue;
585                 p = &commit_list_insert(commit, p)->next;
586         }
587         if (revs.tree_objects)
588                 mark_edges_uninteresting(newlist);
589         if (bisect_list)
590                 newlist = find_bisection(newlist);
591         return newlist;
592 }
593
594 int main(int argc, const char **argv)
595 {
596         struct commit_list *list;
597         int i;
598
599         argc = setup_revisions(argc, argv, &revs);
600
601         for (i = 1 ; i < argc; i++) {
602                 const char *arg = argv[i];
603
604                 /* accept -<digit>, like traditilnal "head" */
605                 if ((*arg == '-') && isdigit(arg[1])) {
606                         revs.max_count = atoi(arg + 1);
607                         continue;
608                 }
609                 if (!strcmp(arg, "-n")) {
610                         if (++i >= argc)
611                                 die("-n requires an argument");
612                         revs.max_count = atoi(argv[i]);
613                         continue;
614                 }
615                 if (!strncmp(arg,"-n",2)) {
616                         revs.max_count = atoi(arg + 2);
617                         continue;
618                 }
619                 if (!strcmp(arg, "--header")) {
620                         verbose_header = 1;
621                         continue;
622                 }
623                 if (!strcmp(arg, "--no-abbrev")) {
624                         abbrev = 0;
625                         continue;
626                 }
627                 if (!strncmp(arg, "--abbrev=", 9)) {
628                         abbrev = strtoul(arg + 9, NULL, 10);
629                         if (abbrev && abbrev < MINIMUM_ABBREV)
630                                 abbrev = MINIMUM_ABBREV;
631                         else if (40 < abbrev)
632                                 abbrev = 40;
633                         continue;
634                 }
635                 if (!strncmp(arg, "--pretty", 8)) {
636                         commit_format = get_commit_format(arg+8);
637                         verbose_header = 1;
638                         hdr_termination = '\n';
639                         if (commit_format == CMIT_FMT_ONELINE)
640                                 commit_prefix = "";
641                         else
642                                 commit_prefix = "commit ";
643                         continue;
644                 }
645                 if (!strncmp(arg, "--no-merges", 11)) {
646                         no_merges = 1;
647                         continue;
648                 }
649                 if (!strcmp(arg, "--parents")) {
650                         show_parents = 1;
651                         continue;
652                 }
653                 if (!strcmp(arg, "--bisect")) {
654                         bisect_list = 1;
655                         continue;
656                 }
657                 if (!strcmp(arg, "--merge-order")) {
658                         merge_order = 1;
659                         continue;
660                 }
661                 if (!strcmp(arg, "--show-breaks")) {
662                         show_breaks = 1;
663                         continue;
664                 }
665                 usage(rev_list_usage);
666
667         }
668
669         list = revs.commits;
670
671         if (!list &&
672             (!(revs.tag_objects||revs.tree_objects||revs.blob_objects) && !revs.pending_objects))
673                 usage(rev_list_usage);
674
675         if (revs.paths)
676                 diff_tree_setup_paths(revs.paths);
677
678         save_commit_buffer = verbose_header;
679         track_object_refs = 0;
680
681         if (!merge_order) {             
682                 sort_by_date(&list);
683                 if (list && !revs.limited && revs.max_count == 1 &&
684                     !revs.tag_objects && !revs.tree_objects && !revs.blob_objects) {
685                         show_commit(list->item);
686                         return 0;
687                 }
688                 if (revs.limited)
689                         list = limit_list(list);
690                 if (revs.topo_order)
691                         sort_in_topological_order(&list, revs.lifo);
692                 show_commit_list(list);
693         } else {
694 #ifndef NO_OPENSSL
695                 if (sort_list_in_merge_order(list, &process_commit)) {
696                         die("merge order sort failed\n");
697                 }
698 #else
699                 die("merge order sort unsupported, OpenSSL not linked");
700 #endif
701         }
702
703         return 0;
704 }