path: root/
diff options
authorNicolas Pitre <>2008-05-14 05:33:53 (GMT)
committerJunio C Hamano <>2008-05-14 05:45:44 (GMT)
commitca11b212eb3e31d6fee12e9974c67dc774c1bc7c (patch)
treec0cff00613a44170ae34b86f89f30536ed99211c /
parentbbac73117ebed9f02ccae3df45f4baa0c793dab7 (diff)
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 <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to '')
1 files changed, 7 insertions, 15 deletions
diff --git a/ b/
index a0e06ed..607f217 100755
--- a/
+++ b/
@@ -8,7 +8,7 @@ OPTIONS_SPEC="\
git-repack [options]
a pack everything in a single pack
-A same as -a, and keep unreachable objects too
+A same as -a, and turn unreachable objects loose
d remove redundant packs, and run git-prune-packed
f pass --no-reuse-delta to git-pack-objects
q,quiet be quiet
@@ -22,7 +22,7 @@ max-pack-size= maximum size of each packfile
. git-sh-setup
-no_update_info= all_into_one= remove_redundant= keep_unreachable=
+no_update_info= all_into_one= remove_redundant= unpack_unreachable=
local= quiet= no_reuse= extra=
while test $# != 0
@@ -30,7 +30,7 @@ do
-n) no_update_info=t ;;
-a) all_into_one=t ;;
-A) all_into_one=t
- keep_unreachable=t ;;
+ unpack_unreachable=--unpack-unreachable ;;
-d) remove_redundant=t ;;
-q) quiet=-q ;;
-f) no_reuse=--no-reuse-object ;;
@@ -78,6 +78,9 @@ case ",$all_into_one," in
if test -z "$args"
args='--unpacked --incremental'
+ elif test -n "$unpack_unreachable"
+ then
+ args="$args $unpack_unreachable"
@@ -127,18 +130,7 @@ then
case " $fullbases " in
*" $e "*) ;;
- *)
- rm -f "$e.idx" "$e.keep"
- if test -n "$keep_unreachable" &&
- test -f "$e.pack"
- then
- git unpack-objects < "$e.pack" || {
- echo >&2 "Failed unpacking unreachable objects from redundant pack file $e.pack"
- exit 1
- }
- fi
- rm -f "$e.pack"
- ;;
+ *) rm -f "$e.pack" "$e.idx" "$e.keep" ;;