Code

git-log (internal): more options.
authorJunio C Hamano <junkio@cox.net>
Wed, 1 Mar 2006 08:58:56 +0000 (00:58 -0800)
committerJunio C Hamano <junkio@cox.net>
Wed, 1 Mar 2006 11:16:34 +0000 (03:16 -0800)
This ports the following options from rev-list based git-log
implementation:

 * -<n>, -n<n>, and -n <n>.  I am still wondering if we want
    this natively supported by setup_revisions(), which already
    takes --max-count.  We may want to move them in the next
    round.  Also I am not sure if we can get away with not
    setting revs->limited when we set max-count.  The latest
    rev-list.c and revision.c in this series do not, so I left
    them as they are.

 * --pretty and --pretty=<fmt>.

 * --abbrev=<n> and --no-abbrev.

The previous commit already handles time-based limiters
(--since, --until and friends).  The remaining things that
rev-list based git-log happens to do are not useful in a pure
log-viewing purposes, and not ported:

 * --bisect (obviously).

 * --header.  I am actually in favor of doing the NUL
   terminated record format, but rev-list based one always
   passed --pretty, which defeated this option.  Maybe next
   round.

 * --parents.  I do not think of a reason a log viewer wants
   this.  The flag is primarily for feeding squashed history
   via pipe to downstream tools.

Signed-off-by: Junio C Hamano <junkio@cox.net>
git.c
rev-list.c
revision.h

diff --git a/git.c b/git.c
index b0da6b19457cf06f8e880bd0b18f270da94069b1..bf68daca200cee00747cec1bbcace985ff0af9d1 100644 (file)
--- a/git.c
+++ b/git.c
@@ -256,12 +256,80 @@ static int cmd_log(int argc, char **argv, char **envp)
        struct rev_info rev;
        struct commit *commit;
        char *buf = xmalloc(LOGSIZE);
+       static enum cmit_fmt commit_format = CMIT_FMT_DEFAULT;
+       int abbrev = DEFAULT_ABBREV;
+       int show_parents = 0;
+       const char *commit_prefix = "commit ";
 
        argc = setup_revisions(argc, argv, &rev, "HEAD");
+       while (1 < argc) {
+               char *arg = argv[1];
+               /* accept -<digit>, like traditilnal "head" */
+               if ((*arg == '-') && isdigit(arg[1])) {
+                       rev.max_count = atoi(arg + 1);
+               }
+               else if (!strcmp(arg, "-n")) {
+                       if (argc < 2)
+                               die("-n requires an argument");
+                       rev.max_count = atoi(argv[2]);
+                       argc--; argv++;
+               }
+               else if (!strncmp(arg,"-n",2)) {
+                       rev.max_count = atoi(arg + 2);
+               }
+               else if (!strncmp(arg, "--pretty", 8)) {
+                       commit_format = get_commit_format(arg + 8);
+                       if (commit_format == CMIT_FMT_ONELINE)
+                               commit_prefix = "";
+               }
+               else if (!strcmp(arg, "--parents")) {
+                       show_parents = 1;
+               }
+               else if (!strcmp(arg, "--no-abbrev")) {
+                       abbrev = 0;
+               }
+               else if (!strncmp(arg, "--abbrev=", 9)) {
+                       abbrev = strtoul(arg + 9, NULL, 10);
+                       if (abbrev && abbrev < MINIMUM_ABBREV)
+                               abbrev = MINIMUM_ABBREV;
+                       else if (40 < abbrev)
+                               abbrev = 40;
+               }
+               else
+                       die("unrecognized argument: %s", arg);
+               argc--; argv++;
+       }
+
        prepare_revision_walk(&rev);
        setup_pager();
        while ((commit = get_revision(&rev)) != NULL) {
-               pretty_print_commit(CMIT_FMT_DEFAULT, commit, ~0, buf, LOGSIZE, 18);
+               printf("%s%s", commit_prefix,
+                      sha1_to_hex(commit->object.sha1));
+               if (show_parents) {
+                       struct commit_list *parents = commit->parents;
+                       while (parents) {
+                               struct object *o = &(parents->item->object);
+                               parents = parents->next;
+                               if (o->flags & TMP_MARK)
+                                       continue;
+                               printf(" %s", sha1_to_hex(o->sha1));
+                               o->flags |= TMP_MARK;
+                       }
+                       /* TMP_MARK is a general purpose flag that can
+                        * be used locally, but the user should clean
+                        * things up after it is done with them.
+                        */
+                       for (parents = commit->parents;
+                            parents;
+                            parents = parents->next)
+                               parents->item->object.flags &= ~TMP_MARK;
+               }
+               if (commit_format == CMIT_FMT_ONELINE)
+                       putchar(' ');
+               else
+                       putchar('\n');
+               pretty_print_commit(commit_format, commit, ~0, buf,
+                                   LOGSIZE, abbrev);
                printf("%s\n", buf);
        }
        free(buf);
index 6af8d869eeb4a0c7edf2c9d4c58c9a306adbfa4f..8e4d83efba369c5ce925fd1e22d36a768917147b 100644 (file)
@@ -7,10 +7,9 @@
 #include "diff.h"
 #include "revision.h"
 
-/* bits #0-3 in revision.h */
+/* bits #0-4 in revision.h */
 
-#define COUNTED                (1u << 4)
-#define TMP_MARK       (1u << 5) /* for isolated cases; clean after use */
+#define COUNTED                (1u<<5)
 
 static const char rev_list_usage[] =
 "git-rev-list [OPTION] <commit-id>... [ -- paths... ]\n"
index 0043c1694cbc86e78477f038ef6018e71b96983f..31e8f615677634a92992df8404c86a8c2184ff2a 100644 (file)
@@ -5,6 +5,7 @@
 #define UNINTERESTING   (1u<<1)
 #define TREECHANGE     (1u<<2)
 #define SHOWN          (1u<<3)
+#define TMP_MARK       (1u<<4) /* for isolated cases; clean after use */
 
 struct rev_info {
        /* Starting list */