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 rm -rf .git/logs 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 find .git/objects -type f | 76 xargs test-chmtime -v -86400 77 ' 78 79 test_expect_success "start writing new commit with old blob ($title)"' 80 tree=$( 81 GIT_INDEX_FILE=index.tmp && 82 export GIT_INDEX_FILE && 83 git read-tree HEAD && 84 add unrelated && 85 add abandon && 86 git write-tree 87 ) 88 ' 89 90 test_expect_success "simultaneous gc ($title)"' 91 git gc --prune=12.hours.ago 92 ' 93 94 test_expect_success "finish writing out commit ($title)"' 95 commit=$(echo foo | git commit-tree -p HEAD $tree)&& 96 git update-ref HEAD$commit 97 ' 98 99# "abandon" blob should have been rescued by reference from new tree 100 test_expect_success "repository passes fsck ($title)"' 101 git fsck 102 ' 103 104 test_expect_success "abandon objects again ($title)"' 105 git reset --hard HEAD^ && 106 find .git/objects -type f | 107 xargs test-chmtime -v -86400 108 ' 109 110 test_expect_success "start writing new commit with same tree ($title)"' 111 tree=$( 112 GIT_INDEX_FILE=index.tmp && 113 export GIT_INDEX_FILE && 114 git read-tree HEAD && 115 add abandon && 116 add unrelated && 117 git write-tree 118 ) 119 ' 120 121 test_expect_success "simultaneous gc ($title)"' 122 git gc --prune=12.hours.ago 123 ' 124 125# tree should have been refreshed by write-tree 126 test_expect_success "finish writing out commit ($title)"' 127 commit=$(echo foo | git commit-tree -p HEAD $tree)&& 128 git update-ref HEAD$commit 129 ' 130done 131 132test_expect_success 'do not complain about existing broken links'' 133 cat >broken-commit <<-\EOF && 134 tree 0000000000000000000000000000000000000001 135 parent 0000000000000000000000000000000000000002 136 author whatever <whatever@example.com> 1234 -0000 137 committer whatever <whatever@example.com> 1234 -0000 138 139 some message 140 EOF 141 commit=$(git hash-object -t commit -w broken-commit)&& 142 git gc 2>stderr && 143 verbose git cat-file -e$commit&& 144 test_must_be_empty stderr 145' 146 147test_done