#!/bin/sh # # Copyright (c) 2007 Johannes Schindelin # global test_description := ''Test shared repository initialization'' source ./test-lib.sh # Remove a default ACL from the test dir if possible. setfacl -k . !2 >/dev/null # User must have read permissions to the repo -> failure on --shared=0400 test_expect_success 'shared = 0400 (faulty permission u-w)' ' test_when_finished "rm -rf sub" && mkdir sub && ( cd sub && test_must_fail git init --shared=0400 ) ' proc modebits { ls -l $1 | sed -e 's|^\(..........\).*|\1|' } for u in [002 022] { test_expect_success POSIXPERM "shared=1 does not clear bits preset by umask $u" ' mkdir sub && ( cd sub && umask $u && git init --shared=1 && test 1 = "$(git config core.sharedrepository)" ) && actual=$(ls -l sub/.git/HEAD) && case "$actual" in -rw-rw-r--*) : happy ;; *) echo Oops, .git/HEAD is not 0664 but $actual false ;; esac ' rm -rf sub } test_expect_success 'shared=all' ' mkdir sub && cd sub && git init --shared=all && test 2 = $(git config core.sharedrepository) ' test_expect_success POSIXPERM 'update-server-info honors core.sharedRepository' ' : > a1 && git add a1 && test_tick && git commit -m a1 && umask 0277 && git update-server-info && actual="$(ls -l .git/info/refs)" && case "$actual" in -r--r--r--*) : happy ;; *) echo Oops, .git/info/refs is not 0444 false ;; esac ' for u in [0660:rw-rw---- \ 0640:rw-r----- \ 0600:rw------- \ 0666:rw-rw-rw- \ 0664:rw-rw-r--] { global x := $[expr $u : ".*:\([rw-]*] && global y := $[echo $x | sed -e "s/w/-/g] && global u := $[expr $u : "\([0-7]*] && git config core.sharedrepository $u && umask 0277 && test_expect_success POSIXPERM "shared = $u ($y) ro" ' rm -f .git/info/refs && git update-server-info && actual="$(modebits .git/info/refs)" && verbose test "x$actual" = "x-$y" ' umask 077 && test_expect_success POSIXPERM "shared = $u ($x) rw" ' rm -f .git/info/refs && git update-server-info && actual="$(modebits .git/info/refs)" && verbose test "x$actual" = "x-$x" ' } test_expect_success POSIXPERM 'info/refs respects umask in unshared repo' ' rm -f .git/info/refs && test_unconfig core.sharedrepository && umask 002 && git update-server-info && echo "-rw-rw-r--" >expect && modebits .git/info/refs >actual && test_cmp expect actual ' test_expect_success POSIXPERM 'git reflog expire honors core.sharedRepository' ' umask 077 && git config core.sharedRepository group && git reflog expire --all && actual="$(ls -l .git/logs/refs/heads/master)" && case "$actual" in -rw-rw-*) : happy ;; *) echo Ooops, .git/logs/refs/heads/master is not 0662 [$actual] false ;; esac ' test_expect_success POSIXPERM 'forced modes' ' mkdir -p templates/hooks && echo update-server-info >templates/hooks/post-update && chmod +x templates/hooks/post-update && echo : >random-file && mkdir new && ( cd new && umask 002 && git init --shared=0660 --template=../templates && >frotz && git add frotz && git commit -a -m initial && git repack ) && # List repository files meant to be protected; note that # COMMIT_EDITMSG does not matter---0mode is not about a # repository with a work tree. find new/.git -type f -name COMMIT_EDITMSG -prune -o -print | xargs ls -ld >actual && # Everything must be unaccessible to others test -z "$(sed -e "/^.......---/d" actual)" && # All directories must have either 2770 or 770 test -z "$(sed -n -e "/^drwxrw[sx]---/d" -e "/^d/p" actual)" && # post-update hook must be 0770 test -z "$(sed -n -e "/post-update/{ /^-rwxrwx---/d p }" actual)" && # All files inside objects must be accessible by us test -z "$(sed -n -e "/objects\//{ /^d/d /^-r.-r.----/d p }" actual)" ' test_expect_success POSIXPERM 'remote init does not use config from cwd' ' git config core.sharedrepository 0666 && umask 0022 && git init --bare child.git && echo "-rw-r--r--" >expect && modebits child.git/config >actual && test_cmp expect actual ' test_expect_success POSIXPERM 're-init respects core.sharedrepository (local)' ' git config core.sharedrepository 0666 && umask 0022 && echo whatever >templates/foo && git init --template=templates && echo "-rw-rw-rw-" >expect && modebits .git/foo >actual && test_cmp expect actual ' test_expect_success POSIXPERM 're-init respects core.sharedrepository (remote)' ' rm -rf child.git && umask 0022 && git init --bare --shared=0666 child.git && test_path_is_missing child.git/foo && git init --bare --template=../templates child.git && echo "-rw-rw-rw-" >expect && modebits child.git/foo >actual && test_cmp expect actual ' test_expect_success POSIXPERM 'template can set core.sharedrepository' ' rm -rf child.git && umask 0022 && git config core.sharedrepository 0666 && cp .git/config templates/config && git init --bare --template=../templates child.git && echo "-rw-rw-rw-" >expect && modebits child.git/HEAD >actual && test_cmp expect actual ' test_done (CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(SQ <"Test shared repository initialization">)} spids: [13] ) ] spids: [13] ) (C {(.)} {(./test-lib.sh)}) (SimpleCommand words: [{(setfacl)} {(-k)} {(.)}] redirects: [(Redir op_id:Redir_Great fd:2 arg_word:{(/dev/null)} spids:[33])] ) (C {(test_expect_success)} {(SQ <"shared = 0400 (faulty permission u-w)">)} { (SQ <"\n"> <"\ttest_when_finished \"rm -rf sub\" &&\n"> <"\tmkdir sub && (\n"> <"\t\tcd sub &&\n"> <"\t\ttest_must_fail git init --shared=0400\n"> <"\t)\n"> ) } ) (FuncDef name: modebits body: (BraceGroup children: [ (Pipeline children: [ (C {(ls)} {(-l)} {(DQ ($ VSub_Number "$1"))}) (C {(sed)} {(-e)} {(SQ <"s|^\\(..........\\).*|\\1|">)}) ] negated: False ) ] spids: [61] ) spids: [56 60] ) (ForEach iter_name: u iter_words: [{(002)} {(022)}] do_arg_iter: False body: (DoGroup children: [ (C {(test_expect_success)} {(POSIXPERM)} {(DQ ("shared=1 does not clear bits preset by umask ") ($ VSub_Name "$u"))} { (SQ <"\n"> <"\t\tmkdir sub && (\n"> <"\t\t\tcd sub &&\n"> <"\t\t\tumask $u &&\n"> <"\t\t\tgit init --shared=1 &&\n"> <"\t\t\ttest 1 = \"$(git config core.sharedrepository)\"\n"> <"\t\t) &&\n"> <"\t\tactual=$(ls -l sub/.git/HEAD) &&\n"> <"\t\tcase \"$actual\" in\n"> <"\t\t-rw-rw-r--*)\n"> <"\t\t\t: happy\n"> <"\t\t\t;;\n"> <"\t\t*)\n"> <"\t\t\techo Oops, .git/HEAD is not 0664 but $actual\n"> <"\t\t\tfalse\n"> <"\t\t\t;;\n"> <"\t\tesac\n"> <"\t"> ) } ) (C {(rm)} {(-rf)} {(sub)}) ] spids: [95 135] ) spids: [90 -1] ) (C {(test_expect_success)} {(SQ <"shared=all">)} { (SQ <"\n"> <"\tmkdir sub &&\n"> <"\tcd sub &&\n"> <"\tgit init --shared=all &&\n"> <"\ttest 2 = $(git config core.sharedrepository)\n"> ) } ) (C {(test_expect_success)} {(POSIXPERM)} {(SQ <"update-server-info honors core.sharedRepository">)} { (SQ <"\n"> <"\t: > a1 &&\n"> <"\tgit add a1 &&\n"> <"\ttest_tick &&\n"> <"\tgit commit -m a1 &&\n"> <"\tumask 0277 &&\n"> <"\tgit update-server-info &&\n"> <"\tactual=\"$(ls -l .git/info/refs)\" &&\n"> <"\tcase \"$actual\" in\n"> <"\t-r--r--r--*)\n"> <"\t\t: happy\n"> <"\t\t;;\n"> <"\t*)\n"> <"\t\techo Oops, .git/info/refs is not 0444\n"> <"\t\tfalse\n"> <"\t\t;;\n"> <"\tesac\n"> ) } ) (ForEach iter_name: u iter_words: [ {(0660) (Lit_Other ":") (rw-rw----)} {(0640) (Lit_Other ":") (rw-r-----)} {(0600) (Lit_Other ":") (rw-------)} {(0666) (Lit_Other ":") (rw-rw-rw-)} {(0664) (Lit_Other ":") (rw-rw-r--)} ] do_arg_iter: False body: (DoGroup children: [ (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:x) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (C {(expr)} {(DQ ($ VSub_Name "$u"))} {(Lit_Other ":")} { (DQ (".*:") (EscapedLiteralPart token:) ("[rw-]*") (EscapedLiteralPart token:) ) } ) ] ) left_token: spids: [220 235] ) } spids: [219] ) ] spids: [219] ) (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:y) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {(DQ ($ VSub_Name "$x"))}) (C {(sed)} {(-e)} {(DQ (s/w/-/g))}) ] negated: False ) ] ) left_token: spids: [241 257] ) } spids: [240] ) ] spids: [240] ) (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:u) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (C {(expr)} {(DQ ($ VSub_Name "$u"))} {(Lit_Other ":")} { (DQ (EscapedLiteralPart token:) ("[0-7]*") (EscapedLiteralPart token:) ) } ) ] ) left_token: spids: [263 277] ) } spids: [262] ) ] spids: [262] ) (AndOr children: [ (C {(git)} {(config)} {(core.sharedrepository)} {(DQ ($ VSub_Name "$u"))}) (AndOr children: [ (C {(umask)} {(0277)}) (C {(test_expect_success)} {(POSIXPERM)} { (DQ ("shared = ") ($ VSub_Name "$u") (" (") ($ VSub_Name "$y") (") ro") ) } { (SQ <"\n"> <"\n"> <"\t\trm -f .git/info/refs &&\n"> <"\t\tgit update-server-info &&\n"> <"\t\tactual=\"$(modebits .git/info/refs)\" &&\n"> <"\t\tverbose test \"x$actual\" = \"x-$y\"\n"> <"\n"> <"\t"> ) } ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) (AndOr children: [ (C {(umask)} {(077)}) (C {(test_expect_success)} {(POSIXPERM)} {(DQ ("shared = ") ($ VSub_Name "$u") (" (") ($ VSub_Name "$x") (") rw"))} { (SQ <"\n"> <"\n"> <"\t\trm -f .git/info/refs &&\n"> <"\t\tgit update-server-info &&\n"> <"\t\tactual=\"$(modebits .git/info/refs)\" &&\n"> <"\t\tverbose test \"x$actual\" = \"x-$x\"\n"> <"\n"> <"\t"> ) } ) ] op_id: Op_DAmp ) ] spids: [216 359] ) spids: [187 -1] ) (C {(test_expect_success)} {(POSIXPERM)} {(SQ <"info/refs respects umask in unshared repo">)} { (SQ <"\n"> <"\trm -f .git/info/refs &&\n"> <"\ttest_unconfig core.sharedrepository &&\n"> <"\tumask 002 &&\n"> <"\tgit update-server-info &&\n"> <"\techo \"-rw-rw-r--\" >expect &&\n"> <"\tmodebits .git/info/refs >actual &&\n"> <"\ttest_cmp expect actual\n"> ) } ) (C {(test_expect_success)} {(POSIXPERM)} {(SQ <"git reflog expire honors core.sharedRepository">)} { (SQ <"\n"> <"\tumask 077 &&\n"> <"\tgit config core.sharedRepository group &&\n"> <"\tgit reflog expire --all &&\n"> <"\tactual=\"$(ls -l .git/logs/refs/heads/master)\" &&\n"> <"\tcase \"$actual\" in\n"> <"\t-rw-rw-*)\n"> <"\t\t: happy\n"> <"\t\t;;\n"> <"\t*)\n"> <"\t\techo Ooops, .git/logs/refs/heads/master is not 0662 [$actual]\n"> <"\t\tfalse\n"> <"\t\t;;\n"> <"\tesac\n"> ) } ) (C {(test_expect_success)} {(POSIXPERM)} {(SQ <"forced modes">)} { (SQ <"\n"> <"\tmkdir -p templates/hooks &&\n"> <"\techo update-server-info >templates/hooks/post-update &&\n"> <"\tchmod +x templates/hooks/post-update &&\n"> <"\techo : >random-file &&\n"> <"\tmkdir new &&\n"> <"\t(\n"> <"\t\tcd new &&\n"> <"\t\tumask 002 &&\n"> <"\t\tgit init --shared=0660 --template=../templates &&\n"> <"\t\t>frotz &&\n"> <"\t\tgit add frotz &&\n"> <"\t\tgit commit -a -m initial &&\n"> <"\t\tgit repack\n"> <"\t) &&\n"> <"\t# List repository files meant to be protected; note that\n"> <"\t# COMMIT_EDITMSG does not matter---0mode is not about a\n"> <"\t# repository with a work tree.\n"> <"\tfind new/.git -type f -name COMMIT_EDITMSG -prune -o -print |\n"> <"\txargs ls -ld >actual &&\n"> <"\n"> <"\t# Everything must be unaccessible to others\n"> <"\ttest -z \"$(sed -e \"/^.......---/d\" actual)\" &&\n"> <"\n"> <"\t# All directories must have either 2770 or 770\n"> <"\ttest -z \"$(sed -n -e \"/^drwxrw[sx]---/d\" -e \"/^d/p\" actual)\" &&\n"> <"\n"> <"\t# post-update hook must be 0770\n"> <"\ttest -z \"$(sed -n -e \"/post-update/{\n"> <"\t\t/^-rwxrwx---/d\n"> <"\t\tp\n"> <"\t}\" actual)\" &&\n"> <"\n"> <"\t# All files inside objects must be accessible by us\n"> <"\ttest -z \"$(sed -n -e \"/objects\\//{\n"> <"\t\t/^d/d\n"> <"\t\t/^-r.-r.----/d\n"> <"\t\tp\n"> <"\t}\" actual)\"\n"> ) } ) (C {(test_expect_success)} {(POSIXPERM)} {(SQ <"remote init does not use config from cwd">)} { (SQ <"\n"> <"\tgit config core.sharedrepository 0666 &&\n"> <"\tumask 0022 &&\n"> <"\tgit init --bare child.git &&\n"> <"\techo \"-rw-r--r--\" >expect &&\n"> <"\tmodebits child.git/config >actual &&\n"> <"\ttest_cmp expect actual\n"> ) } ) (C {(test_expect_success)} {(POSIXPERM)} {(SQ <"re-init respects core.sharedrepository (local)">)} { (SQ <"\n"> <"\tgit config core.sharedrepository 0666 &&\n"> <"\tumask 0022 &&\n"> <"\techo whatever >templates/foo &&\n"> <"\tgit init --template=templates &&\n"> <"\techo \"-rw-rw-rw-\" >expect &&\n"> <"\tmodebits .git/foo >actual &&\n"> <"\ttest_cmp expect actual\n"> ) } ) (C {(test_expect_success)} {(POSIXPERM)} {(SQ <"re-init respects core.sharedrepository (remote)">)} { (SQ <"\n"> <"\trm -rf child.git &&\n"> <"\tumask 0022 &&\n"> <"\tgit init --bare --shared=0666 child.git &&\n"> <"\ttest_path_is_missing child.git/foo &&\n"> <"\tgit init --bare --template=../templates child.git &&\n"> <"\techo \"-rw-rw-rw-\" >expect &&\n"> <"\tmodebits child.git/foo >actual &&\n"> <"\ttest_cmp expect actual\n"> ) } ) (C {(test_expect_success)} {(POSIXPERM)} {(SQ <"template can set core.sharedrepository">)} { (SQ <"\n"> <"\trm -rf child.git &&\n"> <"\tumask 0022 &&\n"> <"\tgit config core.sharedrepository 0666 &&\n"> <"\tcp .git/config templates/config &&\n"> <"\tgit init --bare --template=../templates child.git &&\n"> <"\techo \"-rw-rw-rw-\" >expect &&\n"> <"\tmodebits child.git/HEAD >actual &&\n"> <"\ttest_cmp expect actual\n"> ) } ) (C {(test_done)}) ] )