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

[PATCH 1/2] rev-list: "adjust" results of "--count --use-bitmap-index -n"

From
Jeff King <peff@peff.net>
Date
Jun 2, 2016, 23:10 UTC
Message-ID
<20160602231031.GA11247@sigill.intra.peff.net>
In-Reply-To
<20160602230925.GA11196@sigill.intra.peff.net>
If you ask rev-list for:
    git rev-list --count --use-bitmap-index HEAD

we optimize out the actual traversal and just give you the number of bits set in the commit bitmap. This is faster, which is good.

But if you ask to limit the size of the traversal, like:
    git rev-list --count --use-bitmap-index -n 100 HEAD

we'll still output the full bitmapped number we found. On the surface, that might even seem OK. You explicitly asked to use the bitmap index, and it was cheap to compute the real answer, so we gave it to you.

But there's something much more complicated going on under the hood. If we don't have a bitmap directly for HEAD, then we have to actually traverse backwards, looking for a bitmapped commit. And _that_ traversal is bounded by our `-n` count.

This is a good thing, because it bounds the work we have to do, which is probably what the user wanted by asking for `-n`. But now it makes the output quite confusing. You might get many values:

  - your `-n` value, if we walked back and never found a
    bitmap (or fewer if there weren't that many commits)
  - the actual full count, if we found a bitmap root for
    every path of our traversal with in the `-n` limit
  - any number in between! We might have walked back and
    found _some_ bitmaps, but then cut off the traversal
    early with some commits not accounted for in the result.

So you cannot even see a value higher than your `-n` and say "OK, bitmaps kicked in, this must be the real full count". The only sane thing is for git to just clamp the value to a maximum of the `-n` value, which means we should output the exact same results whether bitmaps are in use or not.

The test in t5310 demonstrates this by using `-n 1`. Without this patch we fail in the full-bitmap case (where we do not have to traverse at all) but _not_ in the partial-bitmap case (where we have to walk down to find an actual bitmap). With this patch, both cases just work.

I didn't implement the crazy in-between case, just because it's complicated to set up, and is really a subset of the full-count case, which we do cover.

Signed-off-by: Jeff King <peff@peff.net>
---
 builtin/rev-list.c      | 2 ++
 t/t5310-pack-bitmaps.sh | 6 ++++++
 2 files changed, 8 insertions(+)
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 275da0d..aaa79a3 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -360,6 +360,8 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 			uint32_t commit_count;
 			if (!prepare_bitmap_walk(&revs)) {
 				count_bitmap_commit_list(&commit_count, NULL, NULL, NULL);
+				if (revs.max_count && revs.max_count < commit_count)
+					commit_count = revs.max_count;
 				printf("%d\n", commit_count);
 				return 0;
 			}
diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index d446706..3893afd 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -47,6 +47,12 @@ rev_list_tests() {
 		test_cmp expect actual
 	'
 
+	test_expect_success "counting commits with limit ($state)" '
+		git rev-list --count -n 1 HEAD >expect &&
+		git rev-list --use-bitmap-index --count -n 1 HEAD >actual &&
+		test_cmp expect actual
+	'
+
 	test_expect_success "counting non-linear history ($state)" '
 		git rev-list --count other...master >expect &&
 		git rev-list --use-bitmap-index --count other...master >actual &&
-- 
2.9.0.rc1.132.g33c7f30
Previous: Jeff KingNext: Jeff King
Message 2 of 6 in “corner cases with "rev-list --use-bitmap-index -n"”
  1. 0/2 corner cases with "rev-list --use-bitmap-index -n"Jeff King, Jun 2, 2016
  2. 1/2 rev-list: "adjust" results of "--count --use-bitmap-index -n"Jeff King, Jun 2, 2016
  3. 0/2 corner cases with "rev-list --use-bitmap-index -n"Jeff King, Jun 3, 2016
  4. 1/2 rev-list: "adjust" results of "--count --use-bitmap-index -n"Jeff King, Jun 3, 2016
  5. 2/2 rev-list: disable bitmaps when "-n" is used with listing objectsJeff King, Jun 3, 2016
  6. 2/2 rev-list: disable bitmaps when "-n" is used with listing objectsJeff King, Jun 2, 2016

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.