| 1 | #!/bin/sh |
| 2 | |
| 3 | test_description='test the `scalar` command' |
| 4 | |
| 5 | . ./test-lib.sh |
| 6 | |
| 7 | GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab cron.txt,launchctl:true,schtasks:true" |
| 8 | export GIT_TEST_MAINT_SCHEDULER |
| 9 | |
| 10 | test_expect_success 'scalar shows a usage' ' |
| 11 | test_expect_code 129 scalar -h |
| 12 | ' |
| 13 | |
| 14 | test_expect_success 'scalar invoked on enlistment root' ' |
| 15 | test_when_finished rm -rf test src deeper && |
| 16 | |
| 17 | for enlistment_root in test src deeper/test |
| 18 | do |
| 19 | git init ${enlistment_root}/src && |
| 20 | |
| 21 | # Register |
| 22 | scalar register ${enlistment_root} && |
| 23 | scalar list >out && |
| 24 | grep "$(pwd)/${enlistment_root}/src\$" out && |
| 25 | |
| 26 | # Delete (including enlistment root) |
| 27 | scalar delete $enlistment_root && |
| 28 | test_path_is_missing $enlistment_root && |
| 29 | scalar list >out && |
| 30 | ! grep "^$(pwd)/${enlistment_root}/src\$" out || return 1 |
| 31 | done |
| 32 | ' |
| 33 | |
| 34 | test_expect_success 'scalar invoked on enlistment src repo' ' |
| 35 | test_when_finished rm -rf test src deeper && |
| 36 | |
| 37 | for enlistment_root in test src deeper/test |
| 38 | do |
| 39 | git init ${enlistment_root}/src && |
| 40 | |
| 41 | # Register |
| 42 | scalar register ${enlistment_root}/src && |
| 43 | scalar list >out && |
| 44 | grep "$(pwd)/${enlistment_root}/src\$" out && |
| 45 | |
| 46 | # Delete (will not include enlistment root) |
| 47 | scalar delete ${enlistment_root}/src && |
| 48 | test_path_is_dir $enlistment_root && |
| 49 | scalar list >out && |
| 50 | ! grep "^$(pwd)/${enlistment_root}/src\$" out || return 1 |
| 51 | done |
| 52 | ' |
| 53 | |
| 54 | test_expect_success 'scalar invoked when enlistment root and repo are the same' ' |
| 55 | test_when_finished rm -rf test src deeper && |
| 56 | |
| 57 | for enlistment_root in test src deeper/test |
| 58 | do |
| 59 | git init ${enlistment_root} && |
| 60 | |
| 61 | # Register |
| 62 | scalar register ${enlistment_root} && |
| 63 | scalar list >out && |
| 64 | grep "$(pwd)/${enlistment_root}\$" out && |
| 65 | |
| 66 | # Delete (will not include enlistment root) |
| 67 | scalar delete ${enlistment_root} && |
| 68 | test_path_is_missing $enlistment_root && |
| 69 | scalar list >out && |
| 70 | ! grep "^$(pwd)/${enlistment_root}\$" out && |
| 71 | |
| 72 | # Make sure we did not accidentally delete the trash dir |
| 73 | test_path_is_dir "$TRASH_DIRECTORY" || return 1 |
| 74 | done |
| 75 | ' |
| 76 | |
| 77 | test_expect_success 'scalar repo search respects GIT_CEILING_DIRECTORIES' ' |
| 78 | test_when_finished rm -rf test && |
| 79 | |
| 80 | git init test/src && |
| 81 | mkdir -p test/src/deep && |
| 82 | GIT_CEILING_DIRECTORIES="$(pwd)/test/src" && |
| 83 | ! scalar register test/src/deep 2>err && |
| 84 | grep "not a git repository" err |
| 85 | ' |
| 86 | |
| 87 | test_expect_success 'scalar enlistments need a worktree' ' |
| 88 | test_when_finished rm -rf bare test && |
| 89 | |
| 90 | git init --bare bare/src && |
| 91 | ! scalar register bare/src 2>err && |
| 92 | grep "Scalar enlistments require a worktree" err && |
| 93 | |
| 94 | git init test/src && |
| 95 | ! scalar register test/src/.git 2>err && |
| 96 | grep "Scalar enlistments require a worktree" err |
| 97 | ' |
| 98 | |
| 99 | test_expect_success FSMONITOR_DAEMON 'scalar register starts fsmon daemon' ' |
| 100 | git init test/src && |
| 101 | test_must_fail git -C test/src fsmonitor--daemon status && |
| 102 | scalar register test/src && |
| 103 | git -C test/src fsmonitor--daemon status && |
| 104 | test_cmp_config -C test/src true core.fsmonitor |
| 105 | ' |
| 106 | |
| 107 | test_expect_success 'scalar register warns when background maintenance fails' ' |
| 108 | git init register-repo && |
| 109 | GIT_TEST_MAINT_SCHEDULER="crontab:false,launchctl:false,schtasks:false" \ |
| 110 | scalar register register-repo 2>err && |
| 111 | grep "could not toggle maintenance" err |
| 112 | ' |
| 113 | |
| 114 | test_expect_success 'scalar unregister' ' |
| 115 | git init vanish/src && |
| 116 | scalar register vanish/src && |
| 117 | git config --get --global --fixed-value \ |
| 118 | maintenance.repo "$(pwd)/vanish/src" && |
| 119 | scalar list >scalar.repos && |
| 120 | grep -F "$(pwd)/vanish/src" scalar.repos && |
| 121 | rm -rf vanish/src/.git && |
| 122 | scalar unregister vanish && |
| 123 | test_must_fail git config --get --global --fixed-value \ |
| 124 | maintenance.repo "$(pwd)/vanish/src" && |
| 125 | scalar list >scalar.repos && |
| 126 | ! grep -F "$(pwd)/vanish/src" scalar.repos && |
| 127 | |
| 128 | # scalar unregister should be idempotent |
| 129 | scalar unregister vanish |
| 130 | ' |
| 131 | |
| 132 | test_expect_success 'scalar register --no-maintenance' ' |
| 133 | git init register-no-maint && |
| 134 | event_log="$(pwd)/no-maint.event" && |
| 135 | GIT_TEST_MAINT_SCHEDULER="crontab:false,launchctl:false,schtasks:false" \ |
| 136 | GIT_TRACE2_EVENT="$event_log" \ |
| 137 | GIT_TRACE2_EVENT_DEPTH=100 \ |
| 138 | scalar register --no-maintenance register-no-maint 2>err && |
| 139 | test_must_be_empty err && |
| 140 | test_subcommand ! git maintenance unregister --force <no-maint.event |
| 141 | ' |
| 142 | |
| 143 | test_expect_success 'set up repository to clone' ' |
| 144 | test_commit first && |
| 145 | test_commit second && |
| 146 | test_commit third && |
| 147 | git switch -c parallel first && |
| 148 | mkdir -p 1/2 && |
| 149 | test_commit 1/2/3 && |
| 150 | git config uploadPack.allowFilter true && |
| 151 | git config uploadPack.allowAnySHA1InWant true |
| 152 | ' |
| 153 | |
| 154 | test_expect_success 'scalar clone' ' |
| 155 | # index.skipHash (Scalar default) and GIT_TEST_SPLIT_INDEX are |
| 156 | # incompatible: the shared index gets a null OID and fails to |
| 157 | # load on re-read. |
| 158 | sane_unset GIT_TEST_SPLIT_INDEX && |
| 159 | second=$(git rev-parse --verify second:second.t) && |
| 160 | scalar clone "file://$(pwd)" cloned --single-branch && |
| 161 | ( |
| 162 | cd cloned/src && |
| 163 | |
| 164 | git config --get --global --fixed-value maintenance.repo \ |
| 165 | "$(pwd)" && |
| 166 | |
| 167 | git for-each-ref --format="%(refname)" refs/remotes/origin/ >actual && |
| 168 | echo "refs/remotes/origin/HEAD" >>expect && |
| 169 | echo "refs/remotes/origin/parallel" >>expect && |
| 170 | test_cmp expect actual && |
| 171 | |
| 172 | test_path_is_missing 1/2 && |
| 173 | |
| 174 | # This relies on the fact that the presence of "--missing" |
| 175 | # on the command line forces lazy fetching off before |
| 176 | # "$second^{blob}" gets parsed. Without "^{blob}", a |
| 177 | # bare object name "$second" is taken into the queue and |
| 178 | # the command may not fail with a fixed "rev-list --missing". |
| 179 | test_must_fail git rev-list --missing=print "$second^{blob}" -- && |
| 180 | |
| 181 | git rev-list $second && |
| 182 | git cat-file blob $second >actual && |
| 183 | echo "second" >expect && |
| 184 | test_cmp expect actual |
| 185 | ) |
| 186 | ' |
| 187 | |
| 188 | test_expect_success 'scalar clone --no-... opts' ' |
| 189 | sane_unset GIT_TEST_SPLIT_INDEX && |
| 190 | # Note: redirect stderr always to avoid having a verbose test |
| 191 | # run result in a difference in the --[no-]progress option. |
| 192 | GIT_TRACE2_EVENT="$(pwd)/no-opt-trace" scalar clone \ |
| 193 | --no-tags --no-src \ |
| 194 | "file://$(pwd)" no-opts --single-branch 2>/dev/null && |
| 195 | |
| 196 | test_subcommand git fetch --quiet --no-progress \ |
| 197 | origin --no-tags <no-opt-trace && |
| 198 | ( |
| 199 | cd no-opts && |
| 200 | |
| 201 | test_cmp_config --no-tags remote.origin.tagopt && |
| 202 | git for-each-ref --format="%(refname)" refs/tags/ >tags && |
| 203 | test_line_count = 0 tags |
| 204 | ) |
| 205 | ' |
| 206 | |
| 207 | test_expect_success 'scalar reconfigure' ' |
| 208 | git init one/src && |
| 209 | scalar register one && |
| 210 | git -C one/src config unset gui.gcwarning && |
| 211 | scalar reconfigure one && |
| 212 | test false = "$(git -C one/src config gui.gcwarning)" && |
| 213 | git -C one/src config unset gui.gcwarning && |
| 214 | rm one/src/cron.txt && |
| 215 | GIT_TRACE2_EVENT="$(pwd)/reconfigure" scalar reconfigure -a && |
| 216 | test_path_is_file one/src/cron.txt && |
| 217 | test false = "$(git -C one/src config gui.gcwarning)" && |
| 218 | test_grep "GCWarning = false # set by scalar" one/src/.git/config && |
| 219 | test_grep "excludeDecoration = refs/prefetch/\* # set by scalar" one/src/.git/config && |
| 220 | |
| 221 | test_subcommand git maintenance start <reconfigure && |
| 222 | test_subcommand ! git maintenance unregister --force <reconfigure && |
| 223 | |
| 224 | GIT_TRACE2_EVENT="$(pwd)/reconfigure-maint-disable" \ |
| 225 | scalar reconfigure -a --maintenance=disable && |
| 226 | test_subcommand ! git maintenance start <reconfigure-maint-disable && |
| 227 | test_subcommand git maintenance unregister --force <reconfigure-maint-disable && |
| 228 | |
| 229 | GIT_TRACE2_EVENT="$(pwd)/reconfigure-maint-keep" \ |
| 230 | scalar reconfigure --maintenance=keep -a && |
| 231 | test_subcommand ! git maintenance start <reconfigure-maint-keep && |
| 232 | test_subcommand ! git maintenance unregister --force <reconfigure-maint-keep |
| 233 | ' |
| 234 | |
| 235 | test_expect_success 'scalar reconfigure --all with includeIf.onbranch' ' |
| 236 | repos="two three four" && |
| 237 | for num in $repos |
| 238 | do |
| 239 | git init $num/src && |
| 240 | scalar register $num/src && |
| 241 | git -C $num/src config includeif."onbranch:foo".path something && |
| 242 | git -C $num/src config unset gui.gcwarning || return 1 |
| 243 | done && |
| 244 | |
| 245 | scalar reconfigure --all && |
| 246 | |
| 247 | for num in $repos |
| 248 | do |
| 249 | test false = "$(git -C $num/src config gui.gcwarning)" || return 1 |
| 250 | done |
| 251 | ' |
| 252 | |
| 253 | test_expect_success 'scalar reconfigure --all with detached HEADs' ' |
| 254 | # This test demonstrates an issue with index.skipHash=true and |
| 255 | # this test variable for the split index. Disable the test variable. |
| 256 | sane_unset GIT_TEST_SPLIT_INDEX && |
| 257 | |
| 258 | repos="two three four" && |
| 259 | for num in $repos |
| 260 | do |
| 261 | rm -rf $num/src && |
| 262 | git init $num/src && |
| 263 | scalar register $num/src && |
| 264 | git -C $num/src config unset gui.gcwarning && |
| 265 | test_commit -C $num/src initial && |
| 266 | git -C $num/src switch --detach HEAD || return 1 |
| 267 | done && |
| 268 | |
| 269 | scalar reconfigure --all && |
| 270 | |
| 271 | for num in $repos |
| 272 | do |
| 273 | test false = "$(git -C $num/src config gui.gcwarning)" || return 1 |
| 274 | done |
| 275 | ' |
| 276 | |
| 277 | test_expect_success '`reconfigure -a` removes stale config entries' ' |
| 278 | git init stale/src && |
| 279 | scalar register stale && |
| 280 | scalar list >scalar.repos && |
| 281 | grep stale scalar.repos && |
| 282 | |
| 283 | grep -v stale scalar.repos >expect && |
| 284 | |
| 285 | rm -rf stale && |
| 286 | scalar reconfigure -a && |
| 287 | scalar list >scalar.repos && |
| 288 | test_cmp expect scalar.repos |
| 289 | ' |
| 290 | |
| 291 | test_expect_success 'scalar delete without enlistment shows a usage' ' |
| 292 | test_expect_code 129 scalar delete |
| 293 | ' |
| 294 | |
| 295 | test_expect_success 'scalar delete with enlistment' ' |
| 296 | scalar delete cloned && |
| 297 | test_path_is_missing cloned |
| 298 | ' |
| 299 | |
| 300 | test_expect_success 'scalar supports -c/-C' ' |
| 301 | test_when_finished "scalar delete sub" && |
| 302 | git init sub && |
| 303 | scalar -C sub -c status.aheadBehind=bogus register && |
| 304 | test -z "$(git -C sub config --local status.aheadBehind)" && |
| 305 | test false = "$(git -C sub config gui.gcwarning)" |
| 306 | ' |
| 307 | |
| 308 | test_expect_success '`scalar [...] <dir>` errors out when dir is missing' ' |
| 309 | ! scalar run config cloned 2>err && |
| 310 | grep "cloned. does not exist" err |
| 311 | ' |
| 312 | |
| 313 | SQ="'" |
| 314 | test_expect_success UNZIP 'scalar diagnose' ' |
| 315 | sane_unset GIT_TEST_SPLIT_INDEX && |
| 316 | scalar clone "file://$(pwd)" cloned --single-branch && |
| 317 | git repack && |
| 318 | echo "$(pwd)/.git/objects/" >>cloned/src/.git/objects/info/alternates && |
| 319 | test_commit -C cloned/src loose && |
| 320 | scalar diagnose cloned >out 2>err && |
| 321 | grep "Available space" out && |
| 322 | sed -n "s/.*$SQ\\(.*\\.zip\\)$SQ.*/\\1/p" <err >zip_path && |
| 323 | zip_path=$(cat zip_path) && |
| 324 | test -n "$zip_path" && |
| 325 | "$GIT_UNZIP" -v "$zip_path" && |
| 326 | folder=${zip_path%.zip} && |
| 327 | test_path_is_missing "$folder" && |
| 328 | "$GIT_UNZIP" -p "$zip_path" diagnostics.log >out && |
| 329 | test_file_not_empty out && |
| 330 | "$GIT_UNZIP" -p "$zip_path" packs-local.txt >out && |
| 331 | grep "$(pwd)/.git/objects" out && |
| 332 | "$GIT_UNZIP" -p "$zip_path" objects-local.txt >out && |
| 333 | grep "^Total: [1-9]" out |
| 334 | ' |
| 335 | |
| 336 | test_done |