t / t5312-prune-corruption.shon commit Git 2.6.7 (70fcaef)
   1#!/bin/sh
   2
   3test_description='
   4Test pruning of repositories with minor corruptions. The goal
   5here is that we should always be erring on the side of safety. So
   6if we see, for example, a ref with a bogus name, it is OK either to
   7bail out or to proceed using it as a reachable tip, but it is _not_
   8OK to proceed as if it did not exist. Otherwise we might silently
   9delete objects that cannot be recovered.
  10'
  11. ./test-lib.sh
  12
  13test_expect_success 'disable reflogs' '
  14        git config core.logallrefupdates false &&
  15        git reflog expire --expire=all --all
  16'
  17
  18test_expect_success 'create history reachable only from a bogus-named ref' '
  19        test_tick && git commit --allow-empty -m master &&
  20        base=$(git rev-parse HEAD) &&
  21        test_tick && git commit --allow-empty -m bogus &&
  22        bogus=$(git rev-parse HEAD) &&
  23        git cat-file commit $bogus >saved &&
  24        echo $bogus >.git/refs/heads/bogus..name &&
  25        git reset --hard HEAD^
  26'
  27
  28test_expect_success 'pruning does not drop bogus object' '
  29        test_when_finished "git hash-object -w -t commit saved" &&
  30        test_might_fail git prune --expire=now &&
  31        verbose git cat-file -e $bogus
  32'
  33
  34test_expect_success 'put bogus object into pack' '
  35        git tag reachable $bogus &&
  36        git repack -ad &&
  37        git tag -d reachable &&
  38        verbose git cat-file -e $bogus
  39'
  40
  41test_expect_success 'destructive repack keeps packed object' '
  42        test_might_fail git repack -Ad --unpack-unreachable=now &&
  43        verbose git cat-file -e $bogus &&
  44        test_might_fail git repack -ad &&
  45        verbose git cat-file -e $bogus
  46'
  47
  48# subsequent tests will have different corruptions
  49test_expect_success 'clean up bogus ref' '
  50        rm .git/refs/heads/bogus..name
  51'
  52
  53# We create two new objects here, "one" and "two". Our
  54# master branch points to "two", which is deleted,
  55# corrupting the repository. But we'd like to make sure
  56# that the otherwise unreachable "one" is not pruned
  57# (since it is the user's best bet for recovering
  58# from the corruption).
  59#
  60# Note that we also point HEAD somewhere besides "two",
  61# as we want to make sure we test the case where we
  62# pick up the reference to "two" by iterating the refs,
  63# not by resolving HEAD.
  64test_expect_success 'create history with missing tip commit' '
  65        test_tick && git commit --allow-empty -m one &&
  66        recoverable=$(git rev-parse HEAD) &&
  67        git cat-file commit $recoverable >saved &&
  68        test_tick && git commit --allow-empty -m two &&
  69        missing=$(git rev-parse HEAD) &&
  70        git checkout --detach $base &&
  71        rm .git/objects/$(echo $missing | sed "s,..,&/,") &&
  72        test_must_fail git cat-file -e $missing
  73'
  74
  75test_expect_success 'pruning with a corrupted tip does not drop history' '
  76        test_when_finished "git hash-object -w -t commit saved" &&
  77        test_might_fail git prune --expire=now &&
  78        verbose git cat-file -e $recoverable
  79'
  80
  81test_expect_success 'pack-refs does not silently delete broken loose ref' '
  82        git pack-refs --all --prune &&
  83        echo $missing >expect &&
  84        git rev-parse refs/heads/master >actual &&
  85        test_cmp expect actual
  86'
  87
  88# we do not want to count on running pack-refs to
  89# actually pack it, as it is perfectly reasonable to
  90# skip processing a broken ref
  91test_expect_success 'create packed-refs file with broken ref' '
  92        rm -f .git/refs/heads/master &&
  93        cat >.git/packed-refs <<-EOF &&
  94        $missing refs/heads/master
  95        $recoverable refs/heads/other
  96        EOF
  97        echo $missing >expect &&
  98        git rev-parse refs/heads/master >actual &&
  99        test_cmp expect actual
 100'
 101
 102test_expect_success 'pack-refs does not silently delete broken packed ref' '
 103        git pack-refs --all --prune &&
 104        git rev-parse refs/heads/master >actual &&
 105        test_cmp expect actual
 106'
 107
 108test_expect_success 'pack-refs does not drop broken refs during deletion' '
 109        git update-ref -d refs/heads/other &&
 110        git rev-parse refs/heads/master >actual &&
 111        test_cmp expect actual
 112'
 113
 114test_done