[PATCH 1/2] Fix output of "git log --graph --boundary"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Previously the graphing API wasn't aware of the revs->boundary flag, and
it always assumed that commits marked UNINTERESTING would not be
displayed.  As a result, the boundary commits were printed at the end of
the log output, but they didn't have any branch lines connecting them to
their children in the graph.

There was also another bug in the get_revision() code that caused
graph_update() to be called twice on the first boundary commit.  This
caused the graph API to think that a commit had been skipped, and print
a "..." line in the output.

Signed-off-by: Adam Simpkins <adam@xxxxxxxxxxxxxxxx>
---
 graph.c    |   94 ++++++++++++++++++++++++++++++++++++++++++------------------
 revision.c |    2 +-
 2 files changed, 67 insertions(+), 29 deletions(-)

diff --git a/graph.c b/graph.c
index 479035d..ce1abc0 100644
--- a/graph.c
+++ b/graph.c
@@ -191,9 +191,26 @@ static void graph_ensure_capacity(struct git_graph *graph, int num_columns)
  * Returns 1 if the commit will be printed in the graph output,
  * and 0 otherwise.
  */
-static int graph_is_interesting(struct commit *commit)
+static int graph_is_interesting(struct git_graph *graph, struct commit *commit)
 {
 	/*
+	 * If revs->boundary is set, commits whose children have
+	 * been shown are always interesting, even if they have the
+	 * UNINTERESTING or TREESAME flags set.
+	 *
+	 * However, ignore the commit if SHOWN is set.  If SHOWN is set,
+	 * the commit is interesting, but it has already been printed.
+	 * This can happen because get_revision() doesn't return the
+	 * boundary commits in topological order, even when
+	 * revs->topo_order is set.
+	 */
+	if (graph->revs && graph->revs->boundary) {
+		if ((commit->object.flags & (SHOWN | CHILD_SHOWN)) ==
+		    CHILD_SHOWN)
+			return 1;
+	}
+
+	/*
 	 * Uninteresting and pruned commits won't be printed
 	 */
 	return (commit->object.flags & (UNINTERESTING | TREESAME)) ? 0 : 1;
@@ -208,7 +225,7 @@ static void graph_insert_into_new_columns(struct git_graph *graph,
 	/*
 	 * Ignore uinteresting commits
 	 */
-	if (!graph_is_interesting(commit))
+	if (!graph_is_interesting(graph, commit))
 		return;
 
 	/*
@@ -382,7 +399,7 @@ void graph_update(struct git_graph *graph, struct commit *commit)
 	 */
 	graph->num_parents = 0;
 	for (parent = commit->parents; parent; parent = parent->next) {
-		if (graph_is_interesting(parent->item))
+		if (graph_is_interesting(graph, parent->item))
 			graph->num_parents++;
 	}
 
@@ -545,6 +562,51 @@ static void graph_output_pre_commit_line(struct git_graph *graph,
 		graph->state = GRAPH_COMMIT;
 }
 
+static void graph_output_commit_char(struct git_graph *graph, struct strbuf *sb)
+{
+	/*
+	 * For boundary commits, print 'o'
+	 * (We should only see boundary commits when revs->boundary is set.)
+	 */
+	if (graph->commit->object.flags & BOUNDARY) {
+		assert(graph->revs->boundary);
+		strbuf_addch(sb, 'o');
+		return;
+	}
+
+	/*
+	 * If revs->left_right is set, print '<' for commits that
+	 * come from the left side, and '>' for commits from the right
+	 * side.
+	 */
+	if (graph->revs && graph->revs->left_right) {
+		if (graph->commit->object.flags & SYMMETRIC_LEFT)
+			strbuf_addch(sb, '<');
+		else
+			strbuf_addch(sb, '>');
+		return;
+	}
+
+	/*
+	 * Print 'M' for merge commits
+	 *
+	 * Note that we don't check graph->num_parents to determine if the
+	 * commit is a merge, since that only tracks the number of
+	 * "interesting" parents.  We want to print 'M' for merge commits
+	 * even if they have less than 2 interesting parents.
+	 */
+	if (graph->commit->parents != NULL &&
+	    graph->commit->parents->next != NULL) {
+		strbuf_addch(sb, 'M');
+		return;
+	}
+
+	/*
+	 * Print '*' in all other cases
+	 */
+	strbuf_addch(sb, '*');
+}
+
 void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb)
 {
 	int seen_this = 0;
@@ -570,31 +632,7 @@ void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb)
 
 		if (col_commit == graph->commit) {
 			seen_this = 1;
-			/*
-			 * If revs->left_right is set, print the '<' or '>'
-			 * depending on which side this commit came from.
-			 *
-			 * If revs->left_right is not set and the commit is
-			 * a merge, print 'M'.  Otherwise, print '*'.
-			 *
-			 * Note that we don't check graph->num_parents to
-			 * determine if the commit is a merge, since that
-			 * only tracks the number of "interesting" parents.
-			 * We want to print 'M' for merge commits even if
-			 * they have less than 2 interesting parents.
-			 */
-			if (graph->revs && graph->revs->left_right) {
-				if (graph->commit->object.flags
-						& SYMMETRIC_LEFT)
-					strbuf_addch(sb, '<');
-				else
-					strbuf_addch(sb, '>');
-			}
-			else if (graph->commit->parents != NULL &&
-				 graph->commit->parents->next != NULL)
-				strbuf_addch(sb, 'M');
-			else
-				strbuf_addch(sb, '*');
+			graph_output_commit_char(graph, sb);
 
 			if (graph->num_parents < 2)
 				strbuf_addch(sb, ' ');
diff --git a/revision.c b/revision.c
index 1341f3d..181fb0b 100644
--- a/revision.c
+++ b/revision.c
@@ -1697,7 +1697,7 @@ static struct commit *get_revision_internal(struct rev_info *revs)
 		 * switch to boundary commits output mode.
 		 */
 		revs->boundary = 2;
-		return get_revision(revs);
+		return get_revision_internal(revs);
 	}
 
 	/*
-- 
1.5.5.1.389.g35a9d

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux