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

[PATCH 2/4] graph API: Added additional utility functions to the graph API

From
Adam Simpkins <adam@adamsimpkins.net>
Date
Apr 6, 2008, 18:42 UTC
Message-ID
<1207507332-1866-2-git-send-email-adam@adamsimpkins.net>
In-Reply-To
<1207507332-1866-1-git-send-email-adam@adamsimpkins.net>

Added several graph_show_* functions that print directly to stdout instead of to a strbuf. Also added functions for explicitly adding vertical padding in the graph.

Signed-off-by: Adam Simpkins <adam@adamsimpkins.net>
---
 Documentation/technical/api-history-graph.txt |   28 +++++
 graph.c                                       |  140 +++++++++++++++++++++++++
 graph.h                                       |   51 +++++++++
 3 files changed, 219 insertions(+), 0 deletions(-)
diff --git a/Documentation/technical/api-history-graph.txt b/Documentation/technical/api-history-graph.txt
index 56a0a1e..34f45b0 100644
--- a/Documentation/technical/api-history-graph.txt
+++ b/Documentation/technical/api-history-graph.txt
@@ -20,6 +20,34 @@ Calling sequence
   after the current commit.  This return value can be used to determine where
   to print the commit summary information alongside the graph output.
 
+Utility functions
+-----------------
+
+The following functions are wrappers around `graph_next_line()` and
+`graph_is_commit_finished()`.  They always print the output to stdout.
+They can all be called with a NULL graph argument, in which case no graph output
+will be printed.
+
+* `graph_show_commit()` calls `graph_next_line()` until it returns non-zero.
+  This prints all graph lines up to, and including, the line containing this
+  commit.  Output is printed to stdout.  The last line printed does not contain
+  a terminating newline.  This should not be called if the commit line has
+  already been printed, or it will loop forever.
+
+* `graph_show_oneline()` calls `graph_next_line()` and prints the result to
+  stdout.  The line printed does not contain a terminating newline.
+
+* `graph_show_remainder()` calls `graph_next_line()` until
+  `graph_is_commit_finished()` returns non-zero.  Output is printed to stdout.
+  The last line printed does not contain a terminating newline.  Returns 1 if
+  output was printed, and 0 if no output was necessary.
+
+* `graph_show_strbuf()` prints the specified strbuf to stdout, prefixing all
+  lines but the first with a graph line.  The caller is responsible for ensuring
+  graph output for the first line has already been printed to stdout.  (This can
+  be done with `graph_show_commit()` or `graph_show_oneline()`.)  If a NULL
+  graph is supplied, the strbuf is printed as-is.
+
 Data structure
 --------------
 `struct git_graph` is an opaque data type used to store the current graph
diff --git a/graph.c b/graph.c
index d8cb7d4..e6d1d3a 100644
--- a/graph.c
+++ b/graph.c
@@ -705,7 +705,147 @@ int graph_next_line(struct git_graph *graph, struct strbuf *sb)
 	return 0;
 }
 
+void graph_padding_line(struct git_graph *graph, struct strbuf *sb)
+{
+	int i, j;
+
+	if (graph->state != GRAPH_COMMIT) {
+		graph_next_line(graph, sb);
+		return;
+	}
+
+	/*
+	 * Output the row containing this commit
+	 * Iterate up to and including graph->num_columns,
+	 * since the current commit may not be in any of the existing
+	 * columns.  (This happens when the current commit doesn't have any
+	 * children that we have already processed.)
+	 */
+	for (i = 0; i < graph->num_columns; ++i) {
+		struct commit *col_commit = graph->columns[i].commit;
+		if (col_commit == graph->commit) {
+			strbuf_addch(sb, '|');
+
+			if (graph->num_parents < 3)
+				strbuf_addch(sb, ' ');
+			else {
+				int num_spaces = ((graph->num_parents - 2) * 2);
+				for (j = 0; j < num_spaces; ++j)
+					strbuf_addch(sb, ' ');
+			}
+		} else {
+			strbuf_addstr(sb, "| ");
+		}
+	}
+
+	graph_pad_horizontally(graph, sb);
+}
+
 int graph_is_commit_finished(struct git_graph const *graph)
 {
 	return (graph->state == GRAPH_PADDING);
 }
+
+void graph_show_commit(struct git_graph *graph)
+{
+	struct strbuf msgbuf;
+	int shown_commit_line = 0;
+
+	if (!graph)
+		return;
+
+	strbuf_init(&msgbuf, 0);
+
+	while (!shown_commit_line) {
+		shown_commit_line = graph_next_line(graph, &msgbuf);
+		fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
+		if (!shown_commit_line)
+			putchar('\n');
+		strbuf_setlen(&msgbuf, 0);
+	}
+
+	strbuf_release(&msgbuf);
+}
+
+void graph_show_oneline(struct git_graph *graph)
+{
+	struct strbuf msgbuf;
+
+	if (!graph)
+		return;
+
+	strbuf_init(&msgbuf, 0);
+	graph_next_line(graph, &msgbuf);
+	fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
+	strbuf_release(&msgbuf);
+}
+
+void graph_show_padding(struct git_graph *graph)
+{
+	struct strbuf msgbuf;
+
+	if (!graph)
+		return;
+
+	strbuf_init(&msgbuf, 0);
+	graph_padding_line(graph, &msgbuf);
+	fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
+	strbuf_release(&msgbuf);
+}
+
+int graph_show_remainder(struct git_graph *graph)
+{
+	struct strbuf msgbuf;
+	int shown = 0;
+
+	if (!graph)
+		return 0;
+
+	if (graph_is_commit_finished(graph))
+		return 0;
+
+	strbuf_init(&msgbuf, 0);
+	for (;;) {
+		graph_next_line(graph, &msgbuf);
+		fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
+		strbuf_setlen(&msgbuf, 0);
+		shown = 1;
+
+		if (!graph_is_commit_finished(graph))
+			putchar('\n');
+		else
+			break;
+	}
+	strbuf_release(&msgbuf);
+
+	return shown;
+}
+
+
+void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb)
+{
+	if (!graph) {
+		fwrite(sb->buf, sizeof(char), sb->len, stdout);
+		return;
+	}
+
+	/*
+	 * Print the strbuf line by line,
+	 * and display the graph info before each line but the first.
+	 */
+	char *p = sb->buf;
+	while (p) {
+		size_t len;
+		char *next_p = strchr(p, '\n');
+		if (next_p) {
+			next_p++;
+			len = next_p - p;
+		} else {
+			len = (sb->buf + sb->len) - p;
+		}
+		fwrite(p, sizeof(char), len, stdout);
+		if (next_p && *next_p != '\0')
+			graph_show_oneline(graph);
+		p = next_p;
+	}
+}
diff --git a/graph.h b/graph.h
index fc23bf2..817862e 100644
--- a/graph.h
+++ b/graph.h
@@ -43,6 +43,15 @@ void graph_update(struct git_graph *graph, struct commit *commit);
 int graph_next_line(struct git_graph *graph, struct strbuf *sb);
 
 /*
+ * Output a padding line in the graph.
+ * This is similar to graph_next_line().  However, it is guaranteed to
+ * never print the current commit line.  Instead, if the commit line is
+ * next, it will simply output a line of vertical padding, extending the
+ * branch lines downwards, but leaving them otherwise unchanged.
+ */
+void graph_padding_line(struct git_graph *graph, struct strbuf *sb);
+
+/*
  * Determine if a graph has finished outputting lines for the current
  * commit.
  *
@@ -54,4 +63,46 @@ int graph_next_line(struct git_graph *graph, struct strbuf *sb);
  */
 int graph_is_commit_finished(struct git_graph const *graph);
 
+
+/*
+ * graph_show_*: helper functions for printing to stdout
+ */
+
+
+/*
+ * If the graph is non-NULL, print the history graph to stdout,
+ * up to and including the line containing this commit.
+ * Does not print a terminating newline on the last line.
+ */
+void graph_show_commit(struct git_graph *graph);
+
+/*
+ * If the graph is non-NULL, print one line of the history graph to stdout.
+ * Does not print a terminating newline on the last line.
+ */
+void graph_show_oneline(struct git_graph *graph);
+
+/*
+ * If the graph is non-NULL, print one line of vertical graph padding to
+ * stdout.  Does not print a terminating newline on the last line.
+ */
+void graph_show_padding(struct git_graph *graph);
+
+/*
+ * If the graph is non-NULL, print the rest of the history graph for this
+ * commit to stdout.  Does not print a terminating newline on the last line.
+ */
+int graph_show_remainder(struct git_graph *graph);
+
+/*
+ * Print a strbuf to stdout.  If the graph is non-NULL, all lines but the
+ * first will be prefixed with the graph output.
+ *
+ * Since the firat line will not include the graph ouput, the caller is
+ * responsible for printing this line's graph (perhaps via
+ * graph_show_commit() or graph_show_oneline()) before calling
+ * graph_show_strbuf().
+ */
+void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb);
+
 #endif /* GRAPH_H */
-- 
1.5.3.6
Previous: Adam SimpkinsNext: Adam Simpkins
Message 2 of 37 in “Add history graph API”
  1. 1/4 Add history graph APIAdam Simpkins, Apr 6, 2008
  2. 2/4 graph API: Added additional utility functions to the graph APIAdam Simpkins, Apr 6, 2008
  3. 3/4 git log and git rev-list: Add --graph optionAdam Simpkins, Apr 6, 2008
  4. 4/4 git log: Updated --graph to work even when the commit list is prunedAdam Simpkins, Apr 6, 2008
  5. 5/5 Document the new --graph option for log and rev-listAdam Simpkins, Apr 6, 2008
  6. 1/4 graph API: Fixed coding style problemsAdam Simpkins, Apr 7, 2008
  7. 2/4 log and rev-list: Fixed newline termination issues with --graphAdam Simpkins, Apr 7, 2008
  8. 3/4 log and rev-list: Fix --graph output with --pretty=emailAdam Simpkins, Apr 7, 2008
  9. 4/4 log and rev-list: Improve --graph output when commits have been prunedAdam Simpkins, Apr 7, 2008
  10. Junio C HamanoApr 7, 2008
  11. Junio C HamanoApr 7, 2008
  12. Jeff KingApr 7, 2008
  13. Junio C HamanoApr 7, 2008
  14. Adam SimpkinsApr 7, 2008
  15. Jakub NarebskiApr 7, 2008
  16. Junio C HamanoApr 8, 2008
  17. Govind SalinasApr 8, 2008
  18. Junio C HamanoApr 8, 2008
  19. Teemu LikonenApr 6, 2008
  20. Adam SimpkinsApr 6, 2008
  21. Teemu LikonenApr 6, 2008
  22. Adam SimpkinsApr 6, 2008
  23. Johannes SchindelinApr 6, 2008
  24. Adam SimpkinsApr 6, 2008
  25. Teemu LikonenApr 7, 2008
  26. Adam SimpkinsApr 7, 2008
  27. Teemu LikonenApr 7, 2008
  28. Johannes SchindelinApr 6, 2008
  29. Adam SimpkinsApr 6, 2008
  30. Johannes SchindelinApr 6, 2008
  31. Adam SimpkinsApr 6, 2008
  32. Linus TorvaldsApr 7, 2008
  33. Junio C HamanoApr 7, 2008
  34. bash: Add command line completion of --graph (git log)Teemu Likonen, Apr 6, 2008
  35. bash: Add more command line option completions for 'git log'Teemu Likonen, Apr 7, 2008
  36. Teemu LikonenApr 7, 2008
  37. Adam SimpkinsApr 7, 2008

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.