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

Re: git-rev-list: add "--dense" flag

From
Linus Torvalds <torvalds@osdl.org>
Date
Oct 25, 2005, 18:50 UTC
Message-ID
<Pine.LNX.4.64.0510251137110.10477@g5.osdl.org>
In-Reply-To
<Pine.LNX.4.64.0510251110050.10477@g5.osdl.org>
On Tue, 25 Oct 2005, Linus Torvalds wrote:
Show 5 quoted lines
> 
> Right now --dense will _always_ show the root commit. I didn't do the 
> logic that does the diff against an empty tree. I was lazy.
> 
> This patch does that, and may or may not work.
Never mind. It's incorrect. 

It's -close- to being correct, but it will SIGSEGV because now the root won't necessarily have the TREECHANGED flag, so now it can follow the root down to its parents (which is a NULL pointer - that's the definition of a root commit, of course).

It needs to remove the parent pointers that become NULL.
This patch is even slightly tested, and might do a better job.
[ Sorry for sending untested crap out, but I have a fairly good track 
  record in general. Testing is for wimps ]
		Linus
---
diff --git a/rev-list.c b/rev-list.c
index 5f125fd..edf3b37 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -81,23 +81,28 @@ static void show_commit(struct commit *c
 	fflush(stdout);
 }
 
-static void rewrite_one(struct commit **pp)
+static int rewrite_one(struct commit **pp)
 {
 	for (;;) {
 		struct commit *p = *pp;
 		if (p->object.flags & (TREECHANGE | UNINTERESTING))
-			return;
-		/* Only single-parent commits don't have TREECHANGE */
+			return 0;
+		if (!p->parents)
+			return -1;
 		*pp = p->parents->item;
 	}
 }
 
 static void rewrite_parents(struct commit *commit)
 {
-	struct commit_list *parent = commit->parents;
-	while (parent) {
-		rewrite_one(&parent->item);
-		parent = parent->next;
+	struct commit_list **pp = &commit->parents;
+	while (*pp) {
+		struct commit_list *parent = *pp;
+		if (rewrite_one(&parent->item) < 0) {
+			*pp = parent->next;
+			continue;
+		}
+		pp = &parent->next;
 	}
 }
 
@@ -439,6 +444,30 @@ static int same_tree(struct tree *t1, st
 	return !is_different;
 }
 
+static int same_tree_as_empty(struct tree *t1)
+{
+	int retval;
+	void *tree;
+	struct tree_desc empty, real;
+
+	if (!t1)
+		return 0;
+
+	tree = read_object_with_reference(t1->object.sha1, "tree", &real.size, NULL);
+	if (!tree)
+		return 0;
+	real.buf = tree;
+
+	empty.buf = "";
+	empty.size = 0;
+
+	is_different = 0;
+	retval = diff_tree(&empty, &real, "", &diff_opt);
+	free(tree);
+
+	return retval >= 0 && !is_different;
+}
+
 static struct commit *try_to_simplify_merge(struct commit *commit, struct commit_list *parent)
 {
 	if (!commit->tree)
@@ -523,11 +552,17 @@ static void compress_list(struct commit_
 		struct commit_list *parent = commit->parents;
 		list = list->next;
 
+		if (!parent) {
+			if (!same_tree_as_empty(commit->tree))
+				commit->object.flags |= TREECHANGE;
+			continue;
+		}
+
 		/*
 		 * Exactly one parent? Check if it leaves the tree
 		 * unchanged
 		 */
-		if (parent && !parent->next) {
+		if (!parent->next) {
 			struct tree *t1 = commit->tree;
 			struct tree *t2 = parent->item->tree;
 			if (!t1 || !t2 || same_tree(t1, t2))
Previous: Linus Torvalds
Message 20 of 20 in “git-rev-list: add "--dense" flag”
  1. Linus TorvaldsOct 21, 2005
  2. Linus TorvaldsOct 21, 2005
  3. Linus TorvaldsOct 21, 2005
  4. Petr BaudisOct 22, 2005
  5. Handling renames.Petr Baudis, Oct 22, 2005
  6. Linus TorvaldsOct 22, 2005
  7. Petr BaudisOct 22, 2005
  8. Junio C HamanoOct 22, 2005
  9. Petr BaudisOct 22, 2005
  10. Linus TorvaldsOct 22, 2005
  11. Linus TorvaldsOct 22, 2005
  12. Petr BaudisOct 22, 2005
  13. Linus TorvaldsOct 22, 2005
  14. Junio C HamanoOct 22, 2005
  15. Linus TorvaldsOct 22, 2005
  16. Jonas FonsecaOct 25, 2005
  17. Linus TorvaldsOct 25, 2005
  18. Jonas FonsecaOct 25, 2005
  19. Linus TorvaldsOct 25, 2005
  20. Linus TorvaldsOct 25, 2005

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.