| 1 | #!/bin/sh |
| 2 | |
| 3 | test_description='test git repo-info' |
| 4 | |
| 5 | . ./test-lib.sh |
| 6 | |
| 7 | # Test whether a key-value pair is correctly returned |
| 8 | # |
| 9 | # Usage: test_repo_info <label> <init command> <repo_name> <key> <expected value> |
| 10 | # |
| 11 | # Arguments: |
| 12 | # label: the label of the test |
| 13 | # init_command: a command which creates a repository |
| 14 | # repo_name: the name of the repository that will be created in init_command |
| 15 | # key: the key of the field that is being tested |
| 16 | # expected_value: the value that the field should contain |
| 17 | test_repo_info () { |
| 18 | label=$1 |
| 19 | init_command=$2 |
| 20 | repo_name=$3 |
| 21 | key=$4 |
| 22 | expected_value=$5 |
| 23 | |
| 24 | test_expect_success "setup: $label" ' |
| 25 | eval "$init_command $repo_name" |
| 26 | ' |
| 27 | |
| 28 | test_expect_success "lines: $label" ' |
| 29 | echo "$key=$expected_value" > expect && |
| 30 | git -C "$repo_name" repo info "$key" >actual && |
| 31 | test_cmp expect actual |
| 32 | ' |
| 33 | |
| 34 | test_expect_success "nul: $label" ' |
| 35 | printf "%s\n%s\0" "$key" "$expected_value" >expect && |
| 36 | git -C "$repo_name" repo info --format=nul "$key" >actual && |
| 37 | test_cmp_bin expect actual |
| 38 | ' |
| 39 | } |
| 40 | |
| 41 | test_repo_info 'ref format files is retrieved correctly' \ |
| 42 | 'git init --ref-format=files' 'format-files' 'references.format' 'files' |
| 43 | |
| 44 | test_repo_info 'ref format reftable is retrieved correctly' \ |
| 45 | 'git init --ref-format=reftable' 'format-reftable' 'references.format' 'reftable' |
| 46 | |
| 47 | test_repo_info 'bare repository = false is retrieved correctly' \ |
| 48 | 'git init' 'nonbare' 'layout.bare' 'false' |
| 49 | |
| 50 | test_repo_info 'bare repository = true is retrieved correctly' \ |
| 51 | 'git init --bare' 'bare' 'layout.bare' 'true' |
| 52 | |
| 53 | test_repo_info 'shallow repository = false is retrieved correctly' \ |
| 54 | 'git init' 'nonshallow' 'layout.shallow' 'false' |
| 55 | |
| 56 | test_expect_success 'setup remote' ' |
| 57 | git init remote && |
| 58 | echo x >remote/x && |
| 59 | git -C remote add x && |
| 60 | git -C remote commit -m x |
| 61 | ' |
| 62 | |
| 63 | test_repo_info 'shallow repository = true is retrieved correctly' \ |
| 64 | 'git clone --depth 1 "file://$PWD/remote"' 'shallow' 'layout.shallow' 'true' |
| 65 | |
| 66 | test_repo_info 'object.format = sha1 is retrieved correctly' \ |
| 67 | 'git init --object-format=sha1' 'sha1' 'object.format' 'sha1' |
| 68 | |
| 69 | test_repo_info 'object.format = sha256 is retrieved correctly' \ |
| 70 | 'git init --object-format=sha256' 'sha256' 'object.format' 'sha256' |
| 71 | |
| 72 | test_expect_success 'values returned in order requested' ' |
| 73 | cat >expect <<-\EOF && |
| 74 | layout.bare=false |
| 75 | references.format=files |
| 76 | layout.bare=false |
| 77 | EOF |
| 78 | git init --ref-format=files ordered && |
| 79 | git -C ordered repo info layout.bare references.format layout.bare >actual && |
| 80 | test_cmp expect actual |
| 81 | ' |
| 82 | |
| 83 | test_expect_success 'git-repo-info fails if an invalid key is requested' ' |
| 84 | echo "error: key ${SQ}foo${SQ} not found" >expect && |
| 85 | test_must_fail git repo info foo 2>actual && |
| 86 | test_cmp expect actual |
| 87 | ' |
| 88 | |
| 89 | test_expect_success 'git-repo-info outputs data even if there is an invalid field' ' |
| 90 | echo "references.format=$(test_detect_ref_format)" >expect && |
| 91 | test_must_fail git repo info foo references.format bar >actual && |
| 92 | test_cmp expect actual |
| 93 | ' |
| 94 | |
| 95 | test_expect_success 'git-repo-info aborts when requesting an invalid format' ' |
| 96 | echo "fatal: invalid format ${SQ}foo${SQ}" >expect && |
| 97 | test_must_fail git repo info --format=foo 2>actual && |
| 98 | test_cmp expect actual |
| 99 | ' |
| 100 | |
| 101 | test_expect_success '-z uses nul-terminated format' ' |
| 102 | printf "layout.bare\nfalse\0layout.shallow\nfalse\0" >expected && |
| 103 | git repo info -z layout.bare layout.shallow >actual && |
| 104 | test_cmp expected actual |
| 105 | ' |
| 106 | |
| 107 | test_expect_success 'git repo info uses the last requested format' ' |
| 108 | echo "layout.bare=false" >expected && |
| 109 | git repo info --format=nul -z --format=lines layout.bare >actual && |
| 110 | test_cmp expected actual |
| 111 | ' |
| 112 | |
| 113 | test_expect_success 'git repo info --all and git repo info $(git repo info --keys) output the same data' ' |
| 114 | git repo info $(git repo info --keys) >expect && |
| 115 | git repo info --all >actual && |
| 116 | test_cmp expect actual |
| 117 | ' |
| 118 | |
| 119 | test_expect_success 'git repo info --all <key> aborts' ' |
| 120 | echo "fatal: --all and <key> cannot be used together" >expect && |
| 121 | test_must_fail git repo info --all object.format 2>actual && |
| 122 | test_cmp expect actual |
| 123 | ' |
| 124 | |
| 125 | test_expect_success 'git repo info --keys --format=nul uses nul-terminated output' ' |
| 126 | git repo info --keys --format=lines >lines && |
| 127 | lf_to_nul <lines >expect && |
| 128 | git repo info --keys --format=nul >actual && |
| 129 | test_cmp expect actual |
| 130 | ' |
| 131 | |
| 132 | test_expect_success 'git repo info --keys aborts when using --format other than lines or nul' ' |
| 133 | echo "fatal: --keys can only be used with --format=lines or --format=nul" >expect && |
| 134 | test_must_fail git repo info --keys --format=table 2>actual && |
| 135 | test_cmp expect actual |
| 136 | ' |
| 137 | |
| 138 | test_expect_success 'git repo info --keys aborts when requesting keys' ' |
| 139 | echo "fatal: --keys cannot be used with a <key> or --all" >expect && |
| 140 | test_must_fail git repo info --keys --all 2>actual_all && |
| 141 | test_must_fail git repo info --keys some.key 2>actual_key && |
| 142 | test_cmp expect actual_all && |
| 143 | test_cmp expect actual_key |
| 144 | ' |
| 145 | |
| 146 | test_expect_success 'git repo info --keys uses lines as its default output format' ' |
| 147 | git repo info --keys --format=lines >expect && |
| 148 | git repo info --keys >actual && |
| 149 | test_cmp expect actual |
| 150 | ' |
| 151 | |
| 152 | test_expect_success 'git repo info -h shows only repo info usage' ' |
| 153 | git repo info -h >actual && |
| 154 | test_grep "git repo info" actual && |
| 155 | test_grep ! "git repo structure" actual |
| 156 | ' |
| 157 | |
| 158 | # Helper function to test path keys in both absolute and relative formats. |
| 159 | # $1: label for the test |
| 160 | # $2: field_name (e.g., commondir) |
| 161 | # $3: expected_dir (the directory name, e.g., .git or custom-common) |
| 162 | # $4: init_command (extra setup like exporting env vars) |
| 163 | test_repo_info_path () { |
| 164 | label=$1 |
| 165 | field_name=$2 |
| 166 | expected_dir=$3 |
| 167 | init_command=$4 |
| 168 | |
| 169 | test_expect_success "absolute: $label" ' |
| 170 | test_when_finished "rm -rf repo" && |
| 171 | git init repo && |
| 172 | ( |
| 173 | mkdir -p repo/sub && |
| 174 | cd repo/sub && |
| 175 | ROOT="$(test-tool path-utils real_path ..)" && export ROOT && |
| 176 | eval "$init_command" && |
| 177 | echo "path.$field_name.absolute=$ROOT/$expected_dir" >expect && |
| 178 | git repo info "path.$field_name.absolute" >actual && |
| 179 | test_cmp expect actual |
| 180 | ) |
| 181 | ' |
| 182 | |
| 183 | test_expect_success "relative: $label" ' |
| 184 | test_when_finished "rm -rf repo" && |
| 185 | git init repo && |
| 186 | ( |
| 187 | mkdir -p repo/sub && |
| 188 | cd repo/sub && |
| 189 | ROOT="$(test-tool path-utils real_path ..)" && export ROOT && |
| 190 | eval "$init_command" && |
| 191 | echo "path.$field_name.relative=../$expected_dir" >expect && |
| 192 | git repo info "path.$field_name.relative" >actual && |
| 193 | test_cmp expect actual |
| 194 | ) |
| 195 | ' |
| 196 | } |
| 197 | |
| 198 | test_repo_info_path 'commondir standard' 'commondir' '.git' |
| 199 | |
| 200 | test_repo_info_path 'commondir with GIT_COMMON_DIR and GIT_DIR' 'commondir' \ |
| 201 | 'custom-common' \ |
| 202 | 'GIT_COMMON_DIR="$ROOT/custom-common" && export GIT_COMMON_DIR && |
| 203 | GIT_DIR="../.git" && export GIT_DIR && |
| 204 | git init --bare "$ROOT/custom-common"' |
| 205 | |
| 206 | test_repo_info_path 'commondir with only GIT_DIR' 'commondir' \ |
| 207 | '.git' \ |
| 208 | 'GIT_DIR="../.git" && export GIT_DIR' |
| 209 | |
| 210 | test_expect_success 'path.git-prefix at root and in a subdirectory' ' |
| 211 | test_when_finished "rm -rf repo" && |
| 212 | git init repo && |
| 213 | ( |
| 214 | cd repo && |
| 215 | |
| 216 | echo "path.git-prefix=" >expect.root && |
| 217 | git repo info path.git-prefix >actual.root && |
| 218 | test_cmp expect.root actual.root && |
| 219 | |
| 220 | mkdir -p sub/dir && |
| 221 | cd sub/dir && |
| 222 | |
| 223 | echo "path.git-prefix=sub/dir/" >expect.sub && |
| 224 | git repo info path.git-prefix >actual.sub && |
| 225 | test_cmp expect.sub actual.sub |
| 226 | ) |
| 227 | ' |
| 228 | |
| 229 | test_repo_info_path 'gitdir standard' 'gitdir' '.git' |
| 230 | |
| 231 | test_repo_info_path 'gitdir with explicit GIT_DIR' 'gitdir' \ |
| 232 | '.git' \ |
| 233 | 'GIT_DIR="../.git" && export GIT_DIR' |
| 234 | |
| 235 | test_repo_info_path 'grafts standard' 'grafts' '.git/info/grafts' |
| 236 | |
| 237 | test_repo_info_path 'grafts with GIT_GRAFT_FILE override' 'grafts' \ |
| 238 | 'custom-graft-file' \ |
| 239 | 'GIT_GRAFT_FILE="$ROOT/custom-graft-file" && export GIT_GRAFT_FILE' |
| 240 | |
| 241 | test_repo_info_path 'hooks standard fallback' 'hooks' '.git/hooks' |
| 242 | |
| 243 | test_repo_info_path 'hooks with core.hooksPath override' 'hooks' \ |
| 244 | 'custom-hooks' \ |
| 245 | 'git config core.hooksPath "$ROOT/custom-hooks" && mkdir -p "$ROOT/custom-hooks"' |
| 246 | |
| 247 | test_repo_info_path 'index standard' 'index' '.git/index' |
| 248 | |
| 249 | test_repo_info_path 'index with GIT_INDEX_FILE override' 'index' \ |
| 250 | 'custom-index-file' \ |
| 251 | 'GIT_INDEX_FILE="$ROOT/custom-index-file" && export GIT_INDEX_FILE' |
| 252 | |
| 253 | test_expect_success 'path.index in a bare repository returns default index location' ' |
| 254 | test_when_finished "rm -rf bare.git" && |
| 255 | git init --bare bare.git && |
| 256 | ( |
| 257 | cd bare.git && |
| 258 | ROOT="$(test-tool path-utils real_path .)" && |
| 259 | |
| 260 | echo "path.index.absolute=$ROOT/index" >expect.abs && |
| 261 | git repo info path.index.absolute >actual.abs && |
| 262 | test_cmp expect.abs actual.abs && |
| 263 | |
| 264 | echo "path.index.relative=index" >expect.rel && |
| 265 | git repo info path.index.relative >actual.rel && |
| 266 | test_cmp expect.rel actual.rel |
| 267 | ) |
| 268 | ' |
| 269 | |
| 270 | test_repo_info_path 'objects standard' 'objects' '.git/objects' |
| 271 | |
| 272 | test_repo_info_path 'objects with GIT_OBJECT_DIRECTORY override' 'objects' \ |
| 273 | 'custom-objects' \ |
| 274 | 'GIT_OBJECT_DIRECTORY="$ROOT/custom-objects" && export GIT_OBJECT_DIRECTORY && |
| 275 | mkdir -p "$ROOT/custom-objects"' |
| 276 | |
| 277 | test_expect_success 'path.superproject-working-tree absolute and relative' ' |
| 278 | test_when_finished "rm -rf sub super" && |
| 279 | git init sub && |
| 280 | test_commit -C sub initial && |
| 281 | git init super && |
| 282 | ( |
| 283 | cd super && |
| 284 | git -c protocol.file.allow=always submodule add "../sub" sub && |
| 285 | git commit -m "add submodule" && |
| 286 | |
| 287 | cd sub && |
| 288 | ROOT="$(test-tool path-utils real_path ..)" && |
| 289 | |
| 290 | echo "path.superproject-working-tree.absolute=$ROOT" >expect.abs && |
| 291 | git repo info path.superproject-working-tree.absolute >actual.abs && |
| 292 | test_cmp expect.abs actual.abs && |
| 293 | |
| 294 | echo "path.superproject-working-tree.relative=../" >expect.rel && |
| 295 | git repo info path.superproject-working-tree.relative >actual.rel && |
| 296 | test_cmp expect.rel actual.rel |
| 297 | ) |
| 298 | ' |
| 299 | |
| 300 | test_expect_success 'path.superproject-working-tree returns empty when not in a submodule' ' |
| 301 | test_when_finished "rm -rf repo" && |
| 302 | git init repo && |
| 303 | ( |
| 304 | cd repo && |
| 305 | echo "path.superproject-working-tree.absolute=" >expect && |
| 306 | git repo info path.superproject-working-tree.absolute >actual && |
| 307 | test_cmp expect actual |
| 308 | ) |
| 309 | ' |
| 310 | |
| 311 | test_expect_success 'path.toplevel absolute and relative' ' |
| 312 | test_when_finished "rm -rf repo" && |
| 313 | git init repo && |
| 314 | ( |
| 315 | mkdir -p repo/sub && |
| 316 | cd repo/sub && |
| 317 | |
| 318 | ROOT="$(test-tool path-utils real_path ..)" && |
| 319 | |
| 320 | echo "path.toplevel.absolute=$ROOT" >expect.abs && |
| 321 | git repo info path.toplevel.absolute >actual.abs && |
| 322 | test_cmp expect.abs actual.abs && |
| 323 | |
| 324 | echo "path.toplevel.relative=../" >expect.rel && |
| 325 | git repo info path.toplevel.relative >actual.rel && |
| 326 | test_cmp expect.rel actual.rel |
| 327 | ) |
| 328 | ' |
| 329 | |
| 330 | test_expect_success 'path.toplevel returns empty in a bare repository' ' |
| 331 | test_when_finished "rm -rf bare.git" && |
| 332 | git init --bare bare.git && |
| 333 | ( |
| 334 | cd bare.git && |
| 335 | echo "path.toplevel.absolute=" >expect && |
| 336 | git repo info path.toplevel.absolute >actual && |
| 337 | test_cmp expect actual |
| 338 | ) |
| 339 | ' |
| 340 | |
| 341 | test_done |