teach log --no-walk=unsorted, which avoids sorting
authorMartin von Zweigbergk <martinvonz@gmail.com>
Wed, 29 Aug 2012 06:15:54 +0000 (23:15 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 30 Aug 2012 19:26:50 +0000 (12:26 -0700)
When 'git log' is passed the --no-walk option, no revision walk takes
place, naturally. Perhaps somewhat surprisingly, however, the provided
revisions still get sorted by commit date. So e.g 'git log --no-walk
HEAD HEAD~1' and 'git log --no-walk HEAD~1 HEAD' give the same result
(unless the two revisions share the commit date, in which case they
will retain the order given on the command line). As the commit that
introduced --no-walk (8e64006 (Teach revision machinery about
--no-walk, 2007-07-24)) points out, the sorting is intentional, to
allow things like

 git log --abbrev-commit --pretty=oneline --decorate --all --no-walk

to show all refs in order by commit date.

But there are also other cases where the sorting is not wanted, such
as

 <command producing revisions in order> |
       git log --oneline --no-walk --stdin

To accomodate both cases, leave the decision of whether or not to sort
up to the caller, by allowing --no-walk={sorted,unsorted}, defaulting
to 'sorted' for backward-compatibility reasons.

Signed-off-by: Martin von Zweigbergk <martinvonz@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/rev-list-options.txt
builtin/log.c
builtin/revert.c
revision.c
revision.h
t/t4202-log.sh

index 1ae3c899ef4bb6d37bc5cbcb25ed927011378d90..9780f4646ac867ef79e143a1976c02f08a085ed1 100644 (file)
@@ -619,9 +619,14 @@ These options are mostly targeted for packing of git repositories.
        Only useful with '--objects'; print the object IDs that are not
        in packs.
 
---no-walk::
-
-       Only show the given revs, but do not traverse their ancestors.
+--no-walk[=(sorted|unsorted)]::
+
+       Only show the given commits, but do not traverse their ancestors.
+       This has no effect if a range is specified. If the argument
+       "unsorted" is given, the commits are show in the order they were
+       given on the command line. Otherwise (if "sorted" or no argument
+       was given), the commits are show in reverse chronological order
+       by commit time.
 
 --do-walk::
 
index 906dca475af0ed51d499cce4a7c0a34f038c5810..9e21d1b4909784a4c4104cdcef67568c795307b3 100644 (file)
@@ -454,7 +454,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
        init_revisions(&rev, prefix);
        rev.diff = 1;
        rev.always_show_header = 1;
-       rev.no_walk = 1;
+       rev.no_walk = REVISION_WALK_NO_WALK_SORTED;
        rev.diffopt.stat_width = -1;    /* Scale to real terminal size */
 
        memset(&opt, 0, sizeof(opt));
index 82d1bf844b996d5d121169f244358964fd36fd19..42ce399d88f7f53cb52255f74e15f6557cdb5f70 100644 (file)
@@ -193,7 +193,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
                struct setup_revision_opt s_r_opt;
                opts->revs = xmalloc(sizeof(*opts->revs));
                init_revisions(opts->revs, NULL);
-               opts->revs->no_walk = 1;
+               opts->revs->no_walk = REVISION_WALK_NO_WALK_SORTED;
                if (argc < 2)
                        usage_with_options(usage_str, options);
                memset(&s_r_opt, 0, sizeof(s_r_opt));
index 935e7a7ba413668c95a6c3e846b9058be07f0425..2f9dbddf60e966853f776a4e657fb5191790f5e5 100644 (file)
@@ -1294,7 +1294,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
            !strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk") ||
            !strcmp(arg, "--bisect") || !prefixcmp(arg, "--glob=") ||
            !prefixcmp(arg, "--branches=") || !prefixcmp(arg, "--tags=") ||
-           !prefixcmp(arg, "--remotes="))
+           !prefixcmp(arg, "--remotes=") || !prefixcmp(arg, "--no-walk="))
        {
                unkv[(*unkc)++] = arg;
                return 1;
@@ -1687,7 +1687,18 @@ static int handle_revision_pseudo_opt(const char *submodule,
        } else if (!strcmp(arg, "--not")) {
                *flags ^= UNINTERESTING;
        } else if (!strcmp(arg, "--no-walk")) {
-               revs->no_walk = 1;
+               revs->no_walk = REVISION_WALK_NO_WALK_SORTED;
+       } else if (!prefixcmp(arg, "--no-walk=")) {
+               /*
+                * Detached form ("--no-walk X" as opposed to "--no-walk=X")
+                * not allowed, since the argument is optional.
+                */
+               if (!strcmp(arg + 10, "sorted"))
+                       revs->no_walk = REVISION_WALK_NO_WALK_SORTED;
+               else if (!strcmp(arg + 10, "unsorted"))
+                       revs->no_walk = REVISION_WALK_NO_WALK_UNSORTED;
+               else
+                       return error("invalid argument to --no-walk");
        } else if (!strcmp(arg, "--do-walk")) {
                revs->no_walk = 0;
        } else {
@@ -2091,10 +2102,11 @@ int prepare_revision_walk(struct rev_info *revs)
                }
                e++;
        }
-       commit_list_sort_by_date(&revs->commits);
        if (!revs->leak_pending)
                free(list);
 
+       if (revs->no_walk != REVISION_WALK_NO_WALK_UNSORTED)
+               commit_list_sort_by_date(&revs->commits);
        if (revs->no_walk)
                return 0;
        if (revs->limited)
index 863f4f64543bd9f9e830e7c9567def23e906c7d9..80e22fea4a93a2ca8c5de3aae34dfce02e2ca3d3 100644 (file)
@@ -41,6 +41,10 @@ struct rev_cmdline_info {
        } *rev;
 };
 
+#define REVISION_WALK_WALK 0
+#define REVISION_WALK_NO_WALK_SORTED 1
+#define REVISION_WALK_NO_WALK_UNSORTED 2
+
 struct rev_info {
        /* Starting list */
        struct commit_list *commits;
@@ -62,7 +66,7 @@ struct rev_info {
        /* Traversal flags */
        unsigned int    dense:1,
                        prune:1,
-                       no_walk:1,
+                       no_walk:2,
                        show_all:1,
                        remove_empty_trees:1,
                        simplify_history:1,
index 71be59d446f773c4b567f00c469ac26225d11cb8..bd8335580d0fa02e0c7e1b9b1459cac37050ed44 100755 (executable)
@@ -178,11 +178,21 @@ test_expect_success 'git log --no-walk <commits> sorts by commit time' '
        test_cmp expect actual
 '
 
+test_expect_success 'git log --no-walk=sorted <commits> sorts by commit time' '
+       git log --no-walk=sorted --oneline 5d31159 804a787 394ef78 > actual &&
+       test_cmp expect actual
+'
+
 cat > expect << EOF
 5d31159 fourth
 804a787 sixth
 394ef78 fifth
 EOF
+test_expect_success 'git log --no-walk=unsorted <commits> leaves list of commits as given' '
+       git log --no-walk=unsorted --oneline 5d31159 804a787 394ef78 > actual &&
+       test_cmp expect actual
+'
+
 test_expect_success 'git show <commits> leaves list of commits as given' '
        git show --oneline -s 5d31159 804a787 394ef78 > actual &&
        test_cmp expect actual