let pack-objects do the writing of unreachable objects as loose objects

Commit ccc1297226 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>
This commit is contained in:
Nicolas Pitre
2008-05-14 01:33:53 -04:00
committed by Junio C Hamano
parent bbac73117e
commit ca11b212eb
2 changed files with 45 additions and 17 deletions

View File

@ -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
SUBDIRECTORY_OK='Yes'
. 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
do
@ -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"
then
args='--unpacked --incremental'
elif test -n "$unpack_unreachable"
then
args="$args $unpack_unreachable"
fi
;;
esac
@ -127,18 +130,7 @@ then
do
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" ;;
esac
done
)