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

Re: Shallow clone

From
Junio C Hamano <junkio@cox.net>
Date
Nov 12, 2006, 21:59 UTC
Message-ID
<7vd57scong.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<20061112205909.f8951300.vsu@altlinux.ru>
Sergey Vlasov <vsu@altlinux.ru> writes:
Show 24 quoted lines
> This is due to optimization in builtin-pack-objects.c:try_delta():
>
> 	/*
> 	 * We do not bother to try a delta that we discarded
> 	 * on an earlier try, but only when reusing delta data.
> 	 */
> 	if (!no_reuse_delta && trg_entry->in_pack &&
> 	    trg_entry->in_pack == src_entry->in_pack)
> 		return 0;
>
> After removing this part the shallow pack after clone is 2.6M, as it
> should be.
>
> The problem with this optimization is that it is only valid if we are
> repacking either the same set of objects as we did earlier, or its
> superset.  But if we are packing a subset of objects, there will be some
> objects in that subset which were delta-compressed in the original pack,
> but base objects for that deltas are not included in our subset -
> therefore we will be unable to reuse existing deltas, and with that
> optimization we will never try to use delta compression for these
> objects.
> ...
> So any partial fetch (shallow or not) from a mostly packed repository
> currently results in a suboptimal pack.
That is correct.  How about something like this?

I think the determination of "repacking_superset" may need to be tweaked because existing packs may have overlaps, and the patch counts them once per pack.

diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 69e5dd3..fb25124 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -64,6 +64,7 @@ struct object_entry {
 static unsigned char object_list_sha1[20];
 static int non_empty;
 static int no_reuse_delta;
+static int repacking_superset;
 static int local;
 static int incremental;
 static int allow_ofs_delta;
@@ -1172,10 +1173,13 @@ static int try_delta(struct unpacked *tr
 		return -1;
 
 	/*
-	 * We do not bother to try a delta that we discarded
-	 * on an earlier try, but only when reusing delta data.
+	 * When we are packing the superset of objects we have already
+	 * packed, we do not bother to try a delta that we discarded
+	 * on an earlier try.  This heuristic of course should not
+	 * kick in when we are not reusing delta, or we know we are
+	 * sending a subset of objects from a repository.
 	 */
-	if (!no_reuse_delta && trg_entry->in_pack &&
+	if (!no_reuse_delta && repacking_superset && trg_entry->in_pack &&
 	    trg_entry->in_pack == src_entry->in_pack)
 		return 0;
 
@@ -1493,6 +1497,16 @@ static void get_object_list(int ac, cons
 	traverse_commit_list(&revs, show_commit, show_object);
 }
 
+static int count_packed_objects(void)
+{
+	struct packed_git *p;
+	int cnt = 0;
+
+	for (p = packed_git; p; p = p->next)
+		cnt += num_packed_objects(p);
+	return cnt;
+}
+
 int cmd_pack_objects(int argc, const char **argv, const char *prefix)
 {
 	SHA_CTX ctx;
@@ -1631,6 +1645,8 @@ int cmd_pack_objects(int argc, const cha
 	if (non_empty && !nr_result)
 		return 0;
 
+	repacking_superset = count_packed_objects() < nr_result;
+
 	SHA1_Init(&ctx);
 	list = sorted_by_sha;
 	for (i = 0; i < nr_result; i++) {
Previous: Sergey VlasovNext: Junio C Hamano
Message 10 of 20 in “What's in git.git”
  1. Junio C HamanoNov 8, 2006
  2. David LangNov 8, 2006
  3. Shallow clone [Was Re: What's in git.git ]Aneesh Kumar K.V, Nov 8, 2006
  4. Aneesh Kumar K.VNov 8, 2006
  5. Junio C HamanoNov 9, 2006
  6. Aneesh KumarNov 9, 2006
  7. Alexandre JulliardNov 11, 2006
  8. Junio C HamanoNov 12, 2006
  9. Sergey VlasovNov 12, 2006
  10. Junio C HamanoNov 12, 2006
  11. Junio C HamanoNov 13, 2006
  12. Petr BaudisNov 12, 2006
  13. Junio C HamanoNov 12, 2006
  14. Johannes SchindelinNov 12, 2006
  15. Jakub NarebskiNov 8, 2006
  16. Junio C HamanoNov 8, 2006
  17. Jakub NarebskiNov 8, 2006
  18. Junio C HamanoNov 8, 2006
  19. Petr BaudisNov 8, 2006
  20. Junio C HamanoNov 9, 2006

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.