summaryrefslogtreecommitdiff
path: root/builtin-pack-objects.c
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2008-05-14 01:33:53 -0400
committerJunio C Hamano <gitster@pobox.com>2008-05-13 22:45:44 -0700
commitca11b212eb3e31d6fee12e9974c67dc774c1bc7c (patch)
treec0cff00613a44170ae34b86f89f30536ed99211c /builtin-pack-objects.c
parentbbac73117ebed9f02ccae3df45f4baa0c793dab7 (diff)
downloadgit-ca11b212eb3e31d6fee12e9974c67dc774c1bc7c.tar.gz
let pack-objects do the writing of unreachable objects as loose objects
Commit ccc1297226b184c40459e9d373cc9eebfb7bd898 changed the behavior of 'git repack -A' so unreachable objects are stored as loose objects. However it did so in a naive and inn efficient way by making packs about to be deleted inaccessible and feeding their content through 'git unpack-objects'. While this works, there are major flaws with this approach: - It is unacceptably sloooooooooooooow. In the Linux kernel repository with no actual unreachable objects, doing 'git repack -A -d' before: real 2m33.220s user 2m21.675s sys 0m3.510s And with this change: real 0m36.849s user 0m24.365s sys 0m1.950s For reference, here's the timing for 'git repack -a -d': real 0m35.816s user 0m22.571s sys 0m2.011s This is explained by the fact that 'git unpack-objects' was used to unpack _every_ objects even if (almost) 100% of them were thrown away. - There is a black out period. Between the removal of the .idx file for the redundant pack and the completion of its unpacking, the unreachable objects become completely unaccessible. This is not a big issue as we're talking about unreachable objects, but some consistency is always good. - There is no way to easily set a sensible mtime for the newly created unreachable loose objects. So, while having a command called "pack-objects" to perform object unpacking looks really odd, this is probably the best compromize to be able to solve the above issues in an efficient way. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-pack-objects.c')
-rw-r--r--builtin-pack-objects.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 777f272668..5a10119fbd 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -28,7 +28,8 @@ git-pack-objects [{ -q | --progress | --all-progress }] \n\
[--window=N] [--window-memory=N] [--depth=N] \n\
[--no-reuse-delta] [--no-reuse-object] [--delta-base-offset] \n\
[--threads=N] [--non-empty] [--revs [--unpacked | --all]*] [--reflog] \n\
- [--stdout | base-name] [--include-tag] [--keep-unreachable] \n\
+ [--stdout | base-name] [--include-tag] \n\
+ [--keep-unreachable | --unpack-unreachable] \n\
[<ref-list | <object-list]";
struct object_entry {
@@ -65,7 +66,7 @@ static struct pack_idx_entry **written_list;
static uint32_t nr_objects, nr_alloc, nr_result, nr_written;
static int non_empty;
-static int no_reuse_delta, no_reuse_object, keep_unreachable, include_tag;
+static int no_reuse_delta, no_reuse_object, keep_unreachable, unpack_unreachable, include_tag;
static int local;
static int incremental;
static int allow_ofs_delta;
@@ -1905,6 +1906,32 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
free(in_pack.array);
}
+static void loosen_unused_packed_objects(struct rev_info *revs)
+{
+ struct packed_git *p;
+ uint32_t i;
+ const unsigned char *sha1;
+
+ for (p = packed_git; p; p = p->next) {
+ for (i = 0; i < revs->num_ignore_packed; i++) {
+ if (matches_pack_name(p, revs->ignore_packed[i]))
+ break;
+ }
+ if (revs->num_ignore_packed <= i)
+ continue;
+
+ if (open_pack_index(p))
+ die("cannot open pack index");
+
+ for (i = 0; i < p->num_objects; i++) {
+ sha1 = nth_packed_object_sha1(p, i);
+ if (!locate_object_entry(sha1))
+ if (force_object_loose(sha1, p->mtime))
+ die("unable to force loose object");
+ }
+ }
+}
+
static void get_object_list(int ac, const char **av)
{
struct rev_info revs;
@@ -1939,6 +1966,8 @@ static void get_object_list(int ac, const char **av)
if (keep_unreachable)
add_objects_in_unpacked_packs(&revs);
+ if (unpack_unreachable)
+ loosen_unused_packed_objects(&revs);
}
static int adjust_perm(const char *path, mode_t mode)
@@ -2073,6 +2102,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
keep_unreachable = 1;
continue;
}
+ if (!strcmp("--unpack-unreachable", arg)) {
+ unpack_unreachable = 1;
+ continue;
+ }
if (!strcmp("--include-tag", arg)) {
include_tag = 1;
continue;
@@ -2138,6 +2171,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
if (!pack_to_stdout && thin)
die("--thin cannot be used to build an indexable pack.");
+ if (keep_unreachable && unpack_unreachable)
+ die("--keep-unreachable and --unpack-unreachable are incompatible.");
+
#ifdef THREADED_DELTA_SEARCH
if (!delta_search_threads) /* --threads=0 means autodetect */
delta_search_threads = online_cpus();