| 1 | #!/bin/sh |
| 2 | # shellcheck disable=SC2016 |
| 3 | |
| 4 | # shellcheck disable=SC2034 |
| 5 | test_description='git add respects submodule ignore=all and explicit pathspec' |
| 6 | |
| 7 | # This test covers the behavior of "git add", "git status" and "git log" when |
| 8 | # dealing with submodules that have the ignore=all setting in |
| 9 | # .gitmodules. It ensures that changes in such submodules are |
| 10 | # ignored by default, but can be staged with "git add --force". |
| 11 | |
| 12 | # shellcheck disable=SC1091 |
| 13 | . ./test-lib.sh |
| 14 | |
| 15 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
| 16 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
| 17 | |
| 18 | base_path=$(pwd -P) |
| 19 | |
| 20 | #1 |
| 21 | test_expect_success 'setup: create origin repos' ' |
| 22 | cd "${base_path}" && |
| 23 | git config --global protocol.file.allow always && |
| 24 | git init sub && |
| 25 | pwd && |
| 26 | cd sub && |
| 27 | test_commit sub_file1 && |
| 28 | git tag v1.0 && |
| 29 | test_commit sub_file2 && |
| 30 | git tag v2.0 && |
| 31 | test_commit sub_file3 && |
| 32 | git tag v3.0 && |
| 33 | cd "${base_path}" && |
| 34 | git init main && |
| 35 | cd main && |
| 36 | test_commit first && |
| 37 | cd "${base_path}" |
| 38 | ' |
| 39 | #2 |
| 40 | # add submodule with default config (ignore=none) and |
| 41 | # check log that is contains a path entry for the submodule 'sub' |
| 42 | # change the commit in the submodule and check that 'git status' shows it as modified |
| 43 | test_expect_success 'main: add submodule with default config' ' |
| 44 | cd "${base_path}" && |
| 45 | cd main && |
| 46 | git submodule add ../sub && |
| 47 | git commit -m "add submodule" && |
| 48 | git log --oneline --name-only | grep "^sub$" && |
| 49 | git -C sub reset --hard v2.0 && |
| 50 | git status --porcelain | grep "^ M sub$" && |
| 51 | echo |
| 52 | ' |
| 53 | #3 |
| 54 | # change the submodule config to ignore=all and check that status and log do not show changes |
| 55 | test_expect_success 'main: submodule config ignore=all' ' |
| 56 | cd "${base_path}" && |
| 57 | cd main && |
| 58 | git config -f .gitmodules submodule.sub.ignore all && |
| 59 | GIT_TRACE=1 git add . && |
| 60 | git commit -m "update submodule config sub.ignore all" && |
| 61 | ! git status --porcelain | grep "^.*$" && |
| 62 | ! git log --oneline --name-only | grep "^sub$" && |
| 63 | echo |
| 64 | ' |
| 65 | #4 |
| 66 | # change the commit in the submodule and check that 'git status' does not show it as modified |
| 67 | # but 'git status --ignore-submodules=none' does show it as modified |
| 68 | test_expect_success 'sub: change to different sha1 and check status in main' ' |
| 69 | cd "${base_path}" && |
| 70 | cd main && |
| 71 | git -C sub reset --hard v1.0 && |
| 72 | ! git status --porcelain | grep "^ M sub$" && |
| 73 | git status --ignore-submodules=none --porcelain | grep "^ M sub$" && |
| 74 | echo |
| 75 | ' |
| 76 | |
| 77 | #5 |
| 78 | # check that normal 'git add' does not stage the change in the submodule |
| 79 | test_expect_success 'main: check normal add and status' ' |
| 80 | cd "${base_path}" && |
| 81 | cd main && |
| 82 | GIT_TRACE=1 git add . && |
| 83 | ! git status --porcelain | grep "^ M sub$" && |
| 84 | echo |
| 85 | ' |
| 86 | |
| 87 | #6 |
| 88 | # check that 'git add --force .' does not stage the change in the submodule |
| 89 | # and that 'git status' does not show it as modified |
| 90 | test_expect_success 'main: check --force add . and status' ' |
| 91 | cd "${base_path}" && |
| 92 | cd main && |
| 93 | GIT_TRACE=1 git add --force . && |
| 94 | ! git status --porcelain | grep "^M sub$" && |
| 95 | echo |
| 96 | ' |
| 97 | |
| 98 | #7 |
| 99 | # check that 'git add .' does not stage the change in the submodule |
| 100 | # and that 'git status' does not show it as modified |
| 101 | test_expect_success 'main: check _add sub_ and status' ' |
| 102 | cd "${base_path}" && |
| 103 | cd main && |
| 104 | GIT_TRACE=1 git add sub 2>&1 | grep "Skipping submodule due to ignore=all: sub" && |
| 105 | ! git status --porcelain | grep "^M sub$" && |
| 106 | echo |
| 107 | ' |
| 108 | |
| 109 | #8 |
| 110 | # check that 'git add --force sub' does stage the change in the submodule |
| 111 | # check that 'git add --force ./sub/' does stage the change in the submodule |
| 112 | # and that 'git status --porcelain' does show it as modified |
| 113 | # commit it.. |
| 114 | # check that 'git log --ignore-submodules=none' shows the submodule change |
| 115 | # in the log |
| 116 | test_expect_success 'main: check force add sub and ./sub/ and status' ' |
| 117 | cd "${base_path}" && |
| 118 | cd main && |
| 119 | echo "Adding with --force should work: git add --force sub" && |
| 120 | GIT_TRACE=1 git add --force sub && |
| 121 | git status --porcelain | grep "^M sub$" && |
| 122 | git restore --staged sub && |
| 123 | ! git status --porcelain | grep "^M sub$" && |
| 124 | echo "Adding with --force should work: git add --force ./sub/" && |
| 125 | GIT_TRACE=1 git add --force ./sub/ && |
| 126 | git status --porcelain | grep "^M sub$" && |
| 127 | git commit -m "update submodule pointer" && |
| 128 | ! git status --porcelain | grep "^ M sub$" && |
| 129 | git log --ignore-submodules=none --name-only --oneline | grep "^sub$" && |
| 130 | echo |
| 131 | ' |
| 132 | |
| 133 | test_done |
| 134 | exit 0 |