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

[PATCH 1/4] "log" and friends: --children option

From
Junio C Hamano <gitster@pobox.com>
Date
Apr 3, 2008, 09:12 UTC
Message-ID
<7vlk3v2tg9.fsf@gitster.siamese.dyndns.org>
In-Reply-To
<7v4paj486a.fsf@gitster.siamese.dyndns.org>

This adds a new --children option to the revision machinery. In addition to the list of parents, child commits of each commit are computed and shown in the output from "git log" and friends.

Note that this does _not_ show all children of a commit. It only shows children on the commit ancestry you made the revision machinery traverse. For example, "git log --children master..next" will not show side branches forked from any commits shown in the range that have not been merged to "next" (i.e. what are queued in 'pu' but not yet merged to 'next').

This patch was primarily done for adding the infrastructure to allow users of revision machinery to find out children of commits; please consider the current output not much more than debugging aid. If you want to use it from "git log" and friends, the output format needs a bit more serious thought.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 log-tree.c |   20 ++++++++++++++++++++
 revision.c |   28 ++++++++++++++++++++++++++++
 revision.h |    1 +
 3 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/log-tree.c b/log-tree.c
index 5b29639..75851d1 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -32,6 +32,24 @@ void show_decorations(struct commit *commit)
 	putchar(')');
 }
 
+static void show_children(struct rev_info *revs, struct commit *commit, int abbrev)
+{
+	struct commit_list *p;
+
+	if (!revs->children.name)
+		return;
+	p = lookup_decoration(&revs->children, &commit->object);
+	if (!p)
+		return;
+	printf("child");
+	while (p) {
+		struct commit *child = p->item;
+		printf(" %s", diff_unique_abbrev(child->object.sha1, abbrev));
+		p = p->next;
+	}
+	putchar(revs->diffopt.line_termination);
+}
+
 /*
  * Search for "^[-A-Za-z]+: [^@]+@" pattern. It usually matches
  * Signed-off-by: and Acked-by: lines.
@@ -236,6 +254,7 @@ void show_log(struct rev_info *opt, const char *sep)
 			show_parents(commit, abbrev_commit);
 		show_decorations(commit);
 		putchar(opt->diffopt.line_termination);
+		show_children(opt, commit, abbrev_commit);
 		return;
 	}
 
@@ -297,6 +316,7 @@ void show_log(struct rev_info *opt, const char *sep)
 				return;
 			}
 		}
+		show_children(opt, commit, abbrev_commit);
 	}
 
 	if (!commit->buffer)
diff --git a/revision.c b/revision.c
index 196fedc..e5138b7 100644
--- a/revision.c
+++ b/revision.c
@@ -9,6 +9,7 @@
 #include "grep.h"
 #include "reflog-walk.h"
 #include "patch-ids.h"
+#include "decorate.h"
 
 volatile show_early_output_fn_t show_early_output;
 
@@ -1309,6 +1310,11 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
 				revs->no_walk = 0;
 				continue;
 			}
+			if (!strcmp(arg, "--children")) {
+				revs->children.name = "children";
+				revs->limited = 1;
+				continue;
+			}
 
 			opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
 			if (opts > 0) {
@@ -1398,6 +1404,26 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
 	return left;
 }
 
+static void add_child(struct rev_info *revs, struct commit *parent, struct commit *child)
+{
+	struct commit_list *l = xcalloc(1, sizeof(*l));
+
+	l->item = child;
+	l->next = add_decoration(&revs->children, &parent->object, l);
+}
+
+static void set_children(struct rev_info *revs)
+{
+	struct commit_list *l;
+	for (l = revs->commits; l; l = l->next) {
+		struct commit *commit = l->item;
+		struct commit_list *p;
+
+		for (p = commit->parents; p; p = p->next)
+			add_child(revs, p->item, commit);
+	}
+}
+
 int prepare_revision_walk(struct rev_info *revs)
 {
 	int nr = revs->pending.nr;
@@ -1426,6 +1452,8 @@ int prepare_revision_walk(struct rev_info *revs)
 			return -1;
 	if (revs->topo_order)
 		sort_in_topological_order(&revs->commits, revs->lifo);
+	if (revs->children.name)
+		set_children(revs);
 	return 0;
 }
 
diff --git a/revision.h b/revision.h
index c8b3b94..966116c 100644
--- a/revision.h
+++ b/revision.h
@@ -98,6 +98,7 @@ struct rev_info {
 	struct diff_options pruning;
 
 	struct reflog_walk_info *reflog_info;
+	struct decoration children;
 };
 
 #define REV_TREE_SAME		0
-- 
1.5.5.rc3.139.g8b2cf
Previous: Junio C HamanoNext: Johannes Schindelin
Message 2 of 8 in “Blame in reverse”
  1. 0/4 Blame in reverseJunio C Hamano, Apr 3, 2008
  2. 1/4 "log" and friends: --children optionJunio C Hamano, Apr 3, 2008
  3. Johannes SchindelinApr 3, 2008
  4. 2/4 builtin-blame.c: move prepare_final() into a separate function.Junio C Hamano, Apr 3, 2008
  5. 3/4 builtin-blame.c: allow more than 16 parentsJunio C Hamano, Apr 3, 2008
  6. 4/4 git-blame --reverseJunio C Hamano, Apr 3, 2008
  7. Johannes SixtApr 3, 2008
  8. Junio C HamanoApr 3, 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.