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

[PATCH v3 2/2] log: add --show-linear-break to help see non-linear history

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Mar 20, 2014, 05:44 UTC
Message-ID
<1395294254-941-2-git-send-email-pclouds@gmail.com>
In-Reply-To
<1395294254-941-1-git-send-email-pclouds@gmail.com>

Option explanation is in rev-list-options.txt. The interaction with -z is left undecided.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 * Revert back to the old option name --show-linear-break
 * Get rid of saved_linear, use another flag in struct object instead
 * Fix not showing the break bar after a root commit if the dag graph
   has multiple roots
 * Make it work with --graph (although I don't really see the point of
   using both at the same time)
 * Let the next contributor deal with -z
 Documentation/rev-list-options.txt |  7 ++++++
 log-tree.c                         |  9 ++++++++
 object.h                           |  2 +-
 revision.c                         | 45 +++++++++++++++++++++++++++++++++++---
 revision.h                         |  9 +++++++-
 5 files changed, 67 insertions(+), 5 deletions(-)
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 9a3da36..b813961 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -758,6 +758,13 @@ This enables parent rewriting, see 'History Simplification' below.
 This implies the `--topo-order` option by default, but the
 `--date-order` option may also be specified.
 
+--show-linear-break[=<barrier>]::
+	When --graph is not used, all history branches are flattened
+	which can make it hard to see that the two consecutive commits
+	do not belong to a linear branch. This option puts a barrier
+	in between them in that case. If `<barrier>` is specified, it
+	is the string that will be shown instead of the default one.
+
 ifdef::git-rev-list[]
 --count::
 	Print a number stating how many commits would have been
diff --git a/log-tree.c b/log-tree.c
index 5ce217d..c51a878 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -805,12 +805,21 @@ int log_tree_commit(struct rev_info *opt, struct commit *commit)
 	if (opt->line_level_traverse)
 		return line_log_print(opt, commit);
 
+	if (opt->track_linear && !opt->linear && !opt->reverse_output_stage) {
+		if (opt->graph)
+			graph_show_padding(opt->graph);
+		else
+			puts("\n");
+		printf("%s\n", opt->break_bar);
+	}
 	shown = log_tree_diff(opt, commit, &log);
 	if (!shown && opt->loginfo && opt->always_show_header) {
 		log.parent = NULL;
 		show_log(opt);
 		shown = 1;
 	}
+	if (opt->track_linear && !opt->linear && opt->reverse_output_stage)
+		printf("\n%s\n", opt->break_bar);
 	opt->loginfo = NULL;
 	maybe_flush_or_die(stdout, "stdout");
 	return shown;
diff --git a/object.h b/object.h
index 768490b..9ee1959 100644
--- a/object.h
+++ b/object.h
@@ -28,7 +28,7 @@ struct object_array {
 #define TYPE_BITS   3
 /*
  * object flag allocation:
- * revision.h:      0------10
+ * revision.h:      0------10                 26
  * fetch-pack.c:    0---4
  * walker.c:        0-2
  * upload-pack.c:             11---------19
diff --git a/revision.c b/revision.c
index 78b5c3a..b9afdce 100644
--- a/revision.c
+++ b/revision.c
@@ -1831,6 +1831,18 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
 		revs->notes_opt.use_default_notes = 1;
 	} else if (!strcmp(arg, "--show-signature")) {
 		revs->show_signature = 1;
+	} else if (!strcmp(arg, "--show-linear-break") ||
+		   starts_with(arg, "--show-linear-break=")) {
+		if (starts_with(arg, "--show-linear-break="))
+			revs->break_bar = xstrdup(arg + 20);
+		else
+			revs->break_bar = "                    ..........";
+		revs->track_linear = 1;
+		/*
+		 * make track_linear() not a break bar before the
+		 * first shown commit.
+		 */
+		commit_list_insert(NULL, &revs->previous_parents);
 	} else if (starts_with(arg, "--show-notes=") ||
 		   starts_with(arg, "--notes=")) {
 		struct strbuf buf = STRBUF_INIT;
@@ -2896,6 +2908,22 @@ enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
 	return action;
 }
 
+static void track_linear(struct rev_info *revs, struct commit *commit)
+{
+	struct commit_list *p;
+	for (p = revs->previous_parents; p; p = p->next)
+		if (p->item == NULL || /* first commit */
+		    !hashcmp(p->item->object.sha1, commit->object.sha1))
+			break;
+	revs->linear = p != NULL;
+	if (revs->reverse) {
+		if (revs->linear)
+			commit->object.flags |= TRACK_LINEAR;
+	}
+	free_commit_list(revs->previous_parents);
+	revs->previous_parents = copy_commit_list(commit->parents);
+}
+
 static struct commit *get_revision_1(struct rev_info *revs)
 {
 	if (!revs->commits)
@@ -2935,6 +2963,8 @@ static struct commit *get_revision_1(struct rev_info *revs)
 			die("Failed to simplify parents of commit %s",
 			    sha1_to_hex(commit->object.sha1));
 		default:
+			if (revs->track_linear)
+				track_linear(revs, commit);
 			return commit;
 		}
 	} while (revs->commits);
@@ -3101,14 +3131,23 @@ struct commit *get_revision(struct rev_info *revs)
 		revs->reverse_output_stage = 1;
 	}
 
-	if (revs->reverse_output_stage)
-		return pop_commit(&revs->commits);
+	if (revs->reverse_output_stage) {
+		c = pop_commit(&revs->commits);
+		if (revs->track_linear)
+			revs->linear = !!(c && c->object.flags & TRACK_LINEAR);
+		return c;
+	}
 
 	c = get_revision_internal(revs);
 	if (c && revs->graph)
 		graph_update(revs->graph, c);
-	if (!c)
+	if (!c) {
 		free_saved_parents(revs);
+		if (revs->previous_parents) {
+			free_commit_list(revs->previous_parents);
+			revs->previous_parents = NULL;
+		}
+	}
 	return c;
 }
 
diff --git a/revision.h b/revision.h
index 0262bbd..64503e9 100644
--- a/revision.h
+++ b/revision.h
@@ -19,7 +19,8 @@
 #define SYMMETRIC_LEFT	(1u<<8)
 #define PATCHSAME	(1u<<9)
 #define BOTTOM		(1u<<10)
-#define ALL_REV_FLAGS	((1u<<11)-1)
+#define TRACK_LINEAR	(1u<<26)
+#define ALL_REV_FLAGS	(((1u<<11)-1) | TRACK_LINEAR)
 
 #define DECORATE_SHORT_REFS	1
 #define DECORATE_FULL_REFS	2
@@ -138,6 +139,9 @@ struct rev_info {
 			preserve_subject:1;
 	unsigned int	disable_stdin:1;
 	unsigned int	leak_pending:1;
+	/* --show-linear-break */
+	unsigned int	track_linear:1,
+			linear:1;
 
 	enum date_mode date_mode;
 
@@ -198,6 +202,9 @@ struct rev_info {
 
 	/* copies of the parent lists, for --full-diff display */
 	struct saved_parents *saved_parents_slab;
+
+	struct commit_list *previous_parents;
+	const char *break_bar;
 };
 
 extern int ref_excluded(struct string_list *, const char *path);
-- 
1.9.0.201.g13d9d8b
Previous: Nguyễn Thái Ngọc DuyNext: Junio C Hamano
Message 14 of 19 in “Confusing git log --- First time bug submission please advise on best practices”
  1. Francis StephensFeb 6, 2014
  2. Vincent van RavesteijnFeb 6, 2014
  3. David KastrupFeb 6, 2014
  4. Francis StephensFeb 7, 2014
  5. Duy NguyenFeb 7, 2014
  6. demerphqFeb 7, 2014
  7. log: add --show-linear-break to help see non-linear historyNguyễn Thái Ngọc Duy, Feb 8, 2014
  8. log: add --nonlinear-barrier to help see non-linear historyNguyễn Thái Ngọc Duy, Mar 17, 2014
  9. Eric SunshineMar 17, 2014
  10. Junio C HamanoMar 17, 2014
  11. Duy NguyenMar 18, 2014
  12. Junio C HamanoMar 18, 2014
  13. 1/2 object.h: centralize object flag allocationNguyễn Thái Ngọc Duy, Mar 20, 2014
  14. 2/2 log: add --show-linear-break to help see non-linear historyNguyễn Thái Ngọc Duy, Mar 20, 2014
  15. Junio C HamanoMar 20, 2014
  16. Duy NguyenMar 21, 2014
  17. 1/2 object.h: centralize object flag allocationNguyễn Thái Ngọc Duy, Mar 25, 2014
  18. 2/2 log: add --show-linear-break to help see non-linear historyNguyễn Thái Ngọc Duy, Mar 25, 2014
  19. Junio C HamanoMar 25, 2014

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.