aboutsummaryrefslogtreecommitdiff
path: root/t/t6501-freshen-objects.sh
blob: 157f3f91db1e54f3069e45a5087cdb6a8838c7db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/bin/sh
#
# This test covers the handling of objects which might have old
# mtimes in the filesystem (because they were used previously)
# and are just now becoming referenced again.
#
# We're going to do two things that are a little bit "fake" to
# help make our simulation easier:
#
#   1. We'll turn off reflogs. You can still run into
#      problems with reflogs on, but your objects
#      don't get pruned until both the reflog expiration
#      has passed on their references, _and_ they are out
#      of prune's expiration period. Dropping reflogs
#      means we only have to deal with one variable in our tests,
#      but the results generalize.
#
#   2. We'll use a temporary index file to create our
#      works-in-progress. Most workflows would mention
#      referenced objects in the index, which prune takes
#      into account. However, many operations don't. For
#      example, a partial commit with "git commit foo"
#      will use a temporary index. Or they may not need
#      an index at all (e.g., creating a new commit
#      to refer to an existing tree).

test_description='check pruning of dependent objects'
. ./test-lib.sh

# We care about reachability, so we do not want to use
# the normal test_commit, which creates extra tags.
add () {
	echo "$1" >"$1" &&
	git add "$1"
}
commit () {
	test_tick &&
	add "$1" &&
	git commit -m "$1"
}

maybe_repack () {
	if test -n "$repack"; then
		git repack -ad
	fi
}

for repack in '' true; do
	title=${repack:+repack}
	title=${title:-loose}

	test_expect_success "make repo completely empty ($title)" '
		rm -rf .git &&
		git init
	'

	test_expect_success "disable reflogs ($title)" '
		git config core.logallrefupdates false &&
		rm -rf .git/logs
	'

	test_expect_success "setup basic history ($title)" '
		commit base
	'

	test_expect_success "create and abandon some objects ($title)" '
		git checkout -b experiment &&
		commit abandon &&
		maybe_repack &&
		git checkout master &&
		git branch -D experiment
	'

	test_expect_success "simulate time passing ($title)" '
		find .git/objects -type f |
		xargs test-chmtime -v -86400
	'

	test_expect_success "start writing new commit with old blob ($title)" '
		tree=$(
			GIT_INDEX_FILE=index.tmp &&
			export GIT_INDEX_FILE &&
			git read-tree HEAD &&
			add unrelated &&
			add abandon &&
			git write-tree
		)
	'

	test_expect_success "simultaneous gc ($title)" '
		git gc --prune=12.hours.ago
	'

	test_expect_success "finish writing out commit ($title)" '
		commit=$(echo foo | git commit-tree -p HEAD $tree) &&
		git update-ref HEAD $commit
	'

	# "abandon" blob should have been rescued by reference from new tree
	test_expect_success "repository passes fsck ($title)" '
		git fsck
	'

	test_expect_success "abandon objects again ($title)" '
		git reset --hard HEAD^ &&
		find .git/objects -type f |
		xargs test-chmtime -v -86400
	'

	test_expect_success "start writing new commit with same tree ($title)" '
		tree=$(
			GIT_INDEX_FILE=index.tmp &&
			export GIT_INDEX_FILE &&
			git read-tree HEAD &&
			add abandon &&
			add unrelated &&
			git write-tree
		)
	'

	test_expect_success "simultaneous gc ($title)" '
		git gc --prune=12.hours.ago
	'

	# tree should have been refreshed by write-tree
	test_expect_success "finish writing out commit ($title)" '
		commit=$(echo foo | git commit-tree -p HEAD $tree) &&
		git update-ref HEAD $commit
	'
done

test_done