-
-
Notifications
You must be signed in to change notification settings - Fork 344
/
Copy pathmake_rev_spec_parse_repos.sh
executable file
·427 lines (354 loc) · 11.1 KB
/
make_rev_spec_parse_repos.sh
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
#!/usr/bin/env bash
set -eu -o pipefail
function baseline() {
local spec=${1:?first argument is the spec to test}
{
echo "$spec"
git rev-parse -q --verify "$spec" 2>/dev/null || echo $?
}>> baseline.git
}
# The contents of this file is based on https://github.com/git/git/blob/8168d5e9c23ed44ae3d604f392320d66556453c9/t/t1512-rev-parse-disambiguation.sh#L38
git init --bare blob.prefix
(
cd blob.prefix
# Both start with "dead..", under both SHA-1 and SHA-256
echo brocdnra | git hash-object -w --stdin
echo brigddsv | git hash-object -w --stdin
# Both start with "beef.."
echo 1agllotbh | git hash-object -w --stdin
echo 1bbfctrkc | git hash-object -w --stdin
baseline "dead"
baseline "beef"
)
git init --bare blob.bad
(
cd blob.bad
# Both have the prefix "bad0"
# Maybe one day we have a test to see how disambiguation reporting deals with this.
echo xyzfaowcoh | git hash-object -t bad -w --stdin --literally
echo xyzhjpyvwl | git hash-object -t bad -w --stdin --literally
baseline "bad0"
echo 1bbfctrkc | git hash-object -t bad -w --stdin --literally
baseline "e328"
baseline "e328^{object}"
)
function oid_to_path() {
local basename=${1#??}
echo "${1%$basename}/$basename"
}
git init --bare blob.corrupt
(
cd blob.corrupt
# Both have the prefix "cafe".
# Maybe one day we have a test to see how disambiguation reporting deals with this.
echo bnkxmdwz | git hash-object -w --stdin
oid=$(echo bmwsjxzi | git hash-object -w --stdin)
oidf=objects/$(oid_to_path "$oid")
chmod 755 $oidf
echo broken >$oidf
baseline "cafea"
baseline "cafea^{object}"
)
# This function writes out its parameters, one per line
function write_lines () {
printf "%s\n" "$@"
}
function tick () {
if test -z "${tick+set}"
then
tick=1112911993
else
tick=$(($tick + 60))
fi
GIT_COMMITTER_DATE="$tick -0700"
GIT_AUTHOR_DATE="$tick -0700"
export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
}
GIT_AUTHOR_NAME='A U Thor'
GIT_AUTHOR_DATE='1112354055 +0200'
TEST_COMMITTER_LOCALNAME=committer
TEST_COMMITTER_DOMAIN=example.com
GIT_COMMITTER_NAME='C O Mitter'
GIT_COMMITTER_DATE='1112354055 +0200'
git init ambiguous_blob_tree_commit
(
tick
cd ambiguous_blob_tree_commit
(
write_lines 0 1 2 3 4 5 6 7 8 9
echo
echo b1rwzyc3
) >a0blgqsjc
# create one blob 0000000000b36
git add a0blgqsjc
# create one tree 0000000000cdc
git write-tree
sed -e "s/|$//" >patch <<EOF
diff --git a/frotz b/frotz
index 000000000..ffffff 100644
--- a/frotz
+++ b/frotz
@@ -10,3 +10,4 @@
9
|
b1rwzyc3
+irwry
EOF
(
GIT_INDEX_FILE=frotz
export GIT_INDEX_FILE
git apply --build-fake-ancestor frotz patch
)
# create one commit 0000000000e4f
git commit -m a2onsxbvj
# this commit is ffffffd8 and not ambiguous with the 00000* objects.
# This is not relevant to gitoxide but we need the complete history.
echo "hoaxj" | git commit-tree 0000000000cdc -p 000000000
baseline "0000000000"
baseline "0000000000cdc:a0blgqsjc" # unambiguous by nature
baseline "0000000000:a0blgqsjc" # would be ambiguous, but only trees can have this syntax
baseline "0000000000cdc:missing" # definitely not present
baseline "0000000000cdc^{tree}" # unambiguous with tree assertion
baseline "0000000000^{tree}" # ambiguous with tree assertion, but git can't do it
baseline "0000000000e4f" # unambiguous
baseline "0000000000e" # unambiguous
baseline "0000000000e4f^{commit}" # and with commit assertion
baseline "0000000000^{commit}" # ambiguous name, but there is only one commit, but git can't do it
baseline "0000000000^0" # another transformation that only works for commits
baseline "0000000000f8f" # disambiguated tag
baseline "0000000000^{tag}" # disambiguated by type, but git can't do it
baseline "000000000..000000000" # only one commit is present with this prefix and we prefer these in ranges
baseline "..000000000"
baseline "000000000.."
baseline "000000000...000000000" # only one commit is present with this prefix and we prefer these in ranges
baseline "...000000000"
baseline "000000000..."
baseline "0000000000^{/x}" # disambiguation thanks to a commit being required
baseline "@^{/x}" # the same, but with named revision
baseline "@^{/^.*x}" # regex are available in git
cd ..
git clone ambiguous_blob_tree_commit ambiguous_commits
cd ambiguous_commits;
# create one tag 0000000000f8f (making the previous baseline tests ambiguous, but it could be unambiguous since they point to the same commit)
git tag -a -m j7cp83um v1.0.0
baseline "0000000000f8" # unambiguous
baseline "0000000000^{tag}" # git can't do this yet
baseline "v1.0.0-0-g0000000000e4f" # unambiguous commit
baseline "v1.0.0-0-g0000000000" # ambiguous commit, but we know we need a commit here. The tag doesn't matter.
# commit 0000000000043
git mv a0blgqsjc d12cr3h8t
echo h62xsjeu >>d12cr3h8t
git add d12cr3h8t
tick
git commit -m czy8f73t
# commit 00000000008ec
git mv d12cr3h8t j000jmpzn
echo j08bekfvt >>j000jmpzn
git add j000jmpzn
tick
git commit -m ioiley5o
# commit 0000000005b0
git checkout v1.0.0^0
git mv a0blgqsjc f5518nwu
write_lines h62xsjeu j08bekfvt kg7xflhm >>f5518nwu
git add f5518nwu
tick
git commit -m b3wettvi
side=$(git rev-parse HEAD)
# commit 000000000066
git checkout main
# If you use recursive, merge will fail and you will need to
# clean up a0blgqsjc as well. If you use resolve, merge will
# succeed.
git merge --no-commit -s recursive $side || true
git rm -f f5518nwu j000jmpzn
git rm -f a0blgqsjc
(
git cat-file blob $side:f5518nwu
echo j3l0i9s6
) >ab2gs879
git add ab2gs879
tick
git commit -m ad2uee
baseline "0000000000f^{tree}" # there is a tag, tree and blob with this prefix, and tags can also be trees thus this is ambiguous if the tree is different
baseline "00000000^{commit}" # this fails as there are many commits with this prefix now
baseline "v1.0.0-0-g000000000" # git doesn't take advantage of the generation and anchor reference yet
baseline "v1.0.0-2-g000000000" # ^
baseline "v1.0.0-4-g000000000" # ^
baseline "v1.0.0-1-g000000000" # This should legitimately fail (currently git accidentally fails) as there are two commits at gen 1 with this prefix.
baseline "000000000..000000000" # only one commit is present with this prefix and we prefer these in ranges
baseline "..000000000"
baseline "000000000.."
baseline "000000000...000000000" # only one commit is present with this prefix and we prefer these in ranges
baseline "...000000000"
baseline "000000000..."
baseline "00000000006^!" # exclude parents (without anything related to ambiguity
baseline "00000000006^@" # include parents (without actual commit)
)
git clone ambiguous_commits duplicate_ambiguous_objects
(
cd duplicate_ambiguous_objects
git rev-parse --disambiguate=000000000 >expect
git pack-objects .git/objects/pack/pack <expect
git rev-parse --disambiguate=000000000 >actual
diff actual expect # git deduplicates the same objects even though they are in the loose and packed odb
)
git clone ambiguous_blob_tree_commit ambiguous_refs
(
cd ambiguous_refs
TREE=$(git mktree </dev/null)
REF=$(git rev-parse HEAD)
VAL=$(git commit-tree $TREE </dev/null)
git update-ref refs/heads/$REF $VAL
baseline "$REF" # there is a ref and an object with the same name
TREE=$(git mktree </dev/null)
REF=$(git rev-parse --short HEAD)
VAL=$(git commit-tree $TREE </dev/null)
git update-ref refs/heads/$REF $VAL
baseline "$REF" # there is a ref and an object with the same name
)
for name in committish treeish tree commit blob; do
clone_dir=ambiguous_objects_disambiguation_config_$name
git clone ambiguous_commits $clone_dir
(
cd $clone_dir
git config core.disambiguate $name
baseline "0000000000"
baseline "0000000000f"
baseline "0000000000f^{tree}"
baseline "00000000000..00000000000"
)
done
git init complex_graph
(
cd complex_graph
tick
echo g > file
git add file && git commit -m $'G\n\n initial message'
git branch g
tick
git checkout --orphan=h
echo h > file
git add file && git commit -m H
tick
git checkout main
git merge h --allow-unrelated-histories || :
{ echo g && echo h && echo d; } > file
git add file
git commit -m D
git branch d
tick
git checkout --orphan=i
echo i > file
git add file && git commit -m I
git tag -m I-tag i-tag
tick
git checkout --orphan=j
echo j > file
git add file && git commit -m J
tick
git checkout i
git merge j --allow-unrelated-histories || :
{ echo i && echo j && echo f; } > file
git add file
git commit -m F
git branch f
tick
git checkout --orphan=e
echo e > file
git add file && git commit -m E
tick
git checkout main
git merge e i --allow-unrelated-histories || :
{ echo g && echo h && echo i && echo j && echo d && echo e && echo f && echo b; } > file
git add file && git commit -m B
git tag -m b-tag b-tag && git branch b
tick
git checkout i
echo c >> file
git add file && git commit -m $'C\n\n message recent'
git branch c
git reset --hard i-tag
tick
git checkout main
git merge c || :
{ echo g && echo h && echo i && echo j && echo d && echo e && echo f && echo b && echo c && echo a; } > file
git add file && git commit -m A
git branch a
git remote add origin .
cat <<EOF>>.git/config
[branch "main"]
remote = origin
merge = refs/heads/main
EOF
git fetch
baseline ":/message" # finds 'message recent' instead of 'initial message'
baseline ":/!-message" # above, negated
baseline ":/mes.age" # regexes work too
baseline ":/!-mes.age" # negated above
baseline ":/not there" # definitely not in graph
baseline "@^{/!-B}" # negation from branch
baseline ":file" # index lookup, default stage 0
baseline ":1:file" # stage 1
baseline ":foo" # not found
# parents
baseline "a"
baseline "a^1"
baseline "a~1"
baseline "a^0"
baseline "a~0"
baseline "a^42"
baseline "a~42"
baseline "a~3"
baseline "b"
baseline "a^"
baseline "c"
baseline "a^2"
baseline "d"
baseline "a^^"
baseline "a^1^1"
baseline "a~2"
baseline "e"
baseline "a^^2"
baseline "j"
baseline "b^3^2"
baseline "a^^3^2"
baseline "@{-1}"
baseline "@{-2}"
baseline "@{-3}"
baseline "@{-4}"
baseline "@{-5}"
baseline "@{-6}"
baseline "@{0}"
baseline "@{3}"
baseline "HEAD@{5}"
baseline "main@{12345}"
baseline "@^{}"
baseline "main^{}"
baseline "b-tag^{}"
baseline "@^{tree}"
baseline "@:"
baseline "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
baseline @{push}
baseline main@{push}
baseline main@{upstream}
baseline @{upstream}
baseline "^"
baseline "^!"
baseline "..."
baseline @..@
baseline @...@
)
git init new
(cd new
baseline '@{1}'
)
git init invalid-head
(cd invalid-head
>file && git add file && git commit -m "init"
rm .git/refs/heads/main
baseline 'HEAD'
baseline 'HEAD:file'
)