rev-list.con commit pretty_print_commit: add different formats (000182e)
   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 int verbose_header = 0;
  17static int show_parents = 0;
  18static int hdr_termination = 0;
  19static const char *prefix = "";
  20static unsigned long max_age = -1;
  21static unsigned long min_age = -1;
  22static int max_count = -1;
  23static enum cmit_fmt commit_format = CMIT_FMT_RAW;
  24
  25static void show_commit(struct commit *commit)
  26{
  27        printf("%s%s", prefix, sha1_to_hex(commit->object.sha1));
  28        if (show_parents) {
  29                struct commit_list *parents = commit->parents;
  30                while (parents) {
  31                        printf(" %s", sha1_to_hex(parents->item->object.sha1));
  32                        parents = parents->next;
  33                }
  34        }
  35        putchar('\n');
  36        if (verbose_header) {
  37                static char pretty_header[16384];
  38                pretty_print_commit(commit_format, commit->buffer, ~0, pretty_header, sizeof(pretty_header));
  39                printf("%s%c", pretty_header, hdr_termination);
  40        }
  41}
  42
  43static void show_commit_list(struct commit_list *list)
  44{
  45        while (list) {
  46                struct commit *commit = pop_most_recent_commit(&list, SEEN);
  47
  48                if (commit->object.flags & UNINTERESTING)
  49                        continue;
  50                if (min_age != -1 && (commit->date > min_age))
  51                        continue;
  52                if (max_age != -1 && (commit->date < max_age))
  53                        break;
  54                if (max_count != -1 && !max_count--)
  55                        break;
  56                show_commit(commit);
  57        }
  58}
  59
  60static void mark_parents_uninteresting(struct commit *commit)
  61{
  62        struct commit_list *parents = commit->parents;
  63
  64        while (parents) {
  65                struct commit *commit = parents->item;
  66                commit->object.flags |= UNINTERESTING;
  67                parents = parents->next;
  68        }
  69}
  70
  71static int everybody_uninteresting(struct commit_list *list)
  72{
  73        while (list) {
  74                struct commit *commit = list->item;
  75                list = list->next;
  76                if (commit->object.flags & UNINTERESTING)
  77                        continue;
  78                return 0;
  79        }
  80        return 1;
  81}
  82
  83struct commit_list *limit_list(struct commit_list *list)
  84{
  85        struct commit_list *newlist = NULL;
  86        struct commit_list **p = &newlist;
  87        do {
  88                struct commit *commit = pop_most_recent_commit(&list, SEEN);
  89                struct object *obj = &commit->object;
  90
  91                if (obj->flags & UNINTERESTING) {
  92                        mark_parents_uninteresting(commit);
  93                        if (everybody_uninteresting(list))
  94                                break;
  95                        continue;
  96                }
  97                p = &commit_list_insert(commit, p)->next;
  98        } while (list);
  99        return newlist;
 100}
 101
 102static enum cmit_fmt get_commit_format(const char *arg)
 103{
 104        if (!*arg)
 105                return CMIT_FMT_DEFAULT;
 106        if (!strcmp(arg, "=raw"))
 107                return CMIT_FMT_RAW;
 108        if (!strcmp(arg, "=medium"))
 109                return CMIT_FMT_MEDIUM;
 110        if (!strcmp(arg, "=short"))
 111                return CMIT_FMT_SHORT;
 112        usage(rev_list_usage);  
 113}                       
 114
 115
 116int main(int argc, char **argv)
 117{
 118        struct commit_list *list = NULL;
 119        int i, limited = 0;
 120
 121        for (i = 1 ; i < argc; i++) {
 122                int flags;
 123                char *arg = argv[i];
 124                unsigned char sha1[20];
 125                struct commit *commit;
 126
 127                if (!strncmp(arg, "--max-count=", 12)) {
 128                        max_count = atoi(arg + 12);
 129                        continue;
 130                }
 131                if (!strncmp(arg, "--max-age=", 10)) {
 132                        max_age = atoi(arg + 10);
 133                        continue;
 134                }
 135                if (!strncmp(arg, "--min-age=", 10)) {
 136                        min_age = atoi(arg + 10);
 137                        continue;
 138                }
 139                if (!strcmp(arg, "--header")) {
 140                        verbose_header = 1;
 141                        continue;
 142                }
 143                if (!strncmp(arg, "--pretty", 8)) {
 144                        commit_format = get_commit_format(arg+8);
 145                        verbose_header = 1;
 146                        hdr_termination = '\n';
 147                        prefix = "commit ";
 148                        continue;
 149                }
 150                if (!strcmp(arg, "--parents")) {
 151                        show_parents = 1;
 152                        continue;
 153                }
 154
 155                flags = 0;
 156                if (*arg == '^') {
 157                        flags = UNINTERESTING;
 158                        arg++;
 159                        limited = 1;
 160                }
 161                if (get_sha1(arg, sha1))
 162                        usage(rev_list_usage);
 163                commit = lookup_commit_reference(sha1);
 164                if (!commit || parse_commit(commit) < 0)
 165                        die("bad commit object %s", arg);
 166                commit->object.flags |= flags;
 167                commit_list_insert(commit, &list);
 168        }
 169
 170        if (!list)
 171                usage(rev_list_usage);
 172
 173        if (limited)
 174                list = limit_list(list);
 175
 176        show_commit_list(list);
 177        return 0;
 178}