From: Junio C Hamano Date: Tue, 16 Oct 2018 07:16:00 +0000 (+0900) Subject: Merge branch 'jk/delta-islands-with-bitmap-reuse-delta-fix' X-Git-Tag: v2.20.0-rc0~190 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/73b9c6f58358c2d6167f7a51ac06eee2fab6f5d8?ds=inline;hp=-c Merge branch 'jk/delta-islands-with-bitmap-reuse-delta-fix' Fix interactions between two recent topics. * jk/delta-islands-with-bitmap-reuse-delta-fix: pack-objects: handle island check for "external" delta base --- 73b9c6f58358c2d6167f7a51ac06eee2fab6f5d8 diff --combined builtin/pack-objects.c index e6316d294d,fb97bc5ae1..c6370f2716 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@@ -970,7 -970,8 +970,7 @@@ static int no_try_delta(const char *pat if (!check) check = attr_check_initl("delta", NULL); - if (git_check_attr(&the_index, path, check)) - return 0; + git_check_attr(&the_index, path, check); if (ATTR_FALSE(check->items[0].value)) return 1; return 0; @@@ -1247,7 -1248,7 +1247,7 @@@ static struct pbase_tree_cache *pbase_t */ for (neigh = 0; neigh < 8; neigh++) { ent = pbase_tree_cache[my_ix]; - if (ent && !oidcmp(&ent->oid, oid)) { + if (ent && oideq(&ent->oid, oid)) { ent->ref++; return ent; } @@@ -1429,7 -1430,7 +1429,7 @@@ static void add_preferred_base(struct o return; for (it = pbase_tree; it; it = it->next) { - if (!oidcmp(&it->pcache.oid, &tree_oid)) { + if (oideq(&it->pcache.oid, &tree_oid)) { free(data); return; } @@@ -1469,6 -1470,57 +1469,57 @@@ static void cleanup_preferred_base(void done_pbase_paths_num = done_pbase_paths_alloc = 0; } + /* + * Return 1 iff the object specified by "delta" can be sent + * literally as a delta against the base in "base_sha1". If + * so, then *base_out will point to the entry in our packing + * list, or NULL if we must use the external-base list. + * + * Depth value does not matter - find_deltas() will + * never consider reused delta as the base object to + * deltify other objects against, in order to avoid + * circular deltas. + */ + static int can_reuse_delta(const unsigned char *base_sha1, + struct object_entry *delta, + struct object_entry **base_out) + { + struct object_entry *base; + + if (!base_sha1) + return 0; + + /* + * First see if we're already sending the base (or it's explicitly in + * our "excluded" list). + */ + base = packlist_find(&to_pack, base_sha1, NULL); + if (base) { + if (!in_same_island(&delta->idx.oid, &base->idx.oid)) + return 0; + *base_out = base; + return 1; + } + + /* + * Otherwise, reachability bitmaps may tell us if the receiver has it, + * even if it was buried too deep in history to make it into the + * packing list. + */ + if (thin && bitmap_has_sha1_in_uninteresting(bitmap_git, base_sha1)) { + if (use_delta_islands) { + struct object_id base_oid; + hashcpy(base_oid.hash, base_sha1); + if (!in_same_island(&delta->idx.oid, &base_oid)) + return 0; + } + *base_out = NULL; + return 1; + } + + return 0; + } + static void check_object(struct object_entry *entry) { unsigned long canonical_size; @@@ -1555,22 -1607,7 +1606,7 @@@ break; } - if (base_ref && ( - (base_entry = packlist_find(&to_pack, base_ref, NULL)) || - (thin && - bitmap_has_sha1_in_uninteresting(bitmap_git, base_ref))) && - in_same_island(&entry->idx.oid, &base_entry->idx.oid)) { - /* - * If base_ref was set above that means we wish to - * reuse delta data, and either we found that object in - * the list of objects we want to pack, or it's one we - * know the receiver has. - * - * Depth value does not matter - find_deltas() will - * never consider reused delta as the base object to - * deltify other objects against, in order to avoid - * circular deltas. - */ + if (can_reuse_delta(base_ref, entry, &base_entry)) { oe_set_type(entry, entry->in_pack_type); SET_SIZE(entry, in_pack_size); /* delta size */ SET_DELTA_SIZE(entry, in_pack_size);