1#!/bin/sh 2# 3# This test covers the handling of objects which might have old 4# mtimes in the filesystem (because they were used previously) 5# and are just now becoming referenced again. 6# 7# We're going to do two things that are a little bit "fake" to 8# help make our simulation easier: 9# 10# 1. We'll turn off reflogs. You can still run into 11# problems with reflogs on, but your objects 12# don't get pruned until both the reflog expiration 13# has passed on their references, _and_ they are out 14# of prune's expiration period. Dropping reflogs 15# means we only have to deal with one variable in our tests, 16# but the results generalize. 17# 18# 2. We'll use a temporary index file to create our 19# works-in-progress. Most workflows would mention 20# referenced objects in the index, which prune takes 21# into account. However, many operations don't. For 22# example, a partial commit with "git commit foo" 23# will use a temporary index. Or they may not need 24# an index at all (e.g., creating a new commit 25# to refer to an existing tree). 26 27test_description='check pruning of dependent objects' 28. ./test-lib.sh 29 30# We care about reachability, so we do not want to use 31# the normal test_commit, which creates extra tags. 32add () { 33echo"$1">"$1"&& 34 git add "$1" 35} 36commit () { 37 test_tick && 38 add "$1"&& 39 git commit -m"$1" 40} 41 42maybe_repack () { 43iftest -n"$repack";then 44 git repack -ad 45fi 46} 47 48for repack in'' true;do 49 title=${repack:+repack} 50 title=${title:-loose} 51 52 test_expect_success "make repo completely empty ($title)"' 53 rm -rf .git && 54 git init 55 ' 56 57 test_expect_success "disable reflogs ($title)"' 58 git config core.logallrefupdates false && 59 git reflog expire --expire=all --all 60 ' 61 62 test_expect_success "setup basic history ($title)"' 63 commit base 64 ' 65 66 test_expect_success "create and abandon some objects ($title)"' 67 git checkout -b experiment && 68 commit abandon && 69 maybe_repack && 70 git checkout master && 71 git branch -D experiment 72 ' 73 74 test_expect_success "simulate time passing ($title)"' 75 test-tool chmtime --get -86400$(find .git/objects -type f) 76 ' 77 78 test_expect_success "start writing new commit with old blob ($title)"' 79 tree=$( 80 GIT_INDEX_FILE=index.tmp && 81 export GIT_INDEX_FILE && 82 git read-tree HEAD && 83 add unrelated && 84 add abandon && 85 git write-tree 86 ) 87 ' 88 89 test_expect_success "simultaneous gc ($title)"' 90 git gc --prune=12.hours.ago 91 ' 92 93 test_expect_success "finish writing out commit ($title)"' 94 commit=$(echo foo | git commit-tree -p HEAD $tree)&& 95 git update-ref HEAD$commit 96 ' 97 98# "abandon" blob should have been rescued by reference from new tree 99 test_expect_success "repository passes fsck ($title)"' 100 git fsck 101 ' 102 103 test_expect_success "abandon objects again ($title)"' 104 git reset --hard HEAD^ && 105 test-tool chmtime --get -86400$(find .git/objects -type f) 106 ' 107 108 test_expect_success "start writing new commit with same tree ($title)"' 109 tree=$( 110 GIT_INDEX_FILE=index.tmp && 111 export GIT_INDEX_FILE && 112 git read-tree HEAD && 113 add abandon && 114 add unrelated && 115 git write-tree 116 ) 117 ' 118 119 test_expect_success "simultaneous gc ($title)"' 120 git gc --prune=12.hours.ago 121 ' 122 123# tree should have been refreshed by write-tree 124 test_expect_success "finish writing out commit ($title)"' 125 commit=$(echo foo | git commit-tree -p HEAD $tree)&& 126 git update-ref HEAD$commit 127 ' 128done 129 130test_expect_success 'do not complain about existing broken links (commit)'' 131 cat >broken-commit <<-\EOF && 132 tree 0000000000000000000000000000000000000001 133 parent 0000000000000000000000000000000000000002 134 author whatever <whatever@example.com> 1234 -0000 135 committer whatever <whatever@example.com> 1234 -0000 136 137 some message 138 EOF 139 commit=$(git hash-object -t commit -w broken-commit)&& 140 git gc 2>stderr && 141 verbose git cat-file -e$commit&& 142 test_must_be_empty stderr 143' 144 145test_expect_success 'do not complain about existing broken links (tree)'' 146 cat >broken-tree <<-\EOF && 147 100644 blob 0000000000000000000000000000000000000003 foo 148 EOF 149 tree=$(git mktree --missing <broken-tree)&& 150 git gc 2>stderr && 151 git cat-file -e$tree&& 152 test_must_be_empty stderr 153' 154 155test_expect_success 'do not complain about existing broken links (tag)'' 156 cat >broken-tag <<-\EOF && 157 object 0000000000000000000000000000000000000004 158 type commit 159 tag broken 160 tagger whatever <whatever@example.com> 1234 -0000 161 162 this is a broken tag 163 EOF 164 tag=$(git hash-object -t tag -w broken-tag)&& 165 git gc 2>stderr && 166 git cat-file -e$tag&& 167 test_must_be_empty stderr 168' 169 170test_done