git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 1/3] teach log --no-walk=unsorted, which avoids sorting

From
Martin von Zweigbergk <martinvonz@gmail.com>
Date
Aug 29, 2012, 06:15 UTC
Message-ID
<1346220956-25034-2-git-send-email-martinvonz@gmail.com>
In-Reply-To
<1346220956-25034-1-git-send-email-martinvonz@gmail.com>

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>
---
 Documentation/rev-list-options.txt | 12 ++++++++----
 builtin/log.c                      |  2 +-
 builtin/revert.c                   |  2 +-
 revision.c                         | 18 +++++++++++++++---
 revision.h                         |  6 +++++-
 t/t4202-log.sh                     | 10 ++++++++++
 6 files changed, 40 insertions(+), 10 deletions(-)
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index def1340..5436eba 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -636,10 +636,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.
-	This has no effect if a range is specified.
+--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::
 
diff --git a/builtin/log.c b/builtin/log.c
index ecc2793..20838b1 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -456,7 +456,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));
diff --git a/builtin/revert.c b/builtin/revert.c
index 82d1bf8..42ce399 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -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));
diff --git a/revision.c b/revision.c
index 442a945..66ba2e6 100644
--- a/revision.c
+++ b/revision.c
@@ -1300,7 +1300,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;
@@ -1695,7 +1695,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 {
@@ -2117,10 +2128,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)
diff --git a/revision.h b/revision.h
index cb5ab35..a95bd0b 100644
--- a/revision.h
+++ b/revision.h
@@ -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,
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index 71be59d..bd83355 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -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
-- 
1.7.11.1.104.ge7b44f1
Previous: Martin von ZweigbergkNext: Dan Johnson
Message 14 of 37 in “cherry-pick and 'log --no-walk' and ordering”
  1. Martin von ZweigbergkAug 10, 2012
  2. Junio C HamanoAug 10, 2012
  3. Martin von ZweigbergkAug 11, 2012
  4. Junio C HamanoAug 11, 2012
  5. 0/4 Re: cherry-pick and 'log --no-walk' and orderingy@google.com, Aug 13, 2012
  6. Junio C HamanoAug 13, 2012
  7. Junio C HamanoAug 13, 2012
  8. Martin von ZweigbergkAug 13, 2012
  9. Junio C HamanoAug 13, 2012
  10. Martin von ZweigbergkAug 13, 2012
  11. Junio C HamanoAug 13, 2012
  12. Martin von ZweigbergkAug 13, 2012
  13. 0/3 revision (no-)walking in orderMartin von Zweigbergk, Aug 29, 2012
  14. 1/3 teach log --no-walk=unsorted, which avoids sortingMartin von Zweigbergk, Aug 29, 2012
  15. Dan JohnsonAug 29, 2012
  16. Junio C HamanoAug 29, 2012
  17. 2/3 demonstrate broken 'git cherry-pick three one two'Martin von Zweigbergk, Aug 29, 2012
  18. Junio C HamanoAug 30, 2012
  19. 3/3 cherry-pick/revert: respect order of revisions to pickMartin von Zweigbergk, Aug 29, 2012
  20. Junio C HamanoAug 29, 2012
  21. Martin von Zweigbergk has a new e-mail addressMartin von Zweigbergk, Aug 29, 2012
  22. 1/4 teach log --no-walk=unsorted, which avoids sortingy@google.com, Aug 13, 2012
  23. 2/4 revisions passed to cherry-pick should be in "default" ordery@google.com, Aug 13, 2012
  24. Junio C HamanoAug 13, 2012
  25. Martin von ZweigbergkAug 13, 2012
  26. Junio C HamanoAug 13, 2012
  27. Martin von ZweigbergkAug 15, 2012
  28. Junio C HamanoAug 15, 2012
  29. Martin von ZweigbergkAug 15, 2012
  30. Junio C HamanoAug 15, 2012
  31. Martin von ZweigbergkAug 15, 2012
  32. Martin von ZweigbergkAug 13, 2012
  33. Junio C HamanoAug 13, 2012
  34. 3/4 cherry-pick/revert: respect order of revisions to picky@google.com, Aug 13, 2012
  35. 4/4 cherry-pick/revert: default to topological sortingy@google.com, Aug 13, 2012
  36. Junio C HamanoAug 13, 2012
  37. Junio C HamanoAug 13, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.