Commits

Anonymous committed 4311d32

Be more aggressive about marking trees uninteresting

We'll mark all the trees at the edges (as deep as we had to go to
realize that we have all the commits needed) as uninteresting.
Otherwise we'll occasionally list a lot of objects that were actually
available at the edge in a commit that we just never ended up parsing
because we could determine early that we had all relevant commits.

NOTE! The object listing is still just a _heuristic_. It's guaranteed
to list a superset of the actual new objects, but there might be the
occasional old object in the list, just because the commit that
referenced it was much further back in the history.

For example, let's say that a recent commit is a revert of part of the
tree to much older state: since we didn't walk _that_ far back in the
commit history tree to list the commits necessary, git-rev-tree will
never have marked the old objects uninteresting, and we'll end up
listing them as "new".

That's ok.

Comments (0)

Files changed (1)

 	}
 }
 
-static int everybody_uninteresting(struct commit_list *list)
+static int everybody_uninteresting(struct commit_list *orig)
 {
+	struct commit_list *list = orig;
 	while (list) {
 		struct commit *commit = list->item;
 		list = list->next;
 			continue;
 		return 0;
 	}
+
+	/*
+	 * Ok, go back and mark all the edge trees uninteresting,
+	 * since otherwise we can have situations where a parent
+	 * that was marked uninteresting (and we never even had
+	 * to look at) had lots of objects that we don't want to
+	 * include.
+	 *
+	 * NOTE! This still doesn't mean that the object list is
+	 * "correct", since we may end up listing objects that
+	 * even older commits (that we don't list) do actually
+	 * reference, but it gets us to a minimal list (or very
+	 * close) in practice.
+	 */
+	if (!tree_objects)
+		return 1;
+
+	while (orig) {
+		struct commit *commit = orig->item;
+		if (!parse_commit(commit) && commit->tree)
+			mark_tree_uninteresting(commit->tree);
+		orig = orig->next;
+	}
 	return 1;
 }
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.