t7700-repack: add two new tests demonstrating repacking flaws
authorBrandon Casey <casey@nrlssc.navy.mil>
Fri, 20 Mar 2009 03:47:50 +0000 (22:47 -0500)
committerJunio C Hamano <gitster@pobox.com>
Fri, 20 Mar 2009 20:32:33 +0000 (13:32 -0700)
1) The new --kept-pack-only mechansim of rev-list/pack-objects has
     replaced --unpacked=.  This new mechansim does not operate solely on
     "local" packs now.  The result is that objects residing in an alternate
     pack which has a .keep file will not be repacked with repack -a.

     This flaw is only apparent when a commit object is the one residing in
     an alternate kept pack.

  2) The 'repack unpacked objects' and 'loosen unpacked objects' mechanisms
     of pack-objects, i.e. --keep-unreachable and --unpack-unreachable,
     now do not operate solely on local packs.  The --keep-unreachable
     option no longer has any callers, but --unpack-unreachable is used when
     repack is called with '-A -d' and the local repo has existing packs.
     In this case, objects residing in alternate, not-kept packs will be
     loosened, and then immediately deleted by repack's call to
     prune-packed.

     The test must manually call pack-objects to avoid the call to
     prune-packed that is made by repack when -d is used.

Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/t7700-repack.sh

index 3f602ea7de498e9e60bd61c8f58b66947c9923fe..fa4772101fda56116698f2063572ebfef8d4d46a 100755 (executable)
@@ -69,5 +69,49 @@ test_expect_success 'packed obs in alt ODB are repacked even when local repo is
        done
 '
 
+test_expect_failure 'packed obs in alternate ODB kept pack are repacked' '
+       # swap the .keep so the commit object is in the pack with .keep
+       for p in alt_objects/pack/*.pack
+       do
+               base_name=$(basename $p .pack)
+               if test -f alt_objects/pack/$base_name.keep
+               then
+                       rm alt_objects/pack/$base_name.keep
+               else
+                       touch alt_objects/pack/$base_name.keep
+               fi
+       done
+       git repack -a -d &&
+       myidx=$(ls -1 .git/objects/pack/*.idx) &&
+       test -f "$myidx" &&
+       for p in alt_objects/pack/*.idx; do
+               git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p"
+       done | while read sha1 rest; do
+               if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then
+                       echo "Missing object in local pack: $sha1"
+                       return 1
+               fi
+       done
+'
+
+test_expect_failure 'packed unreachable obs in alternate ODB are not loosened' '
+       rm -f alt_objects/pack/*.keep &&
+       mv .git/objects/pack/* alt_objects/pack/ &&
+       csha1=$(git rev-parse HEAD^{commit}) &&
+       git reset --hard HEAD^ &&
+       sleep 1 &&
+       git reflog expire --expire=now --expire-unreachable=now --all &&
+       # The pack-objects call on the next line is equivalent to
+       # git repack -A -d without the call to prune-packed
+       git pack-objects --honor-pack-keep --non-empty --all --reflog \
+           --unpack-unreachable </dev/null pack &&
+       rm -f .git/objects/pack/* &&
+       mv pack-* .git/objects/pack/ &&
+       test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |
+               egrep "^$csha1 " | sort | uniq | wc -l) &&
+       echo > .git/objects/info/alternates &&
+       test_must_fail git show $csha1
+'
+
 test_done