Start the 2.46 cycle
[alt-git.git] / t / t7064-wtstatus-pv2.sh
blob11884d2fc36911cea7f82a1257e35434de61500c
1 #!/bin/sh
3 test_description='git status --porcelain=v2
5 This test exercises porcelain V2 output for git status.'
7 . ./test-lib.sh
10 test_expect_success setup '
11 git checkout -f --orphan initial-branch &&
12 test_tick &&
13 git config core.autocrlf false &&
14 echo x >file_x &&
15 echo y >file_y &&
16 echo z >file_z &&
17 mkdir dir1 &&
18 echo a >dir1/file_a &&
19 echo b >dir1/file_b
22 test_expect_success 'before initial commit, nothing added, only untracked' '
23 cat >expect <<-EOF &&
24 # branch.oid (initial)
25 # branch.head initial-branch
26 ? actual
27 ? dir1/
28 ? expect
29 ? file_x
30 ? file_y
31 ? file_z
32 EOF
34 git status --porcelain=v2 --branch --untracked-files=normal >actual &&
35 test_cmp expect actual
38 test_expect_success 'before initial commit, things added' '
39 git add file_x file_y file_z dir1 &&
40 OID_A=$(git hash-object -t blob -- dir1/file_a) &&
41 OID_B=$(git hash-object -t blob -- dir1/file_b) &&
42 OID_X=$(git hash-object -t blob -- file_x) &&
43 OID_Y=$(git hash-object -t blob -- file_y) &&
44 OID_Z=$(git hash-object -t blob -- file_z) &&
46 cat >expect <<-EOF &&
47 # branch.oid (initial)
48 # branch.head initial-branch
49 1 A. N... 000000 100644 100644 $ZERO_OID $OID_A dir1/file_a
50 1 A. N... 000000 100644 100644 $ZERO_OID $OID_B dir1/file_b
51 1 A. N... 000000 100644 100644 $ZERO_OID $OID_X file_x
52 1 A. N... 000000 100644 100644 $ZERO_OID $OID_Y file_y
53 1 A. N... 000000 100644 100644 $ZERO_OID $OID_Z file_z
54 ? actual
55 ? expect
56 EOF
58 git status --porcelain=v2 --branch --untracked-files=all >actual &&
59 test_cmp expect actual
62 test_expect_success 'before initial commit, things added (-z)' '
63 lf_to_nul >expect <<-EOF &&
64 # branch.oid (initial)
65 # branch.head initial-branch
66 1 A. N... 000000 100644 100644 $ZERO_OID $OID_A dir1/file_a
67 1 A. N... 000000 100644 100644 $ZERO_OID $OID_B dir1/file_b
68 1 A. N... 000000 100644 100644 $ZERO_OID $OID_X file_x
69 1 A. N... 000000 100644 100644 $ZERO_OID $OID_Y file_y
70 1 A. N... 000000 100644 100644 $ZERO_OID $OID_Z file_z
71 ? actual
72 ? expect
73 EOF
75 git status -z --porcelain=v2 --branch --untracked-files=all >actual &&
76 test_cmp expect actual
79 test_expect_success 'make first commit, comfirm HEAD oid and branch' '
80 git commit -m initial &&
81 H0=$(git rev-parse HEAD) &&
82 cat >expect <<-EOF &&
83 # branch.oid $H0
84 # branch.head initial-branch
85 ? actual
86 ? expect
87 EOF
89 git status --porcelain=v2 --branch --untracked-files=all >actual &&
90 test_cmp expect actual
93 test_expect_success 'after first commit, create unstaged changes' '
94 echo x >>file_x &&
95 OID_X1=$(git hash-object -t blob -- file_x) &&
96 rm file_z &&
97 H0=$(git rev-parse HEAD) &&
99 cat >expect <<-EOF &&
100 # branch.oid $H0
101 # branch.head initial-branch
102 1 .M N... 100644 100644 100644 $OID_X $OID_X file_x
103 1 .D N... 100644 100644 000000 $OID_Z $OID_Z file_z
104 ? actual
105 ? expect
108 git status --porcelain=v2 --branch --untracked-files=all >actual &&
109 test_cmp expect actual
112 test_expect_success 'after first commit, stash existing changes' '
113 cat >expect <<-EOF &&
114 # branch.oid $H0
115 # branch.head initial-branch
116 # stash 2
119 test_when_finished "git stash pop && git stash pop" &&
121 git stash -- file_x &&
122 git stash &&
123 git status --porcelain=v2 --branch --show-stash --untracked-files=no >actual &&
124 test_cmp expect actual
127 test_expect_success 'after first commit but omit untracked files and branch' '
128 cat >expect <<-EOF &&
129 1 .M N... 100644 100644 100644 $OID_X $OID_X file_x
130 1 .D N... 100644 100644 000000 $OID_Z $OID_Z file_z
133 git status --porcelain=v2 --untracked-files=no >actual &&
134 test_cmp expect actual
137 test_expect_success 'after first commit, stage existing changes' '
138 git add file_x &&
139 git rm file_z &&
140 H0=$(git rev-parse HEAD) &&
142 cat >expect <<-EOF &&
143 # branch.oid $H0
144 # branch.head initial-branch
145 1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x
146 1 D. N... 100644 000000 000000 $OID_Z $ZERO_OID file_z
147 ? actual
148 ? expect
151 git status --porcelain=v2 --branch --untracked-files=all >actual &&
152 test_cmp expect actual
155 test_expect_success 'rename causes 2 path lines' '
156 git mv file_y renamed_y &&
157 H0=$(git rev-parse HEAD) &&
159 q_to_tab >expect <<-EOF &&
160 # branch.oid $H0
161 # branch.head initial-branch
162 1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x
163 1 D. N... 100644 000000 000000 $OID_Z $ZERO_OID file_z
164 2 R. N... 100644 100644 100644 $OID_Y $OID_Y R100 renamed_yQfile_y
165 ? actual
166 ? expect
169 git status --porcelain=v2 --branch --untracked-files=all >actual &&
170 test_cmp expect actual
173 test_expect_success 'rename causes 2 path lines (-z)' '
174 H0=$(git rev-parse HEAD) &&
176 ## Lines use NUL path separator and line terminator, so double transform here.
177 q_to_nul <<-EOF | lf_to_nul >expect &&
178 # branch.oid $H0
179 # branch.head initial-branch
180 1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x
181 1 D. N... 100644 000000 000000 $OID_Z $ZERO_OID file_z
182 2 R. N... 100644 100644 100644 $OID_Y $OID_Y R100 renamed_yQfile_y
183 ? actual
184 ? expect
187 git status --porcelain=v2 --branch --untracked-files=all -z >actual &&
188 test_cmp expect actual
191 test_expect_success 'make second commit, confirm clean and new HEAD oid' '
192 git commit -m second &&
193 H1=$(git rev-parse HEAD) &&
195 cat >expect <<-EOF &&
196 # branch.oid $H1
197 # branch.head initial-branch
198 ? actual
199 ? expect
202 git status --porcelain=v2 --branch --untracked-files=all >actual &&
203 test_cmp expect actual
206 test_expect_success 'confirm ignored files are not printed' '
207 test_when_finished "rm -f x.ign .gitignore" &&
208 echo x.ign >.gitignore &&
209 echo "ignore me" >x.ign &&
211 cat >expect <<-EOF &&
212 ? .gitignore
213 ? actual
214 ? expect
217 git status --porcelain=v2 --untracked-files=all >actual &&
218 test_cmp expect actual
221 test_expect_success 'ignored files are printed with --ignored' '
222 test_when_finished "rm -f x.ign .gitignore" &&
223 echo x.ign >.gitignore &&
224 echo "ignore me" >x.ign &&
226 cat >expect <<-EOF &&
227 ? .gitignore
228 ? actual
229 ? expect
230 ! x.ign
233 git status --porcelain=v2 --ignored --untracked-files=all >actual &&
234 test_cmp expect actual
237 test_expect_success 'create and commit permanent ignore file' '
238 cat >.gitignore <<-EOF &&
239 actual*
240 expect*
243 git add .gitignore &&
244 git commit -m ignore_trash &&
245 H1=$(git rev-parse HEAD) &&
247 cat >expect <<-EOF &&
248 # branch.oid $H1
249 # branch.head initial-branch
252 git status --porcelain=v2 --branch >actual &&
253 test_cmp expect actual
256 test_expect_success 'verify --intent-to-add output' '
257 test_when_finished "git rm -f intent1.add intent2.add" &&
258 touch intent1.add &&
259 echo test >intent2.add &&
261 git add --intent-to-add intent1.add intent2.add &&
263 cat >expect <<-EOF &&
264 1 .A N... 000000 000000 100644 $ZERO_OID $ZERO_OID intent1.add
265 1 .A N... 000000 000000 100644 $ZERO_OID $ZERO_OID intent2.add
268 git status --porcelain=v2 >actual &&
269 test_cmp expect actual
272 test_expect_success 'verify AA (add-add) conflict' '
273 test_when_finished "git reset --hard" &&
275 git branch AA_A initial-branch &&
276 git checkout AA_A &&
277 echo "Branch AA_A" >conflict.txt &&
278 OID_AA_A=$(git hash-object -t blob -- conflict.txt) &&
279 git add conflict.txt &&
280 git commit -m "branch aa_a" &&
282 git branch AA_B initial-branch &&
283 git checkout AA_B &&
284 echo "Branch AA_B" >conflict.txt &&
285 OID_AA_B=$(git hash-object -t blob -- conflict.txt) &&
286 git add conflict.txt &&
287 git commit -m "branch aa_b" &&
289 git branch AA_M AA_B &&
290 git checkout AA_M &&
291 test_must_fail git merge AA_A &&
293 HM=$(git rev-parse HEAD) &&
295 cat >expect <<-EOF &&
296 # branch.oid $HM
297 # branch.head AA_M
298 u AA N... 000000 100644 100644 100644 $ZERO_OID $OID_AA_B $OID_AA_A conflict.txt
301 git status --porcelain=v2 --branch --untracked-files=all >actual &&
302 test_cmp expect actual
305 test_expect_success 'verify UU (edit-edit) conflict' '
306 test_when_finished "git reset --hard" &&
308 git branch UU_ANC initial-branch &&
309 git checkout UU_ANC &&
310 echo "Ancestor" >conflict.txt &&
311 OID_UU_ANC=$(git hash-object -t blob -- conflict.txt) &&
312 git add conflict.txt &&
313 git commit -m "UU_ANC" &&
315 git branch UU_A UU_ANC &&
316 git checkout UU_A &&
317 echo "Branch UU_A" >conflict.txt &&
318 OID_UU_A=$(git hash-object -t blob -- conflict.txt) &&
319 git add conflict.txt &&
320 git commit -m "branch uu_a" &&
322 git branch UU_B UU_ANC &&
323 git checkout UU_B &&
324 echo "Branch UU_B" >conflict.txt &&
325 OID_UU_B=$(git hash-object -t blob -- conflict.txt) &&
326 git add conflict.txt &&
327 git commit -m "branch uu_b" &&
329 git branch UU_M UU_B &&
330 git checkout UU_M &&
331 test_must_fail git merge UU_A &&
333 HM=$(git rev-parse HEAD) &&
335 cat >expect <<-EOF &&
336 # branch.oid $HM
337 # branch.head UU_M
338 u UU N... 100644 100644 100644 100644 $OID_UU_ANC $OID_UU_B $OID_UU_A conflict.txt
341 git status --porcelain=v2 --branch --untracked-files=all >actual &&
342 test_cmp expect actual
345 test_expect_success 'verify upstream fields in branch header' '
346 git checkout initial-branch &&
347 test_when_finished "rm -rf sub_repo" &&
348 git clone . sub_repo &&
350 ## Confirm local initial-branch tracks remote initial-branch.
351 cd sub_repo &&
352 HUF=$(git rev-parse HEAD) &&
354 cat >expect <<-EOF &&
355 # branch.oid $HUF
356 # branch.head initial-branch
357 # branch.upstream origin/initial-branch
358 # branch.ab +0 -0
361 git status --porcelain=v2 --branch --untracked-files=all >actual &&
362 test_cmp expect actual &&
364 ## Test ahead/behind.
365 echo xyz >file_xyz &&
366 git add file_xyz &&
367 git commit -m xyz &&
369 HUF=$(git rev-parse HEAD) &&
371 cat >expect <<-EOF &&
372 # branch.oid $HUF
373 # branch.head initial-branch
374 # branch.upstream origin/initial-branch
375 # branch.ab +1 -0
378 git status --porcelain=v2 --branch --untracked-files=all >actual &&
379 test_cmp expect actual &&
381 ## Repeat the above but without --branch.
382 git status --porcelain=v2 --untracked-files=all >actual &&
383 test_must_be_empty actual &&
385 ## Test upstream-gone case. Fake this by pointing
386 ## origin/initial-branch at a non-existing commit.
387 git update-ref -d refs/remotes/origin/initial-branch &&
389 HUF=$(git rev-parse HEAD) &&
391 cat >expect <<-EOF &&
392 # branch.oid $HUF
393 # branch.head initial-branch
394 # branch.upstream origin/initial-branch
397 git status --porcelain=v2 --branch --untracked-files=all >actual &&
398 test_cmp expect actual
402 test_expect_success 'verify --[no-]ahead-behind with V2 format' '
403 git checkout initial-branch &&
404 test_when_finished "rm -rf sub_repo" &&
405 git clone . sub_repo &&
407 ## Confirm local initial-branch tracks remote initial-branch.
408 cd sub_repo &&
409 HUF=$(git rev-parse HEAD) &&
411 # Confirm --no-ahead-behind reports traditional branch.ab with 0/0 for equal branches.
412 cat >expect <<-EOF &&
413 # branch.oid $HUF
414 # branch.head initial-branch
415 # branch.upstream origin/initial-branch
416 # branch.ab +0 -0
419 git status --no-ahead-behind --porcelain=v2 --branch --untracked-files=all >actual &&
420 test_cmp expect actual &&
422 # Confirm --ahead-behind reports traditional branch.ab with 0/0.
423 cat >expect <<-EOF &&
424 # branch.oid $HUF
425 # branch.head initial-branch
426 # branch.upstream origin/initial-branch
427 # branch.ab +0 -0
430 git status --ahead-behind --porcelain=v2 --branch --untracked-files=all >actual &&
431 test_cmp expect actual &&
433 ## Test non-equal ahead/behind.
434 echo xyz >file_xyz &&
435 git add file_xyz &&
436 git commit -m xyz &&
438 HUF=$(git rev-parse HEAD) &&
440 # Confirm --no-ahead-behind reports branch.ab with ?/? for non-equal branches.
441 cat >expect <<-EOF &&
442 # branch.oid $HUF
443 # branch.head initial-branch
444 # branch.upstream origin/initial-branch
445 # branch.ab +? -?
448 git status --no-ahead-behind --porcelain=v2 --branch --untracked-files=all >actual &&
449 test_cmp expect actual &&
451 # Confirm --ahead-behind reports traditional branch.ab with 1/0.
452 cat >expect <<-EOF &&
453 # branch.oid $HUF
454 # branch.head initial-branch
455 # branch.upstream origin/initial-branch
456 # branch.ab +1 -0
459 git status --ahead-behind --porcelain=v2 --branch --untracked-files=all >actual &&
460 test_cmp expect actual &&
462 # Confirm that "status.aheadbehind" DOES NOT work on V2 format.
463 git -c status.aheadbehind=false status --porcelain=v2 --branch --untracked-files=all >actual &&
464 test_cmp expect actual &&
466 # Confirm that "status.aheadbehind" DOES NOT work on V2 format.
467 git -c status.aheadbehind=true status --porcelain=v2 --branch --untracked-files=all >actual &&
468 test_cmp expect actual
472 test_expect_success 'create and add submodule, submodule appears clean (A. S...)' '
473 git checkout initial-branch &&
474 git clone . sub_repo &&
475 git clone . super_repo &&
476 test_config_global protocol.file.allow always &&
477 ( cd super_repo &&
478 git submodule add ../sub_repo sub1 &&
480 ## Confirm stage/add of clean submodule.
481 HMOD=$(git hash-object -t blob -- .gitmodules) &&
482 HSUP=$(git rev-parse HEAD) &&
483 HSUB=$HSUP &&
485 cat >expect <<-EOF &&
486 # branch.oid $HSUP
487 # branch.head initial-branch
488 # branch.upstream origin/initial-branch
489 # branch.ab +0 -0
490 1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
491 1 A. S... 000000 160000 160000 $ZERO_OID $HSUB sub1
494 git status --porcelain=v2 --branch --untracked-files=all >actual &&
495 test_cmp expect actual
499 test_expect_success 'untracked changes in added submodule (AM S..U)' '
500 ( cd super_repo &&
501 ## create untracked file in the submodule.
502 ( cd sub1 &&
503 echo "xxxx" >file_in_sub
504 ) &&
506 HMOD=$(git hash-object -t blob -- .gitmodules) &&
507 HSUP=$(git rev-parse HEAD) &&
508 HSUB=$HSUP &&
510 cat >expect <<-EOF &&
511 # branch.oid $HSUP
512 # branch.head initial-branch
513 # branch.upstream origin/initial-branch
514 # branch.ab +0 -0
515 1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
516 1 AM S..U 000000 160000 160000 $ZERO_OID $HSUB sub1
519 git status --porcelain=v2 --branch --untracked-files=all >actual &&
520 test_cmp expect actual
524 test_expect_success 'staged changes in added submodule (AM S.M.)' '
525 ( cd super_repo &&
526 ## stage the changes in the submodule.
527 ( cd sub1 &&
528 git add file_in_sub
529 ) &&
531 HMOD=$(git hash-object -t blob -- .gitmodules) &&
532 HSUP=$(git rev-parse HEAD) &&
533 HSUB=$HSUP &&
535 cat >expect <<-EOF &&
536 # branch.oid $HSUP
537 # branch.head initial-branch
538 # branch.upstream origin/initial-branch
539 # branch.ab +0 -0
540 1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
541 1 AM S.M. 000000 160000 160000 $ZERO_OID $HSUB sub1
544 git status --porcelain=v2 --branch --untracked-files=all >actual &&
545 test_cmp expect actual
549 test_expect_success 'staged and unstaged changes in added (AM S.M.)' '
550 ( cd super_repo &&
551 ( cd sub1 &&
552 ## make additional unstaged changes (on the same file) in the submodule.
553 ## This does not cause us to get S.MU (because the submodule does not report
554 ## a "?" line for the unstaged changes).
555 echo "more changes" >>file_in_sub
556 ) &&
558 HMOD=$(git hash-object -t blob -- .gitmodules) &&
559 HSUP=$(git rev-parse HEAD) &&
560 HSUB=$HSUP &&
562 cat >expect <<-EOF &&
563 # branch.oid $HSUP
564 # branch.head initial-branch
565 # branch.upstream origin/initial-branch
566 # branch.ab +0 -0
567 1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
568 1 AM S.M. 000000 160000 160000 $ZERO_OID $HSUB sub1
571 git status --porcelain=v2 --branch --untracked-files=all >actual &&
572 test_cmp expect actual
576 test_expect_success 'staged and untracked changes in added submodule (AM S.MU)' '
577 ( cd super_repo &&
578 ( cd sub1 &&
579 ## stage new changes in tracked file.
580 git add file_in_sub &&
581 ## create new untracked file.
582 echo "yyyy" >>another_file_in_sub
583 ) &&
585 HMOD=$(git hash-object -t blob -- .gitmodules) &&
586 HSUP=$(git rev-parse HEAD) &&
587 HSUB=$HSUP &&
589 cat >expect <<-EOF &&
590 # branch.oid $HSUP
591 # branch.head initial-branch
592 # branch.upstream origin/initial-branch
593 # branch.ab +0 -0
594 1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
595 1 AM S.MU 000000 160000 160000 $ZERO_OID $HSUB sub1
598 git status --porcelain=v2 --branch --untracked-files=all >actual &&
599 test_cmp expect actual
603 test_expect_success 'commit within the submodule appears as new commit in super (AM SC..)' '
604 ( cd super_repo &&
605 ( cd sub1 &&
606 ## Make a new commit in the submodule.
607 git add file_in_sub &&
608 rm -f another_file_in_sub &&
609 git commit -m "new commit"
610 ) &&
612 HMOD=$(git hash-object -t blob -- .gitmodules) &&
613 HSUP=$(git rev-parse HEAD) &&
614 HSUB=$HSUP &&
616 cat >expect <<-EOF &&
617 # branch.oid $HSUP
618 # branch.head initial-branch
619 # branch.upstream origin/initial-branch
620 # branch.ab +0 -0
621 1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
622 1 AM SC.. 000000 160000 160000 $ZERO_OID $HSUB sub1
625 git status --porcelain=v2 --branch --untracked-files=all >actual &&
626 test_cmp expect actual
630 test_expect_success 'stage submodule in super and commit' '
631 ( cd super_repo &&
632 ## Stage the new submodule commit in the super.
633 git add sub1 &&
634 ## Commit the super so that the sub no longer appears as added.
635 git commit -m "super commit" &&
637 HSUP=$(git rev-parse HEAD) &&
639 cat >expect <<-EOF &&
640 # branch.oid $HSUP
641 # branch.head initial-branch
642 # branch.upstream origin/initial-branch
643 # branch.ab +1 -0
646 git status --porcelain=v2 --branch --untracked-files=all >actual &&
647 test_cmp expect actual
651 test_expect_success 'make unstaged changes in existing submodule (.M S.M.)' '
652 ( cd super_repo &&
653 ( cd sub1 &&
654 echo "zzzz" >>file_in_sub
655 ) &&
657 HSUP=$(git rev-parse HEAD) &&
658 HSUB=$(cd sub1 && git rev-parse HEAD) &&
660 cat >expect <<-EOF &&
661 # branch.oid $HSUP
662 # branch.head initial-branch
663 # branch.upstream origin/initial-branch
664 # branch.ab +1 -0
665 1 .M S.M. 160000 160000 160000 $HSUB $HSUB sub1
668 git status --porcelain=v2 --branch --untracked-files=all >actual &&
669 test_cmp expect actual
673 test_done