Raw
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Johannes E. Schindelin
4 #
5
6 test_description='git status'
7
8 . ./test-lib.sh
9 . "$TEST_DIRECTORY"/lib-terminal.sh
10
11 test_expect_success 'status -h in broken repository' '
12 git config --global advice.statusuoption false &&
13 mkdir broken &&
14 test_when_finished "rm -fr broken" &&
15 (
16 cd broken &&
17 git init &&
18 echo "[status] showuntrackedfiles = CORRUPT" >>.git/config &&
19 test_expect_code 129 git status -h >usage 2>&1
20 ) &&
21 test_grep "[Uu]sage" broken/usage
22 '
23
24 test_expect_success 'commit -h in broken repository' '
25 mkdir broken &&
26 test_when_finished "rm -fr broken" &&
27 (
28 cd broken &&
29 git init &&
30 echo "[status] showuntrackedfiles = CORRUPT" >>.git/config &&
31 test_expect_code 129 git commit -h >usage 2>&1
32 ) &&
33 test_grep "[Uu]sage" broken/usage
34 '
35
36 test_expect_success 'create upstream branch' '
37 git checkout -b upstream &&
38 test_commit upstream1 &&
39 test_commit upstream2 &&
40 # leave the first commit on main as root because several
41 # tests depend on this case; for our upstream we only
42 # care about commit counts anyway, so a totally divergent
43 # history is OK
44 git checkout --orphan main
45 '
46
47 test_expect_success 'setup' '
48 : >tracked &&
49 : >modified &&
50 mkdir dir1 &&
51 : >dir1/tracked &&
52 : >dir1/modified &&
53 mkdir dir2 &&
54 : >dir1/tracked &&
55 : >dir1/modified &&
56 git add . &&
57
58 git status >output &&
59
60 test_tick &&
61 git commit -m initial &&
62 : >untracked &&
63 : >dir1/untracked &&
64 : >dir2/untracked &&
65 echo 1 >dir1/modified &&
66 echo 2 >dir2/modified &&
67 echo 3 >dir2/added &&
68 git add dir2/added &&
69
70 git branch --set-upstream-to=upstream
71 '
72
73 test_expect_success 'status (1)' '
74 test_grep "use \"git rm --cached <file>\.\.\.\" to unstage" output
75 '
76
77 strip_comments () {
78 tab=' '
79 sed "s/^\# //; s/^\#$//; s/^#$tab/$tab/" <"$1" >"$1".tmp &&
80 rm "$1" && mv "$1".tmp "$1"
81 }
82
83 cat >.gitignore <<\EOF
84 .gitignore
85 expect*
86 output*
87 EOF
88
89 test_expect_success 'status --column' '
90 cat >expect <<\EOF &&
91 # On branch main
92 # Your branch and '\''upstream'\'' have diverged,
93 # and have 1 and 2 different commits each, respectively.
94 # (use "git pull" if you want to integrate the remote branch with yours)
95 #
96 # Changes to be committed:
97 # (use "git restore --staged <file>..." to unstage)
98 # new file: dir2/added
99 #
100 # Changes not staged for commit:
101 # (use "git add <file>..." to update what will be committed)
102 # (use "git restore <file>..." to discard changes in working directory)
103 # modified: dir1/modified
104 #
105 # Untracked files:
106 # (use "git add <file>..." to include in what will be committed)
107 # dir1/untracked dir2/untracked
108 # dir2/modified untracked
109 #
110 EOF
111 COLUMNS=50 git -c status.displayCommentPrefix=true status --column="column dense" >output &&
112 test_cmp expect output
113 '
114
115 test_expect_success 'status --column status.displayCommentPrefix=false' '
116 strip_comments expect &&
117 COLUMNS=49 git -c status.displayCommentPrefix=false status --column="column dense" >output &&
118 test_cmp expect output
119 '
120
121 cat >expect <<\EOF
122 # On branch main
123 # Your branch and 'upstream' have diverged,
124 # and have 1 and 2 different commits each, respectively.
125 # (use "git pull" if you want to integrate the remote branch with yours)
126 #
127 # Changes to be committed:
128 # (use "git restore --staged <file>..." to unstage)
129 # new file: dir2/added
130 #
131 # Changes not staged for commit:
132 # (use "git add <file>..." to update what will be committed)
133 # (use "git restore <file>..." to discard changes in working directory)
134 # modified: dir1/modified
135 #
136 # Untracked files:
137 # (use "git add <file>..." to include in what will be committed)
138 # dir1/untracked
139 # dir2/modified
140 # dir2/untracked
141 # untracked
142 #
143 EOF
144
145 test_expect_success 'status with status.displayCommentPrefix=true' '
146 git -c status.displayCommentPrefix=true status >output &&
147 test_cmp expect output
148 '
149
150 test_expect_success 'status with status.displayCommentPrefix=false' '
151 strip_comments expect &&
152 git -c status.displayCommentPrefix=false status >output &&
153 test_cmp expect output
154 '
155
156 test_expect_success 'status -v' '
157 (cat expect && git diff --cached) >expect-with-v &&
158 git status -v >output &&
159 test_cmp expect-with-v output
160 '
161
162 test_expect_success 'status -v -v' '
163 (cat expect &&
164 echo "Changes to be committed:" &&
165 git -c diff.mnemonicprefix=true diff --cached &&
166 echo "--------------------------------------------------" &&
167 echo "Changes not staged for commit:" &&
168 git -c diff.mnemonicprefix=true diff) >expect-with-v &&
169 git status -v -v >output &&
170 test_cmp expect-with-v output
171 '
172
173 test_expect_success 'setup fake editor' '
174 cat >.git/editor <<-\EOF &&
175 #! /bin/sh
176 cp "$1" output
177 EOF
178 chmod 755 .git/editor
179 '
180
181 commit_template_commented () {
182 (
183 EDITOR=.git/editor &&
184 export EDITOR &&
185 # Fails due to empty message
186 test_must_fail git commit
187 ) &&
188 ! grep '^[^#]' output
189 }
190
191 test_expect_success 'commit ignores status.displayCommentPrefix=false in COMMIT_EDITMSG' '
192 commit_template_commented
193 '
194
195 cat >expect <<\EOF
196 On branch main
197 Your branch and 'upstream' have diverged,
198 and have 1 and 2 different commits each, respectively.
199
200 Changes to be committed:
201 new file: dir2/added
202
203 Changes not staged for commit:
204 modified: dir1/modified
205
206 Untracked files:
207 dir1/untracked
208 dir2/modified
209 dir2/untracked
210 untracked
211
212 EOF
213
214 test_expect_success 'status (advice.statusHints false)' '
215 test_config advice.statusHints false &&
216 git status >output &&
217 test_cmp expect output
218
219 '
220
221 cat >expect <<\EOF
222 M dir1/modified
223 A dir2/added
224 ?? dir1/untracked
225 ?? dir2/modified
226 ?? dir2/untracked
227 ?? untracked
228 EOF
229
230 test_expect_success 'status -s' '
231
232 git status -s >output &&
233 test_cmp expect output
234
235 '
236
237 test_expect_success 'status with gitignore' '
238 {
239 echo ".gitignore" &&
240 echo "expect*" &&
241 echo "output" &&
242 echo "untracked"
243 } >.gitignore &&
244
245 cat >expect <<-\EOF &&
246 M dir1/modified
247 A dir2/added
248 ?? dir2/modified
249 EOF
250 git status -s >output &&
251 test_cmp expect output &&
252
253 cat >expect <<-\EOF &&
254 M dir1/modified
255 A dir2/added
256 ?? dir2/modified
257 !! .gitignore
258 !! dir1/untracked
259 !! dir2/untracked
260 !! expect
261 !! expect-with-v
262 !! output
263 !! untracked
264 EOF
265 git status -s --ignored >output &&
266 test_filter_gitconfig output &&
267 test_cmp expect output &&
268
269 cat >expect <<\EOF &&
270 On branch main
271 Your branch and '\''upstream'\'' have diverged,
272 and have 1 and 2 different commits each, respectively.
273 (use "git pull" if you want to integrate the remote branch with yours)
274
275 Changes to be committed:
276 (use "git restore --staged <file>..." to unstage)
277 new file: dir2/added
278
279 Changes not staged for commit:
280 (use "git add <file>..." to update what will be committed)
281 (use "git restore <file>..." to discard changes in working directory)
282 modified: dir1/modified
283
284 Untracked files:
285 (use "git add <file>..." to include in what will be committed)
286 dir2/modified
287
288 Ignored files:
289 (use "git add -f <file>..." to include in what will be committed)
290 .gitignore
291 dir1/untracked
292 dir2/untracked
293 expect
294 expect-with-v
295 output
296 untracked
297
298 EOF
299 git status --ignored >output &&
300 test_filter_gitconfig output &&
301 test_cmp expect output
302 '
303
304 test_expect_success 'status with gitignore (nothing untracked)' '
305 {
306 echo ".gitignore" &&
307 echo "expect*" &&
308 echo "dir2/modified" &&
309 echo "output" &&
310 echo "untracked"
311 } >.gitignore &&
312
313 cat >expect <<-\EOF &&
314 M dir1/modified
315 A dir2/added
316 EOF
317 git status -s >output &&
318 test_cmp expect output &&
319
320 cat >expect <<-\EOF &&
321 M dir1/modified
322 A dir2/added
323 !! .gitignore
324 !! dir1/untracked
325 !! dir2/modified
326 !! dir2/untracked
327 !! expect
328 !! expect-with-v
329 !! output
330 !! untracked
331 EOF
332 git status -s --ignored >output &&
333 test_filter_gitconfig output &&
334 test_cmp expect output &&
335
336 cat >expect <<\EOF &&
337 On branch main
338 Your branch and '\''upstream'\'' have diverged,
339 and have 1 and 2 different commits each, respectively.
340 (use "git pull" if you want to integrate the remote branch with yours)
341
342 Changes to be committed:
343 (use "git restore --staged <file>..." to unstage)
344 new file: dir2/added
345
346 Changes not staged for commit:
347 (use "git add <file>..." to update what will be committed)
348 (use "git restore <file>..." to discard changes in working directory)
349 modified: dir1/modified
350
351 Ignored files:
352 (use "git add -f <file>..." to include in what will be committed)
353 .gitignore
354 dir1/untracked
355 dir2/modified
356 dir2/untracked
357 expect
358 expect-with-v
359 output
360 untracked
361
362 EOF
363 git status --ignored >output &&
364 test_filter_gitconfig output &&
365 test_cmp expect output
366 '
367
368 cat >.gitignore <<\EOF
369 .gitignore
370 expect*
371 output*
372 EOF
373
374 cat >expect <<\EOF
375 ## main...upstream [ahead 1, behind 2]
376 M dir1/modified
377 A dir2/added
378 ?? dir1/untracked
379 ?? dir2/modified
380 ?? dir2/untracked
381 ?? untracked
382 EOF
383
384 test_expect_success 'status -s -b' '
385
386 git status -s -b >output &&
387 test_cmp expect output
388
389 '
390
391 test_expect_success 'status -s -z -b' '
392 tr "\\n" Q <expect >expect.q &&
393 mv expect.q expect &&
394 git status -s -z -b >output &&
395 nul_to_q <output >output.q &&
396 mv output.q output &&
397 test_cmp expect output
398 '
399
400 test_expect_success 'setup dir3' '
401 mkdir dir3 &&
402 : >dir3/untracked1 &&
403 : >dir3/untracked2
404 '
405
406 test_expect_success 'status -uno' '
407 cat >expect <<EOF &&
408 On branch main
409 Your branch and '\''upstream'\'' have diverged,
410 and have 1 and 2 different commits each, respectively.
411 (use "git pull" if you want to integrate the remote branch with yours)
412
413 Changes to be committed:
414 (use "git restore --staged <file>..." to unstage)
415 new file: dir2/added
416
417 Changes not staged for commit:
418 (use "git add <file>..." to update what will be committed)
419 (use "git restore <file>..." to discard changes in working directory)
420 modified: dir1/modified
421
422 Untracked files not listed (use -u option to show untracked files)
423 EOF
424 git status -uno >output &&
425 test_cmp expect output &&
426 git status -ufalse >output &&
427 test_cmp expect output
428 '
429
430 for no in no false 0
431 do
432 test_expect_success "status (status.showUntrackedFiles $no)" '
433 test_config status.showuntrackedfiles "$no" &&
434 git status >output &&
435 test_cmp expect output
436 '
437 done
438
439 test_expect_success 'status -uno (advice.statusHints false)' '
440 cat >expect <<EOF &&
441 On branch main
442 Your branch and '\''upstream'\'' have diverged,
443 and have 1 and 2 different commits each, respectively.
444
445 Changes to be committed:
446 new file: dir2/added
447
448 Changes not staged for commit:
449 modified: dir1/modified
450
451 Untracked files not listed
452 EOF
453 test_config advice.statusHints false &&
454 git status -uno >output &&
455 test_cmp expect output
456 '
457
458 cat >expect << EOF
459 M dir1/modified
460 A dir2/added
461 EOF
462 test_expect_success 'status -s -uno' '
463 git status -s -uno >output &&
464 test_cmp expect output
465 '
466
467 test_expect_success 'status -s (status.showUntrackedFiles no)' '
468 git config status.showuntrackedfiles no &&
469 git status -s >output &&
470 test_cmp expect output
471 '
472
473 test_expect_success 'status -unormal' '
474 cat >expect <<EOF &&
475 On branch main
476 Your branch and '\''upstream'\'' have diverged,
477 and have 1 and 2 different commits each, respectively.
478 (use "git pull" if you want to integrate the remote branch with yours)
479
480 Changes to be committed:
481 (use "git restore --staged <file>..." to unstage)
482 new file: dir2/added
483
484 Changes not staged for commit:
485 (use "git add <file>..." to update what will be committed)
486 (use "git restore <file>..." to discard changes in working directory)
487 modified: dir1/modified
488
489 Untracked files:
490 (use "git add <file>..." to include in what will be committed)
491 dir1/untracked
492 dir2/modified
493 dir2/untracked
494 dir3/
495 untracked
496
497 EOF
498 git status -unormal >output &&
499 test_cmp expect output &&
500 git status -utrue >output &&
501 test_cmp expect output &&
502 git status -uyes >output &&
503 test_cmp expect output
504 '
505
506 for normal in normal true 1
507 do
508 test_expect_success "status (status.showUntrackedFiles $normal)" '
509 test_config status.showuntrackedfiles $normal &&
510 git status >output &&
511 test_cmp expect output
512 '
513 done
514
515 cat >expect <<EOF
516 M dir1/modified
517 A dir2/added
518 ?? dir1/untracked
519 ?? dir2/modified
520 ?? dir2/untracked
521 ?? dir3/
522 ?? untracked
523 EOF
524 test_expect_success 'status -s -unormal' '
525 git status -s -unormal >output &&
526 test_cmp expect output
527 '
528
529 test_expect_success 'status -s (status.showUntrackedFiles normal)' '
530 git config status.showuntrackedfiles normal &&
531 git status -s >output &&
532 test_cmp expect output
533 '
534
535 test_expect_success 'status -uall' '
536 cat >expect <<EOF &&
537 On branch main
538 Your branch and '\''upstream'\'' have diverged,
539 and have 1 and 2 different commits each, respectively.
540 (use "git pull" if you want to integrate the remote branch with yours)
541
542 Changes to be committed:
543 (use "git restore --staged <file>..." to unstage)
544 new file: dir2/added
545
546 Changes not staged for commit:
547 (use "git add <file>..." to update what will be committed)
548 (use "git restore <file>..." to discard changes in working directory)
549 modified: dir1/modified
550
551 Untracked files:
552 (use "git add <file>..." to include in what will be committed)
553 dir1/untracked
554 dir2/modified
555 dir2/untracked
556 dir3/untracked1
557 dir3/untracked2
558 untracked
559
560 EOF
561 git status -uall >output &&
562 test_cmp expect output
563 '
564
565 test_expect_success 'status (status.showUntrackedFiles all)' '
566 test_config status.showuntrackedfiles all &&
567 git status >output &&
568 test_cmp expect output
569 '
570
571 test_expect_success 'teardown dir3' '
572 rm -rf dir3
573 '
574
575 cat >expect <<EOF
576 M dir1/modified
577 A dir2/added
578 ?? dir1/untracked
579 ?? dir2/modified
580 ?? dir2/untracked
581 ?? untracked
582 EOF
583 test_expect_success 'status -s -uall' '
584 test_unconfig status.showuntrackedfiles &&
585 git status -s -uall >output &&
586 test_cmp expect output
587 '
588 test_expect_success 'status -s (status.showUntrackedFiles all)' '
589 test_config status.showuntrackedfiles all &&
590 git status -s >output &&
591 rm -rf dir3 &&
592 test_cmp expect output
593 '
594
595 test_expect_success 'status with relative paths' '
596 cat >expect <<\EOF &&
597 On branch main
598 Your branch and '\''upstream'\'' have diverged,
599 and have 1 and 2 different commits each, respectively.
600 (use "git pull" if you want to integrate the remote branch with yours)
601
602 Changes to be committed:
603 (use "git restore --staged <file>..." to unstage)
604 new file: ../dir2/added
605
606 Changes not staged for commit:
607 (use "git add <file>..." to update what will be committed)
608 (use "git restore <file>..." to discard changes in working directory)
609 modified: modified
610
611 Untracked files:
612 (use "git add <file>..." to include in what will be committed)
613 untracked
614 ../dir2/modified
615 ../dir2/untracked
616 ../untracked
617
618 EOF
619 (cd dir1 && git status) >output &&
620 test_cmp expect output
621 '
622
623 cat >expect <<\EOF
624 M modified
625 A ../dir2/added
626 ?? untracked
627 ?? ../dir2/modified
628 ?? ../dir2/untracked
629 ?? ../untracked
630 EOF
631 test_expect_success 'status -s with relative paths' '
632
633 (cd dir1 && git status -s) >output &&
634 test_cmp expect output
635
636 '
637
638 cat >expect <<\EOF
639 M dir1/modified
640 A dir2/added
641 ?? dir1/untracked
642 ?? dir2/modified
643 ?? dir2/untracked
644 ?? untracked
645 EOF
646
647 test_expect_success 'status --porcelain ignores relative paths setting' '
648
649 (cd dir1 && git status --porcelain) >output &&
650 test_cmp expect output
651
652 '
653
654 test_expect_success 'setup unique colors' '
655
656 git config status.color.untracked blue &&
657 git config status.color.branch green &&
658 git config status.color.localBranch yellow &&
659 git config status.color.remoteBranch cyan
660
661 '
662
663 test_expect_success TTY 'status with color.ui' '
664 cat >expect <<\EOF &&
665 On branch <GREEN>main<RESET>
666 Your branch and '\''upstream'\'' have diverged,
667 and have 1 and 2 different commits each, respectively.
668 (use "git pull" if you want to integrate the remote branch with yours)
669
670 Changes to be committed:
671 (use "git restore --staged <file>..." to unstage)
672 <GREEN>new file: dir2/added<RESET>
673
674 Changes not staged for commit:
675 (use "git add <file>..." to update what will be committed)
676 (use "git restore <file>..." to discard changes in working directory)
677 <RED>modified: dir1/modified<RESET>
678
679 Untracked files:
680 (use "git add <file>..." to include in what will be committed)
681 <BLUE>dir1/untracked<RESET>
682 <BLUE>dir2/modified<RESET>
683 <BLUE>dir2/untracked<RESET>
684 <BLUE>untracked<RESET>
685
686 EOF
687 test_config color.ui auto &&
688 test_terminal git status | test_decode_color >output &&
689 test_cmp expect output
690 '
691
692 test_expect_success TTY 'status with color.status' '
693 test_config color.status auto &&
694 test_terminal git status | test_decode_color >output &&
695 test_cmp expect output
696 '
697
698 cat >expect <<\EOF
699 <RED>M<RESET> dir1/modified
700 <GREEN>A<RESET> dir2/added
701 <BLUE>??<RESET> dir1/untracked
702 <BLUE>??<RESET> dir2/modified
703 <BLUE>??<RESET> dir2/untracked
704 <BLUE>??<RESET> untracked
705 EOF
706
707 test_expect_success TTY 'status -s with color.ui' '
708
709 git config color.ui auto &&
710 test_terminal git status -s | test_decode_color >output &&
711 test_cmp expect output
712
713 '
714
715 test_expect_success TTY 'status -s with color.status' '
716
717 git config --unset color.ui &&
718 git config color.status auto &&
719 test_terminal git status -s | test_decode_color >output &&
720 test_cmp expect output
721
722 '
723
724 test_expect_success TTY 'status -s keeps colors with -z' '
725 test_when_finished "rm -f output.*" &&
726 test_terminal git status -s -z >output.raw &&
727 # convert back to newlines to avoid portability issues with
728 # test_decode_color and test_cmp, and to let us use the same expected
729 # output as earlier tests
730 tr "\0" "\n" <output.raw >output.nl &&
731 test_decode_color <output.nl >output &&
732 test_cmp expect output
733 '
734
735 cat >expect <<\EOF
736 ## <YELLOW>main<RESET>...<CYAN>upstream<RESET> [ahead <YELLOW>1<RESET>, behind <CYAN>2<RESET>]
737 <RED>M<RESET> dir1/modified
738 <GREEN>A<RESET> dir2/added
739 <BLUE>??<RESET> dir1/untracked
740 <BLUE>??<RESET> dir2/modified
741 <BLUE>??<RESET> dir2/untracked
742 <BLUE>??<RESET> untracked
743 EOF
744
745 test_expect_success TTY 'status -s -b with color.status' '
746
747 test_terminal git status -s -b | test_decode_color >output &&
748 test_cmp expect output
749
750 '
751
752 cat >expect <<\EOF
753 M dir1/modified
754 A dir2/added
755 ?? dir1/untracked
756 ?? dir2/modified
757 ?? dir2/untracked
758 ?? untracked
759 EOF
760
761 test_expect_success TTY 'status --porcelain ignores color.ui' '
762
763 git config --unset color.status &&
764 git config color.ui auto &&
765 test_terminal git status --porcelain | test_decode_color >output &&
766 test_cmp expect output
767
768 '
769
770 test_expect_success TTY 'status --porcelain ignores color.status' '
771
772 git config --unset color.ui &&
773 git config color.status auto &&
774 test_terminal git status --porcelain | test_decode_color >output &&
775 test_cmp expect output
776
777 '
778
779 # recover unconditionally from color tests
780 git config --unset color.status || :
781 git config --unset color.ui || :
782
783 test_expect_success 'status --porcelain respects -b' '
784
785 git status --porcelain -b >output &&
786 {
787 echo "## main...upstream [ahead 1, behind 2]" &&
788 cat expect
789 } >tmp &&
790 mv tmp expect &&
791 test_cmp expect output
792
793 '
794
795
796
797 test_expect_success 'status without relative paths' '
798 cat >expect <<\EOF &&
799 On branch main
800 Your branch and '\''upstream'\'' have diverged,
801 and have 1 and 2 different commits each, respectively.
802 (use "git pull" if you want to integrate the remote branch with yours)
803
804 Changes to be committed:
805 (use "git restore --staged <file>..." to unstage)
806 new file: dir2/added
807
808 Changes not staged for commit:
809 (use "git add <file>..." to update what will be committed)
810 (use "git restore <file>..." to discard changes in working directory)
811 modified: dir1/modified
812
813 Untracked files:
814 (use "git add <file>..." to include in what will be committed)
815 dir1/untracked
816 dir2/modified
817 dir2/untracked
818 untracked
819
820 EOF
821 test_config status.relativePaths false &&
822 (cd dir1 && git status) >output &&
823 test_cmp expect output
824
825 '
826
827 cat >expect <<\EOF
828 M dir1/modified
829 A dir2/added
830 ?? dir1/untracked
831 ?? dir2/modified
832 ?? dir2/untracked
833 ?? untracked
834 EOF
835
836 test_expect_success 'status -s without relative paths' '
837
838 test_config status.relativePaths false &&
839 (cd dir1 && git status -s) >output &&
840 test_cmp expect output
841
842 '
843
844 cat >expect <<\EOF
845 M dir1/modified
846 A dir2/added
847 A "file with spaces"
848 ?? dir1/untracked
849 ?? dir2/modified
850 ?? dir2/untracked
851 ?? "file with spaces 2"
852 ?? untracked
853 EOF
854
855 test_expect_success 'status -s without relative paths' '
856 test_when_finished "git rm --cached \"file with spaces\"; rm -f file*" &&
857 >"file with spaces" &&
858 >"file with spaces 2" &&
859 >"expect with spaces" &&
860 git add "file with spaces" &&
861
862 git status -s >output &&
863 test_cmp expect output &&
864
865 git status -s --ignored >output &&
866 grep "^!! \"expect with spaces\"$" output &&
867 grep -v "^!! " output >output-wo-ignored &&
868 test_cmp expect output-wo-ignored
869 '
870
871 test_expect_success 'dry-run of partial commit excluding new file in index' '
872 cat >expect <<EOF &&
873 On branch main
874 Your branch and '\''upstream'\'' have diverged,
875 and have 1 and 2 different commits each, respectively.
876
877 Changes to be committed:
878 (use "git restore --staged <file>..." to unstage)
879 modified: dir1/modified
880
881 Untracked files:
882 (use "git add <file>..." to include in what will be committed)
883 dir1/untracked
884 dir2/
885 untracked
886
887 EOF
888 git commit --dry-run dir1/modified >output &&
889 test_cmp expect output
890 '
891
892 cat >expect <<EOF
893 :100644 100644 $EMPTY_BLOB $ZERO_OID M dir1/modified
894 EOF
895 test_expect_success 'status refreshes the index' '
896 touch dir2/added &&
897 git status &&
898 git diff-files >output &&
899 test_cmp expect output
900 '
901
902 test_expect_success 'status shows detached HEAD properly after checking out non-local upstream branch' '
903 test_when_finished rm -rf upstream downstream actual &&
904
905 test_create_repo upstream &&
906 test_commit -C upstream foo &&
907
908 git clone upstream downstream &&
909 git -C downstream checkout @{u} &&
910 git -C downstream status >actual &&
911 grep -E "HEAD detached at [0-9a-f]+" actual
912 '
913
914 test_expect_success 'setup status submodule summary' '
915 test_create_repo sm && (
916 cd sm &&
917 >foo &&
918 git add foo &&
919 git commit -m "Add foo"
920 ) &&
921 git add sm
922 '
923
924 test_expect_success 'status submodule summary is disabled by default' '
925 cat >expect <<EOF &&
926 On branch main
927 Your branch and '\''upstream'\'' have diverged,
928 and have 1 and 2 different commits each, respectively.
929 (use "git pull" if you want to integrate the remote branch with yours)
930
931 Changes to be committed:
932 (use "git restore --staged <file>..." to unstage)
933 new file: dir2/added
934 new file: sm
935
936 Changes not staged for commit:
937 (use "git add <file>..." to update what will be committed)
938 (use "git restore <file>..." to discard changes in working directory)
939 modified: dir1/modified
940
941 Untracked files:
942 (use "git add <file>..." to include in what will be committed)
943 dir1/untracked
944 dir2/modified
945 dir2/untracked
946 untracked
947
948 EOF
949 git status >output &&
950 test_cmp expect output
951 '
952
953 # we expect the same as the previous test
954 test_expect_success 'status --untracked-files=all does not show submodule' '
955 git status --untracked-files=all >output &&
956 test_cmp expect output
957 '
958
959 cat >expect <<EOF
960 M dir1/modified
961 A dir2/added
962 A sm
963 ?? dir1/untracked
964 ?? dir2/modified
965 ?? dir2/untracked
966 ?? untracked
967 EOF
968 test_expect_success 'status -s submodule summary is disabled by default' '
969 git status -s >output &&
970 test_cmp expect output
971 '
972
973 # we expect the same as the previous test
974 test_expect_success 'status -s --untracked-files=all does not show submodule' '
975 git status -s --untracked-files=all >output &&
976 test_cmp expect output
977 '
978
979 head=$(cd sm && git rev-parse --short=7 --verify HEAD)
980
981 test_expect_success 'status submodule summary' '
982 cat >expect <<EOF &&
983 On branch main
984 Your branch and '\''upstream'\'' have diverged,
985 and have 1 and 2 different commits each, respectively.
986 (use "git pull" if you want to integrate the remote branch with yours)
987
988 Changes to be committed:
989 (use "git restore --staged <file>..." to unstage)
990 new file: dir2/added
991 new file: sm
992
993 Changes not staged for commit:
994 (use "git add <file>..." to update what will be committed)
995 (use "git restore <file>..." to discard changes in working directory)
996 modified: dir1/modified
997
998 Submodule changes to be committed:
999
1000 * sm 0000000...$head (1):
1001 > Add foo
1002
1003 Untracked files:
1004 (use "git add <file>..." to include in what will be committed)
1005 dir1/untracked
1006 dir2/modified
1007 dir2/untracked
1008 untracked
1009
1010 EOF
1011 git config status.submodulesummary 10 &&
1012 git status >output &&
1013 test_cmp expect output
1014 '
1015
1016 test_expect_success 'status submodule summary with status.displayCommentPrefix=false' '
1017 strip_comments expect &&
1018 git -c status.displayCommentPrefix=false status >output &&
1019 test_cmp expect output
1020 '
1021
1022 test_expect_success 'commit with submodule summary ignores status.displayCommentPrefix' '
1023 commit_template_commented
1024 '
1025
1026 cat >expect <<EOF
1027 M dir1/modified
1028 A dir2/added
1029 A sm
1030 ?? dir1/untracked
1031 ?? dir2/modified
1032 ?? dir2/untracked
1033 ?? untracked
1034 EOF
1035 test_expect_success 'status -s submodule summary' '
1036 git status -s >output &&
1037 test_cmp expect output
1038 '
1039
1040 test_expect_success 'status submodule summary (clean submodule): commit' '
1041 cat >expect-status <<EOF &&
1042 On branch main
1043 Your branch and '\''upstream'\'' have diverged,
1044 and have 2 and 2 different commits each, respectively.
1045 (use "git pull" if you want to integrate the remote branch with yours)
1046
1047 Changes not staged for commit:
1048 (use "git add <file>..." to update what will be committed)
1049 (use "git restore <file>..." to discard changes in working directory)
1050 modified: dir1/modified
1051
1052 Untracked files:
1053 (use "git add <file>..." to include in what will be committed)
1054 dir1/untracked
1055 dir2/modified
1056 dir2/untracked
1057 untracked
1058
1059 no changes added to commit (use "git add" and/or "git commit -a")
1060 EOF
1061 sed "/git pull/d" expect-status > expect-commit &&
1062 git commit -m "commit submodule" &&
1063 git config status.submodulesummary 10 &&
1064 test_must_fail git commit --dry-run >output &&
1065 test_cmp expect-commit output &&
1066 git status >output &&
1067 test_cmp expect-status output
1068 '
1069
1070 cat >expect <<EOF
1071 M dir1/modified
1072 ?? dir1/untracked
1073 ?? dir2/modified
1074 ?? dir2/untracked
1075 ?? untracked
1076 EOF
1077 test_expect_success 'status -s submodule summary (clean submodule)' '
1078 git status -s >output &&
1079 test_cmp expect output
1080 '
1081
1082 test_expect_success 'status -z implies porcelain' '
1083 git status --porcelain |
1084 tr "\012" "\000" >expect &&
1085 git status -z >output &&
1086 test_cmp expect output
1087 '
1088
1089 test_expect_success 'commit --dry-run submodule summary (--amend)' '
1090 cat >expect <<EOF &&
1091 On branch main
1092 Your branch and '\''upstream'\'' have diverged,
1093 and have 2 and 2 different commits each, respectively.
1094
1095 Changes to be committed:
1096 (use "git restore --source=HEAD^1 --staged <file>..." to unstage)
1097 new file: dir2/added
1098 new file: sm
1099
1100 Changes not staged for commit:
1101 (use "git add <file>..." to update what will be committed)
1102 (use "git restore <file>..." to discard changes in working directory)
1103 modified: dir1/modified
1104
1105 Submodule changes to be committed:
1106
1107 * sm 0000000...$head (1):
1108 > Add foo
1109
1110 Untracked files:
1111 (use "git add <file>..." to include in what will be committed)
1112 dir1/untracked
1113 dir2/modified
1114 dir2/untracked
1115 untracked
1116
1117 EOF
1118 git config status.submodulesummary 10 &&
1119 git commit --dry-run --amend >output &&
1120 test_cmp expect output
1121 '
1122
1123 test_expect_success POSIXPERM,SANITY 'status succeeds in a read-only repository' '
1124 test_when_finished "chmod 775 .git" &&
1125 (
1126 chmod a-w .git &&
1127 # make dir1/tracked stat-dirty
1128 >dir1/tracked1 && mv -f dir1/tracked1 dir1/tracked &&
1129 git status -s >output &&
1130 ! grep dir1/tracked output &&
1131 # make sure "status" succeeded without writing index out
1132 git diff-files | grep dir1/tracked
1133 )
1134 '
1135
1136 (cd sm && echo > bar && git add bar && git commit -q -m 'Add bar') && git add sm
1137 new_head=$(cd sm && git rev-parse --short=7 --verify HEAD)
1138 touch .gitmodules
1139
1140 test_expect_success '--ignore-submodules=untracked suppresses submodules with untracked content' '
1141 cat > expect << EOF &&
1142 On branch main
1143 Your branch and '\''upstream'\'' have diverged,
1144 and have 2 and 2 different commits each, respectively.
1145 (use "git pull" if you want to integrate the remote branch with yours)
1146
1147 Changes to be committed:
1148 (use "git restore --staged <file>..." to unstage)
1149 modified: sm
1150
1151 Changes not staged for commit:
1152 (use "git add <file>..." to update what will be committed)
1153 (use "git restore <file>..." to discard changes in working directory)
1154 modified: dir1/modified
1155
1156 Submodule changes to be committed:
1157
1158 * sm $head...$new_head (1):
1159 > Add bar
1160
1161 Untracked files:
1162 (use "git add <file>..." to include in what will be committed)
1163 .gitmodules
1164 dir1/untracked
1165 dir2/modified
1166 dir2/untracked
1167 untracked
1168
1169 EOF
1170 echo modified sm/untracked &&
1171 git status --ignore-submodules=untracked >output &&
1172 test_cmp expect output
1173 '
1174
1175 test_expect_success '.gitmodules ignore=untracked suppresses submodules with untracked content' '
1176 test_config diff.ignoreSubmodules dirty &&
1177 git status >output &&
1178 test_cmp expect output &&
1179 git config --add -f .gitmodules submodule.subname.ignore untracked &&
1180 git config --add -f .gitmodules submodule.subname.path sm &&
1181 git status >output &&
1182 test_cmp expect output &&
1183 git config -f .gitmodules --remove-section submodule.subname
1184 '
1185
1186 test_expect_success '.git/config ignore=untracked suppresses submodules with untracked content' '
1187 git config --add -f .gitmodules submodule.subname.ignore none &&
1188 git config --add -f .gitmodules submodule.subname.path sm &&
1189 git config --add submodule.subname.ignore untracked &&
1190 git config --add submodule.subname.path sm &&
1191 git status >output &&
1192 test_cmp expect output &&
1193 git config --remove-section submodule.subname &&
1194 git config --remove-section -f .gitmodules submodule.subname
1195 '
1196
1197 test_expect_success '--ignore-submodules=dirty suppresses submodules with untracked content' '
1198 git status --ignore-submodules=dirty >output &&
1199 test_cmp expect output
1200 '
1201
1202 test_expect_success '.gitmodules ignore=dirty suppresses submodules with untracked content' '
1203 test_config diff.ignoreSubmodules dirty &&
1204 git status >output &&
1205 ! test -s actual &&
1206 git config --add -f .gitmodules submodule.subname.ignore dirty &&
1207 git config --add -f .gitmodules submodule.subname.path sm &&
1208 git status >output &&
1209 test_cmp expect output &&
1210 git config -f .gitmodules --remove-section submodule.subname
1211 '
1212
1213 test_expect_success '.git/config ignore=dirty suppresses submodules with untracked content' '
1214 git config --add -f .gitmodules submodule.subname.ignore none &&
1215 git config --add -f .gitmodules submodule.subname.path sm &&
1216 git config --add submodule.subname.ignore dirty &&
1217 git config --add submodule.subname.path sm &&
1218 git status >output &&
1219 test_cmp expect output &&
1220 git config --remove-section submodule.subname &&
1221 git config -f .gitmodules --remove-section submodule.subname
1222 '
1223
1224 test_expect_success '--ignore-submodules=dirty suppresses submodules with modified content' '
1225 echo modified >sm/foo &&
1226 git status --ignore-submodules=dirty >output &&
1227 test_cmp expect output
1228 '
1229
1230 test_expect_success '.gitmodules ignore=dirty suppresses submodules with modified content' '
1231 git config --add -f .gitmodules submodule.subname.ignore dirty &&
1232 git config --add -f .gitmodules submodule.subname.path sm &&
1233 git status >output &&
1234 test_cmp expect output &&
1235 git config -f .gitmodules --remove-section submodule.subname
1236 '
1237
1238 test_expect_success '.git/config ignore=dirty suppresses submodules with modified content' '
1239 git config --add -f .gitmodules submodule.subname.ignore none &&
1240 git config --add -f .gitmodules submodule.subname.path sm &&
1241 git config --add submodule.subname.ignore dirty &&
1242 git config --add submodule.subname.path sm &&
1243 git status >output &&
1244 test_cmp expect output &&
1245 git config --remove-section submodule.subname &&
1246 git config -f .gitmodules --remove-section submodule.subname
1247 '
1248
1249 test_expect_success "--ignore-submodules=untracked doesn't suppress submodules with modified content" '
1250 cat > expect << EOF &&
1251 On branch main
1252 Your branch and '\''upstream'\'' have diverged,
1253 and have 2 and 2 different commits each, respectively.
1254 (use "git pull" if you want to integrate the remote branch with yours)
1255
1256 Changes to be committed:
1257 (use "git restore --staged <file>..." to unstage)
1258 modified: sm
1259
1260 Changes not staged for commit:
1261 (use "git add <file>..." to update what will be committed)
1262 (use "git restore <file>..." to discard changes in working directory)
1263 (commit or discard the untracked or modified content in submodules)
1264 modified: dir1/modified
1265 modified: sm (modified content)
1266
1267 Submodule changes to be committed:
1268
1269 * sm $head...$new_head (1):
1270 > Add bar
1271
1272 Untracked files:
1273 (use "git add <file>..." to include in what will be committed)
1274 .gitmodules
1275 dir1/untracked
1276 dir2/modified
1277 dir2/untracked
1278 untracked
1279
1280 EOF
1281 git status --ignore-submodules=untracked > output &&
1282 test_cmp expect output
1283 '
1284
1285 test_expect_success ".gitmodules ignore=untracked doesn't suppress submodules with modified content" '
1286 git config --add -f .gitmodules submodule.subname.ignore untracked &&
1287 git config --add -f .gitmodules submodule.subname.path sm &&
1288 git status >output &&
1289 test_cmp expect output &&
1290 git config -f .gitmodules --remove-section submodule.subname
1291 '
1292
1293 test_expect_success ".git/config ignore=untracked doesn't suppress submodules with modified content" '
1294 git config --add -f .gitmodules submodule.subname.ignore none &&
1295 git config --add -f .gitmodules submodule.subname.path sm &&
1296 git config --add submodule.subname.ignore untracked &&
1297 git config --add submodule.subname.path sm &&
1298 git status >output &&
1299 test_cmp expect output &&
1300 git config --remove-section submodule.subname &&
1301 git config -f .gitmodules --remove-section submodule.subname
1302 '
1303
1304 head2=$(cd sm && git commit -q -m "2nd commit" foo && git rev-parse --short=7 --verify HEAD)
1305
1306 test_expect_success "--ignore-submodules=untracked doesn't suppress submodule summary" '
1307 cat > expect << EOF &&
1308 On branch main
1309 Your branch and '\''upstream'\'' have diverged,
1310 and have 2 and 2 different commits each, respectively.
1311 (use "git pull" if you want to integrate the remote branch with yours)
1312
1313 Changes to be committed:
1314 (use "git restore --staged <file>..." to unstage)
1315 modified: sm
1316
1317 Changes not staged for commit:
1318 (use "git add <file>..." to update what will be committed)
1319 (use "git restore <file>..." to discard changes in working directory)
1320 modified: dir1/modified
1321 modified: sm (new commits)
1322
1323 Submodule changes to be committed:
1324
1325 * sm $head...$new_head (1):
1326 > Add bar
1327
1328 Submodules changed but not updated:
1329
1330 * sm $new_head...$head2 (1):
1331 > 2nd commit
1332
1333 Untracked files:
1334 (use "git add <file>..." to include in what will be committed)
1335 .gitmodules
1336 dir1/untracked
1337 dir2/modified
1338 dir2/untracked
1339 untracked
1340
1341 EOF
1342 git status --ignore-submodules=untracked > output &&
1343 test_cmp expect output
1344 '
1345
1346 test_expect_success ".gitmodules ignore=untracked doesn't suppress submodule summary" '
1347 git config --add -f .gitmodules submodule.subname.ignore untracked &&
1348 git config --add -f .gitmodules submodule.subname.path sm &&
1349 git status >output &&
1350 test_cmp expect output &&
1351 git config -f .gitmodules --remove-section submodule.subname
1352 '
1353
1354 test_expect_success ".git/config ignore=untracked doesn't suppress submodule summary" '
1355 git config --add -f .gitmodules submodule.subname.ignore none &&
1356 git config --add -f .gitmodules submodule.subname.path sm &&
1357 git config --add submodule.subname.ignore untracked &&
1358 git config --add submodule.subname.path sm &&
1359 git status >output &&
1360 test_cmp expect output &&
1361 git config --remove-section submodule.subname &&
1362 git config -f .gitmodules --remove-section submodule.subname
1363 '
1364
1365 test_expect_success "--ignore-submodules=dirty doesn't suppress submodule summary" '
1366 git status --ignore-submodules=dirty > output &&
1367 test_cmp expect output
1368 '
1369 test_expect_success ".gitmodules ignore=dirty doesn't suppress submodule summary" '
1370 git config --add -f .gitmodules submodule.subname.ignore dirty &&
1371 git config --add -f .gitmodules submodule.subname.path sm &&
1372 git status >output &&
1373 test_cmp expect output &&
1374 git config -f .gitmodules --remove-section submodule.subname
1375 '
1376
1377 test_expect_success ".git/config ignore=dirty doesn't suppress submodule summary" '
1378 git config --add -f .gitmodules submodule.subname.ignore none &&
1379 git config --add -f .gitmodules submodule.subname.path sm &&
1380 git config --add submodule.subname.ignore dirty &&
1381 git config --add submodule.subname.path sm &&
1382 git status >output &&
1383 test_cmp expect output &&
1384 git config --remove-section submodule.subname &&
1385 git config -f .gitmodules --remove-section submodule.subname
1386 '
1387
1388 cat > expect << EOF
1389 ; On branch main
1390 ; Your branch and 'upstream' have diverged,
1391 ; and have 2 and 2 different commits each, respectively.
1392 ; (use "git pull" if you want to integrate the remote branch with yours)
1393 ;
1394 ; Changes to be committed:
1395 ; (use "git restore --staged <file>..." to unstage)
1396 ; modified: sm
1397 ;
1398 ; Changes not staged for commit:
1399 ; (use "git add <file>..." to update what will be committed)
1400 ; (use "git restore <file>..." to discard changes in working directory)
1401 ; modified: dir1/modified
1402 ; modified: sm (new commits)
1403 ;
1404 ; Submodule changes to be committed:
1405 ;
1406 ; * sm $head...$new_head (1):
1407 ; > Add bar
1408 ;
1409 ; Submodules changed but not updated:
1410 ;
1411 ; * sm $new_head...$head2 (1):
1412 ; > 2nd commit
1413 ;
1414 ; Untracked files:
1415 ; (use "git add <file>..." to include in what will be committed)
1416 ; .gitmodules
1417 ; dir1/untracked
1418 ; dir2/modified
1419 ; dir2/untracked
1420 ; untracked
1421 ;
1422 EOF
1423
1424 test_expect_success "status (core.commentchar with submodule summary)" '
1425 test_config core.commentchar ";" &&
1426 git -c status.displayCommentPrefix=true status >output &&
1427 test_cmp expect output
1428 '
1429
1430 test_expect_success "status (core.commentchar with two chars with submodule summary)" '
1431 test_config core.commentchar ";;" &&
1432 sed "s/^/;/" <expect >expect.double &&
1433 git -c status.displayCommentPrefix=true status >output &&
1434 test_cmp expect.double output
1435 '
1436
1437 test_expect_success "--ignore-submodules=all suppresses submodule summary" '
1438 cat > expect << EOF &&
1439 On branch main
1440 Your branch and '\''upstream'\'' have diverged,
1441 and have 2 and 2 different commits each, respectively.
1442 (use "git pull" if you want to integrate the remote branch with yours)
1443
1444 Changes not staged for commit:
1445 (use "git add <file>..." to update what will be committed)
1446 (use "git restore <file>..." to discard changes in working directory)
1447 modified: dir1/modified
1448
1449 Untracked files:
1450 (use "git add <file>..." to include in what will be committed)
1451 .gitmodules
1452 dir1/untracked
1453 dir2/modified
1454 dir2/untracked
1455 untracked
1456
1457 no changes added to commit (use "git add" and/or "git commit -a")
1458 EOF
1459 git status --ignore-submodules=all > output &&
1460 test_cmp expect output
1461 '
1462
1463 test_expect_success '.gitmodules ignore=all suppresses unstaged submodule summary' '
1464 cat > expect << EOF &&
1465 On branch main
1466 Your branch and '\''upstream'\'' have diverged,
1467 and have 2 and 2 different commits each, respectively.
1468 (use "git pull" if you want to integrate the remote branch with yours)
1469
1470 Changes to be committed:
1471 (use "git restore --staged <file>..." to unstage)
1472 modified: sm
1473
1474 Changes not staged for commit:
1475 (use "git add <file>..." to update what will be committed)
1476 (use "git restore <file>..." to discard changes in working directory)
1477 modified: dir1/modified
1478
1479 Untracked files:
1480 (use "git add <file>..." to include in what will be committed)
1481 .gitmodules
1482 dir1/untracked
1483 dir2/modified
1484 dir2/untracked
1485 untracked
1486
1487 EOF
1488 git config --add -f .gitmodules submodule.subname.ignore all &&
1489 git config --add -f .gitmodules submodule.subname.path sm &&
1490 git status > output &&
1491 test_cmp expect output &&
1492 git config -f .gitmodules --remove-section submodule.subname
1493 '
1494
1495 test_expect_success '.git/config ignore=all suppresses unstaged submodule summary' '
1496 git config --add -f .gitmodules submodule.subname.ignore none &&
1497 git config --add -f .gitmodules submodule.subname.path sm &&
1498 git config --add submodule.subname.ignore all &&
1499 git config --add submodule.subname.path sm &&
1500 git status > output &&
1501 test_cmp expect output &&
1502 git config --remove-section submodule.subname &&
1503 git config -f .gitmodules --remove-section submodule.subname
1504 '
1505
1506 test_expect_success 'setup of test environment' '
1507 git config status.showUntrackedFiles no &&
1508 git status -s >expected_short &&
1509 git status --no-short >expected_noshort
1510 '
1511
1512 test_expect_success '"status.short=true" same as "-s"' '
1513 git -c status.short=true status >actual &&
1514 test_cmp expected_short actual
1515 '
1516
1517 test_expect_success '"status.short=true" weaker than "--no-short"' '
1518 git -c status.short=true status --no-short >actual &&
1519 test_cmp expected_noshort actual
1520 '
1521
1522 test_expect_success '"status.short=false" same as "--no-short"' '
1523 git -c status.short=false status >actual &&
1524 test_cmp expected_noshort actual
1525 '
1526
1527 test_expect_success '"status.short=false" weaker than "-s"' '
1528 git -c status.short=false status -s >actual &&
1529 test_cmp expected_short actual
1530 '
1531
1532 test_expect_success '"status.branch=true" same as "-b"' '
1533 git status -sb >expected_branch &&
1534 git -c status.branch=true status -s >actual &&
1535 test_cmp expected_branch actual
1536 '
1537
1538 test_expect_success '"status.branch=true" different from "--no-branch"' '
1539 git status -s --no-branch >expected_nobranch &&
1540 git -c status.branch=true status -s >actual &&
1541 ! test_cmp expected_nobranch actual
1542 '
1543
1544 test_expect_success '"status.branch=true" weaker than "--no-branch"' '
1545 git -c status.branch=true status -s --no-branch >actual &&
1546 test_cmp expected_nobranch actual
1547 '
1548
1549 test_expect_success '"status.branch=true" weaker than "--porcelain"' '
1550 git -c status.branch=true status --porcelain >actual &&
1551 test_cmp expected_nobranch actual
1552 '
1553
1554 test_expect_success '"status.branch=false" same as "--no-branch"' '
1555 git -c status.branch=false status -s >actual &&
1556 test_cmp expected_nobranch actual
1557 '
1558
1559 test_expect_success '"status.branch=false" weaker than "-b"' '
1560 git -c status.branch=false status -sb >actual &&
1561 test_cmp expected_branch actual
1562 '
1563
1564 test_expect_success 'Restore default test environment' '
1565 git config --unset status.showUntrackedFiles
1566 '
1567
1568 test_expect_success 'git commit will commit a staged but ignored submodule' '
1569 git config --add -f .gitmodules submodule.subname.ignore all &&
1570 git config --add -f .gitmodules submodule.subname.path sm &&
1571 git config --add submodule.subname.ignore all &&
1572 git status -s --ignore-submodules=dirty >output &&
1573 test_grep "^M. sm" output &&
1574 GIT_EDITOR="echo hello >>\"\$1\"" &&
1575 export GIT_EDITOR &&
1576 git commit -uno &&
1577 git status -s --ignore-submodules=dirty >output &&
1578 test_grep ! "^M. sm" output
1579 '
1580
1581 test_expect_success 'git commit --dry-run will show a staged but ignored submodule' '
1582 git reset HEAD^ &&
1583 git add --force sm &&
1584 cat >expect << EOF &&
1585 On branch main
1586 Your branch and '\''upstream'\'' have diverged,
1587 and have 2 and 2 different commits each, respectively.
1588
1589 Changes to be committed:
1590 (use "git restore --staged <file>..." to unstage)
1591 modified: sm
1592
1593 Changes not staged for commit:
1594 (use "git add <file>..." to update what will be committed)
1595 (use "git restore <file>..." to discard changes in working directory)
1596 modified: dir1/modified
1597
1598 Untracked files not listed (use -u option to show untracked files)
1599 EOF
1600 git commit -uno --dry-run >output &&
1601 test_cmp expect output &&
1602 git status -s --ignore-submodules=dirty >output &&
1603 test_grep "^M. sm" output
1604 '
1605
1606 test_expect_success 'git commit -m will commit a staged but ignored submodule' '
1607 git commit -uno -m message &&
1608 git status -s --ignore-submodules=dirty >output &&
1609 test_grep ! "^M. sm" output &&
1610 git config --remove-section submodule.subname &&
1611 git config -f .gitmodules --remove-section submodule.subname
1612 '
1613
1614 test_expect_success 'show stash info with "--show-stash"' '
1615 git reset --hard &&
1616 git stash clear &&
1617 echo 1 >file &&
1618 git add file &&
1619 git stash &&
1620 git status >expected_default &&
1621 git status --show-stash >expected_with_stash &&
1622 test_grep "^Your stash currently has 1 entry$" expected_with_stash
1623 '
1624
1625 test_expect_success 'no stash info with "--show-stash --no-show-stash"' '
1626 git status --show-stash --no-show-stash >expected_without_stash &&
1627 test_cmp expected_default expected_without_stash
1628 '
1629
1630 test_expect_success '"status.showStash=false" weaker than "--show-stash"' '
1631 git -c status.showStash=false status --show-stash >actual &&
1632 test_cmp expected_with_stash actual
1633 '
1634
1635 test_expect_success '"status.showStash=true" weaker than "--no-show-stash"' '
1636 git -c status.showStash=true status --no-show-stash >actual &&
1637 test_cmp expected_without_stash actual
1638 '
1639
1640 test_expect_success 'no additional info if no stash entries' '
1641 git stash clear &&
1642 git -c status.showStash=true status >actual &&
1643 test_cmp expected_without_stash actual
1644 '
1645
1646 test_expect_success '"No commits yet" should be noted in status output' '
1647 git checkout --orphan empty-branch-1 &&
1648 git status >output &&
1649 test_grep "No commits yet" output
1650 '
1651
1652 test_expect_success '"No commits yet" should not be noted in status output' '
1653 git checkout --orphan empty-branch-2 &&
1654 test_commit test-commit-1 &&
1655 git status >output &&
1656 test_grep ! "No commits yet" output
1657 '
1658
1659 test_expect_success '"Initial commit" should be noted in commit template' '
1660 git checkout --orphan empty-branch-3 &&
1661 touch to_be_committed_1 &&
1662 git add to_be_committed_1 &&
1663 git commit --dry-run >output &&
1664 test_grep "Initial commit" output
1665 '
1666
1667 test_expect_success '"Initial commit" should not be noted in commit template' '
1668 git checkout --orphan empty-branch-4 &&
1669 test_commit test-commit-2 &&
1670 touch to_be_committed_2 &&
1671 git add to_be_committed_2 &&
1672 git commit --dry-run >output &&
1673 test_grep ! "Initial commit" output
1674 '
1675
1676 test_expect_success '--no-optional-locks prevents index update' '
1677 test_set_magic_mtime .git/index &&
1678 git --no-optional-locks status &&
1679 test_is_magic_mtime .git/index &&
1680 git status &&
1681 ! test_is_magic_mtime .git/index
1682 '
1683
1684 test_expect_success 'racy timestamps will be fixed for clean worktree' '
1685 echo content >racy-dirty &&
1686 echo content >racy-racy &&
1687 git add racy* &&
1688 git commit -m "racy test files" &&
1689 # let status rewrite the index, if necessary; after that we expect
1690 # no more index writes unless caused by racy timestamps; note that
1691 # timestamps may already be racy now (depending on previous tests)
1692 git status &&
1693 test_set_magic_mtime .git/index &&
1694 git status &&
1695 ! test_is_magic_mtime .git/index
1696 '
1697
1698 test_expect_success 'racy timestamps will be fixed for dirty worktree' '
1699 echo content2 >racy-dirty &&
1700 git status &&
1701 test_set_magic_mtime .git/index &&
1702 git status &&
1703 ! test_is_magic_mtime .git/index
1704 '
1705
1706 test_expect_success 'setup slow status advice' '
1707 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main git init slowstatus &&
1708 (
1709 cd slowstatus &&
1710 cat >.gitignore <<-\EOF &&
1711 /actual
1712 /expected
1713 /out
1714 EOF
1715 git add .gitignore &&
1716 git commit -m "Add .gitignore" &&
1717 git config set advice.statusuoption true
1718 )
1719 '
1720
1721 test_expect_success 'slow status advice when core.untrackedCache and fsmonitor are unset' '
1722 (
1723 cd slowstatus &&
1724 git config core.untrackedCache false &&
1725 git config core.fsmonitor false &&
1726 GIT_TEST_UF_DELAY_WARNING=1 git status >actual &&
1727 cat >expected <<-\EOF &&
1728 On branch main
1729
1730 It took 3.25 seconds to enumerate untracked files.
1731 See '\''git help status'\'' for information on how to improve this.
1732
1733 nothing to commit, working tree clean
1734 EOF
1735 test_cmp expected actual
1736 )
1737 '
1738
1739 test_expect_success 'slow status advice when core.untrackedCache true, but not fsmonitor' '
1740 (
1741 cd slowstatus &&
1742 git config core.untrackedCache true &&
1743 git config core.fsmonitor false &&
1744 GIT_TEST_UF_DELAY_WARNING=1 git status >actual &&
1745 cat >expected <<-\EOF &&
1746 On branch main
1747
1748 It took 3.25 seconds to enumerate untracked files.
1749 See '\''git help status'\'' for information on how to improve this.
1750
1751 nothing to commit, working tree clean
1752 EOF
1753 test_cmp expected actual
1754 )
1755 '
1756
1757 test_expect_success 'slow status advice when core.untrackedCache true, and fsmonitor' '
1758 (
1759 cd slowstatus &&
1760 git config core.untrackedCache true &&
1761 git config core.fsmonitor true &&
1762 GIT_TEST_UF_DELAY_WARNING=1 git status >actual &&
1763 cat >expected <<-\EOF &&
1764 On branch main
1765
1766 It took 3.25 seconds to enumerate untracked files,
1767 but the results were cached, and subsequent runs may be faster.
1768 See '\''git help status'\'' for information on how to improve this.
1769
1770 nothing to commit, working tree clean
1771 EOF
1772 test_cmp expected actual
1773 )
1774 '
1775
1776 test_expect_success EXPENSIVE 'status does not re-read unchanged 4 or 8 GiB file' '
1777 (
1778 mkdir large-file &&
1779 cd large-file &&
1780 # Files are 2 GiB, 4 GiB, and 8 GiB sparse files.
1781 test-tool truncate file-a 0x080000000 &&
1782 test-tool truncate file-b 0x100000000 &&
1783 test-tool truncate file-c 0x200000000 &&
1784 # This will be slow.
1785 git add file-a file-b file-c &&
1786 git commit -m "add large files" &&
1787 git diff-index HEAD file-a file-b file-c >actual &&
1788 test_must_be_empty actual
1789 )
1790 '
1791
1792 test_done