aboutsummaryrefslogtreecommitdiffstats
path: root/t/t6022-rev-list-missing.sh
blob: 127180e1c9a246769fb5bb7ede57f814abb4fc79 (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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/bin/sh

test_description='handling of missing objects in rev-list'

TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh

# We setup the repository with two commits, this way HEAD is always
# available and we can hide commit 1.
test_expect_success 'create repository and alternate directory' '
	test_commit 1 &&
	test_commit 2 &&
	test_commit 3 &&
	git tag -m "tag message" annot_tag HEAD~1 &&
	git tag regul_tag HEAD~1 &&
	git branch a_branch HEAD~1
'

# We manually corrupt the repository, which means that the commit-graph may
# contain references to already-deleted objects. We thus need to enable
# commit-graph paranoia to not returned these deleted commits from the graph.
GIT_COMMIT_GRAPH_PARANOIA=true
export GIT_COMMIT_GRAPH_PARANOIA

for obj in "HEAD~1" "HEAD~1^{tree}" "HEAD:1.t"
do
	test_expect_success "rev-list --missing=error fails with missing object $obj" '
		oid="$(git rev-parse $obj)" &&
		path=".git/objects/$(test_oid_to_path $oid)" &&

		mv "$path" "$path.hidden" &&
		test_when_finished "mv $path.hidden $path" &&

		test_must_fail git rev-list --missing=error --objects \
			--no-object-names HEAD
	'
done

for obj in "HEAD~1" "HEAD~1^{tree}" "HEAD:1.t"
do
	for action in "allow-any" "print"
	do
		test_expect_success "rev-list --missing=$action with missing $obj" '
			oid="$(git rev-parse $obj)" &&
			path=".git/objects/$(test_oid_to_path $oid)" &&

			# Before the object is made missing, we use rev-list to
			# get the expected oids.
			git rev-list --objects --no-object-names \
				HEAD ^$obj >expect.raw &&

			# Blobs are shared by all commits, so even though a commit/tree
			# might be skipped, its blob must be accounted for.
			if test $obj != "HEAD:1.t"
			then
				echo $(git rev-parse HEAD:1.t) >>expect.raw &&
				echo $(git rev-parse HEAD:2.t) >>expect.raw
			fi &&

			mv "$path" "$path.hidden" &&
			test_when_finished "mv $path.hidden $path" &&

			git rev-list --missing=$action --objects --no-object-names \
				HEAD >actual.raw &&

			# When the action is to print, we should also add the missing
			# oid to the expect list.
			case $action in
			allow-any)
				;;
			print)
				grep ?$oid actual.raw &&
				echo ?$oid >>expect.raw
				;;
			esac &&

			sort actual.raw >actual &&
			sort expect.raw >expect &&
			test_cmp expect actual
		'
	done
done

for missing_tip in "annot_tag" "regul_tag" "a_branch" "HEAD~1" "HEAD~1^{tree}" "HEAD:1.t"
do
	# We want to check that things work when both
	#   - all the tips passed are missing (case existing_tip = ""), and
	#   - there is one missing tip and one existing tip (case existing_tip = "HEAD")
	for existing_tip in "" "HEAD"
	do
		for action in "allow-any" "print"
		do
			test_expect_success "--missing=$action with tip '$missing_tip' missing and tip '$existing_tip'" '
				# Before the object is made missing, we use rev-list to
				# get the expected oids.
				if test "$existing_tip" = "HEAD"
				then
					git rev-list --objects --no-object-names \
						HEAD ^$missing_tip >expect.raw
				else
					>expect.raw
				fi &&

				# Blobs are shared by all commits, so even though a commit/tree
				# might be skipped, its blob must be accounted for.
				if test "$existing_tip" = "HEAD" && test $missing_tip != "HEAD:1.t"
				then
					echo $(git rev-parse HEAD:1.t) >>expect.raw &&
					echo $(git rev-parse HEAD:2.t) >>expect.raw
				fi &&

				missing_oid="$(git rev-parse $missing_tip)" &&

				if test "$missing_tip" = "annot_tag"
				then
					oid="$(git rev-parse $missing_tip^{commit})" &&
					echo "$missing_oid" >>expect.raw
				else
					oid="$missing_oid"
				fi &&

				path=".git/objects/$(test_oid_to_path $oid)" &&

				mv "$path" "$path.hidden" &&
				test_when_finished "mv $path.hidden $path" &&

				git rev-list --missing=$action --objects --no-object-names \
				     $missing_oid $existing_tip >actual.raw &&

				# When the action is to print, we should also add the missing
				# oid to the expect list.
				case $action in
				allow-any)
					;;
				print)
					grep ?$oid actual.raw &&
					echo ?$oid >>expect.raw
					;;
				esac &&

				sort actual.raw >actual &&
				sort expect.raw >expect &&
				test_cmp expect actual
			'
		done
	done
done

test_done