revision: mark non-user-given objects instead
[git] / t / t6112-rev-list-filters-objects.sh
1 #!/bin/sh
2
3 test_description='git rev-list using object filtering'
4
5 . ./test-lib.sh
6
7 # Test the blob:none filter.
8
9 test_expect_success 'setup r1' '
10         echo "{print \$1}" >print_1.awk &&
11         echo "{print \$2}" >print_2.awk &&
12
13         git init r1 &&
14         for n in 1 2 3 4 5
15         do
16                 echo "This is file: $n" > r1/file.$n
17                 git -C r1 add file.$n
18                 git -C r1 commit -m "$n"
19         done
20 '
21
22 test_expect_success 'verify blob:none omits all 5 blobs' '
23         git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 \
24                 | awk -f print_2.awk \
25                 | sort >expected &&
26         git -C r1 rev-list HEAD --quiet --objects --filter-print-omitted --filter=blob:none \
27                 | awk -f print_1.awk \
28                 | sed "s/~//" \
29                 | sort >observed &&
30         test_cmp observed expected
31 '
32
33 test_expect_success 'specify blob explicitly prevents filtering' '
34         file_3=$(git -C r1 ls-files -s file.3 |
35                  awk -f print_2.awk) &&
36
37         file_4=$(git -C r1 ls-files -s file.4 |
38                  awk -f print_2.awk) &&
39
40         git -C r1 rev-list --objects --filter=blob:none HEAD $file_3 >observed &&
41         grep -q "$file_3" observed &&
42         test_must_fail grep -q "$file_4" observed
43 '
44
45 test_expect_success 'verify emitted+omitted == all' '
46         git -C r1 rev-list HEAD --objects \
47                 | awk -f print_1.awk \
48                 | sort >expected &&
49         git -C r1 rev-list HEAD --objects --filter-print-omitted --filter=blob:none \
50                 | awk -f print_1.awk \
51                 | sed "s/~//" \
52                 | sort >observed &&
53         test_cmp observed expected
54 '
55
56
57 # Test blob:limit=<n>[kmg] filter.
58 # We boundary test around the size parameter.  The filter is strictly less than
59 # the value, so size 500 and 1000 should have the same results, but 1001 should
60 # filter more.
61
62 test_expect_success 'setup r2' '
63         git init r2 &&
64         for n in 1000 10000
65         do
66                 printf "%"$n"s" X > r2/large.$n
67                 git -C r2 add large.$n
68                 git -C r2 commit -m "$n"
69         done
70 '
71
72 test_expect_success 'verify blob:limit=500 omits all blobs' '
73         git -C r2 ls-files -s large.1000 large.10000 \
74                 | awk -f print_2.awk \
75                 | sort >expected &&
76         git -C r2 rev-list HEAD --quiet --objects --filter-print-omitted --filter=blob:limit=500 \
77                 | awk -f print_1.awk \
78                 | sed "s/~//" \
79                 | sort >observed &&
80         test_cmp observed expected
81 '
82
83 test_expect_success 'verify emitted+omitted == all' '
84         git -C r2 rev-list HEAD --objects \
85                 | awk -f print_1.awk \
86                 | sort >expected &&
87         git -C r2 rev-list HEAD --objects --filter-print-omitted --filter=blob:limit=500 \
88                 | awk -f print_1.awk \
89                 | sed "s/~//" \
90                 | sort >observed &&
91         test_cmp observed expected
92 '
93
94 test_expect_success 'verify blob:limit=1000' '
95         git -C r2 ls-files -s large.1000 large.10000 \
96                 | awk -f print_2.awk \
97                 | sort >expected &&
98         git -C r2 rev-list HEAD --quiet --objects --filter-print-omitted --filter=blob:limit=1000 \
99                 | awk -f print_1.awk \
100                 | sed "s/~//" \
101                 | sort >observed &&
102         test_cmp observed expected
103 '
104
105 test_expect_success 'verify blob:limit=1001' '
106         git -C r2 ls-files -s large.10000 \
107                 | awk -f print_2.awk \
108                 | sort >expected &&
109         git -C r2 rev-list HEAD --quiet --objects --filter-print-omitted --filter=blob:limit=1001 \
110                 | awk -f print_1.awk \
111                 | sed "s/~//" \
112                 | sort >observed &&
113         test_cmp observed expected
114 '
115
116 test_expect_success 'verify blob:limit=1k' '
117         git -C r2 ls-files -s large.10000 \
118                 | awk -f print_2.awk \
119                 | sort >expected &&
120         git -C r2 rev-list HEAD --quiet --objects --filter-print-omitted --filter=blob:limit=1k \
121                 | awk -f print_1.awk \
122                 | sed "s/~//" \
123                 | sort >observed &&
124         test_cmp observed expected
125 '
126
127 test_expect_success 'verify blob:limit=1m' '
128         cat </dev/null >expected &&
129         git -C r2 rev-list HEAD --quiet --objects --filter-print-omitted --filter=blob:limit=1m \
130                 | awk -f print_1.awk \
131                 | sed "s/~//" \
132                 | sort >observed &&
133         test_cmp observed expected
134 '
135
136 # Test sparse:path=<path> filter.
137 # Use a local file containing a sparse-checkout specification to filter
138 # out blobs not required for the corresponding sparse-checkout.  We do not
139 # require sparse-checkout to actually be enabled.
140
141 test_expect_success 'setup r3' '
142         git init r3 &&
143         mkdir r3/dir1 &&
144         for n in sparse1 sparse2
145         do
146                 echo "This is file: $n" > r3/$n
147                 git -C r3 add $n
148                 echo "This is file: dir1/$n" > r3/dir1/$n
149                 git -C r3 add dir1/$n
150         done &&
151         git -C r3 commit -m "sparse" &&
152         echo dir1/ >pattern1 &&
153         echo sparse1 >pattern2
154 '
155
156 test_expect_success 'verify sparse:path=pattern1 omits top-level files' '
157         git -C r3 ls-files -s sparse1 sparse2 \
158                 | awk -f print_2.awk \
159                 | sort >expected &&
160         git -C r3 rev-list HEAD --quiet --objects --filter-print-omitted --filter=sparse:path=../pattern1 \
161                 | awk -f print_1.awk \
162                 | sed "s/~//" \
163                 | sort >observed &&
164         test_cmp observed expected
165 '
166
167 test_expect_success 'verify sparse:path=pattern2 omits both sparse2 files' '
168         git -C r3 ls-files -s sparse2 dir1/sparse2 \
169                 | awk -f print_2.awk \
170                 | sort >expected &&
171         git -C r3 rev-list HEAD --quiet --objects --filter-print-omitted --filter=sparse:path=../pattern2 \
172                 | awk -f print_1.awk \
173                 | sed "s/~//" \
174                 | sort >observed &&
175         test_cmp observed expected
176 '
177
178 # Test sparse:oid=<oid-ish> filter.
179 # Like sparse:path, but we get the sparse-checkout specification from
180 # a blob rather than a file on disk.
181
182 test_expect_success 'setup r3 part 2' '
183         echo dir1/ >r3/pattern &&
184         git -C r3 add pattern &&
185         git -C r3 commit -m "pattern"
186 '
187
188 test_expect_success 'verify sparse:oid=OID omits top-level files' '
189         git -C r3 ls-files -s pattern sparse1 sparse2 \
190                 | awk -f print_2.awk \
191                 | sort >expected &&
192         oid=$(git -C r3 ls-files -s pattern | awk -f print_2.awk) &&
193         git -C r3 rev-list HEAD --quiet --objects --filter-print-omitted --filter=sparse:oid=$oid \
194                 | awk -f print_1.awk \
195                 | sed "s/~//" \
196                 | sort >observed &&
197         test_cmp observed expected
198 '
199
200 test_expect_success 'verify sparse:oid=oid-ish omits top-level files' '
201         git -C r3 ls-files -s pattern sparse1 sparse2 \
202                 | awk -f print_2.awk \
203                 | sort >expected &&
204         git -C r3 rev-list HEAD --quiet --objects --filter-print-omitted --filter=sparse:oid=master:pattern \
205                 | awk -f print_1.awk \
206                 | sed "s/~//" \
207                 | sort >observed &&
208         test_cmp observed expected
209 '
210
211 test_expect_success 'rev-list W/ --missing=print and --missing=allow-any for trees' '
212         TREE=$(git -C r3 rev-parse HEAD:dir1) &&
213
214         # Create a spare repo because we will be deleting objects from this one.
215         git clone r3 r3.b &&
216
217         rm r3.b/.git/objects/$(echo $TREE | sed "s|^..|&/|") &&
218
219         git -C r3.b rev-list --quiet --missing=print --objects HEAD \
220                 >missing_objs 2>rev_list_err &&
221         echo "?$TREE" >expected &&
222         test_cmp expected missing_objs &&
223
224         # do not complain when a missing tree cannot be parsed
225         test_must_be_empty rev_list_err &&
226
227         git -C r3.b rev-list --missing=allow-any --objects HEAD \
228                 >objs 2>rev_list_err &&
229         ! grep $TREE objs &&
230         test_must_be_empty rev_list_err
231 '
232
233 # Delete some loose objects and use rev-list, but WITHOUT any filtering.
234 # This models previously omitted objects that we did not receive.
235
236 test_expect_success 'rev-list W/ --missing=print' '
237         git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 \
238                 | awk -f print_2.awk \
239                 | sort >expected &&
240         for id in `cat expected | sed "s|..|&/|"`
241         do
242                 rm r1/.git/objects/$id
243         done &&
244         git -C r1 rev-list --quiet HEAD --missing=print --objects \
245                 | awk -f print_1.awk \
246                 | sed "s/?//" \
247                 | sort >observed &&
248         test_cmp observed expected
249 '
250
251 test_expect_success 'rev-list W/O --missing fails' '
252         test_must_fail git -C r1 rev-list --quiet --objects HEAD
253 '
254
255 test_expect_success 'rev-list W/ missing=allow-any' '
256         git -C r1 rev-list --quiet --missing=allow-any --objects HEAD
257 '
258
259 test_done