rev-list.con commit Update tutorial for simplified "git" script. (81bb573)
   1#include "cache.h"
   2#include "commit.h"
   3
   4#define SEEN            (1u << 0)
   5#define INTERESTING     (1u << 1)
   6#define UNINTERESTING   (1u << 2)
   7
   8static const char rev_list_usage[] =
   9        "usage: git-rev-list [OPTION] commit-id <commit-id>\n"
  10                      "  --max-count=nr\n"
  11                      "  --max-age=epoch\n"
  12                      "  --min-age=epoch\n"
  13                      "  --header\n"
  14                      "  --pretty";
  15
  16static void mark_parents_uninteresting(struct commit *commit)
  17{
  18        struct commit_list *parents = commit->parents;
  19
  20        while (parents) {
  21                struct commit *commit = parents->item;
  22                commit->object.flags |= UNINTERESTING;
  23                parents = parents->next;
  24        }
  25}
  26
  27static int everybody_uninteresting(struct commit_list *list)
  28{
  29        while (list) {
  30                struct commit *commit = list->item;
  31                list = list->next;
  32                if (commit->object.flags & UNINTERESTING)
  33                        continue;
  34                return 0;
  35        }
  36        return 1;
  37}
  38
  39int main(int argc, char **argv)
  40{
  41        int nr_sha;
  42        unsigned char sha1[2][20];
  43        struct commit_list *list = NULL;
  44        struct commit *commit, *end;
  45        int i, verbose_header = 0, show_parents = 0, pretty_print = 0;
  46        int hdr_termination = 0;
  47        const char *prefix = "";
  48        unsigned long max_age = -1;
  49        unsigned long min_age = -1;
  50        int max_count = -1;
  51
  52        nr_sha = 0;
  53        for (i = 1 ; i < argc; i++) {
  54                char *arg = argv[i];
  55
  56                if (!strncmp(arg, "--max-count=", 12)) {
  57                        max_count = atoi(arg + 12);
  58                        continue;
  59                }
  60                if (!strncmp(arg, "--max-age=", 10)) {
  61                        max_age = atoi(arg + 10);
  62                        continue;
  63                }
  64                if (!strncmp(arg, "--min-age=", 10)) {
  65                        min_age = atoi(arg + 10);
  66                        continue;
  67                }
  68                if (!strcmp(arg, "--header")) {
  69                        verbose_header = 1;
  70                        continue;
  71                }
  72                if (!strcmp(arg, "--pretty")) {
  73                        verbose_header = 1;
  74                        pretty_print = 1;
  75                        hdr_termination = '\n';
  76                        prefix = "commit ";
  77                        continue;
  78                }
  79                if (!strcmp(arg, "--parents")) {
  80                        show_parents = 1;
  81                        continue;
  82                }
  83
  84                if (nr_sha > 2 || get_sha1(arg, sha1[nr_sha]))
  85                        usage(rev_list_usage);
  86                nr_sha++;
  87        }
  88
  89        if (!nr_sha)
  90                usage(rev_list_usage);
  91
  92        commit = lookup_commit_reference(sha1[0]);
  93        if (!commit || parse_commit(commit) < 0)
  94                die("bad starting commit object");
  95
  96        end = NULL;
  97        if (nr_sha > 1) {
  98                end = lookup_commit_reference(sha1[1]);
  99                if (!end || parse_commit(end) < 0)
 100                        die("bad ending commit object");
 101        }
 102
 103        commit_list_insert(commit, &list);
 104        if (end) {
 105                struct commit_list *newlist = NULL;
 106                struct commit_list **p = &newlist;
 107                do {
 108                        struct commit *commit = pop_most_recent_commit(&list, SEEN);
 109                        struct object *obj = &commit->object;
 110
 111                        if (commit == end || (obj->flags & UNINTERESTING)) {
 112                                mark_parents_uninteresting(commit);
 113                                if (everybody_uninteresting(list))
 114                                        break;
 115                                continue;
 116                        }
 117                        p = &commit_list_insert(commit, p)->next;
 118                } while (list);
 119                list = newlist;
 120        }
 121
 122        while (list) {
 123                struct commit *commit = pop_most_recent_commit(&list, SEEN);
 124
 125                if (commit->object.flags & UNINTERESTING)
 126                        continue;
 127                if (min_age != -1 && (commit->date > min_age))
 128                        continue;
 129                if (max_age != -1 && (commit->date < max_age))
 130                        break;
 131                if (max_count != -1 && !max_count--)
 132                        break;
 133                printf("%s%s", prefix, sha1_to_hex(commit->object.sha1));
 134                if (show_parents) {
 135                        struct commit_list *parents = commit->parents;
 136                        while (parents) {
 137                                printf(" %s", sha1_to_hex(parents->item->object.sha1));
 138                                parents = parents->next;
 139                        }
 140                }
 141                putchar('\n');
 142                if (verbose_header) {
 143                        const char *buf = commit->buffer;
 144                        if (pretty_print) {
 145                                static char pretty_header[16384];
 146                                pretty_print_commit(commit->buffer, ~0, pretty_header, sizeof(pretty_header));
 147                                buf = pretty_header;
 148                        }
 149                        printf("%s%c", buf, hdr_termination);
 150                }
 151        }
 152        return 0;
 153}