Git fork
at reftables-rust 224 lines 6.5 kB view raw
1#!/bin/sh 2# 3# Copyright (c) 2012 Robert Luberda 4# 5 6test_description='concurrent git svn dcommit' 7 8. ./lib-git-svn.sh 9 10 11 12test_expect_success 'setup svn repository' ' 13 svn_cmd checkout "$svnrepo" work.svn && 14 ( 15 cd work.svn && 16 echo >file && echo > auto_updated_file && 17 svn_cmd add file auto_updated_file && 18 svn_cmd commit -m "initial commit" 19 ) && 20 svn_cmd checkout "$svnrepo" work-auto-commits.svn 21' 22N=0 23next_N() 24{ 25 N=$(( $N + 1 )) 26} 27 28# Setup SVN repository hooks to emulate SVN failures or concurrent commits 29# The function adds 30# either pre-commit hook, which causes SVN commit given in second argument 31# to fail 32# or post-commit hook, which creates a new commit (a new line added to 33# auto_updated_file) after given SVN commit 34# The first argument contains a type of the hook 35# The second argument contains a number (not SVN revision) of commit 36# the hook should be applied for (each time the hook is run, the given 37# number is decreased by one until it gets 0, in which case the hook 38# will execute its real action) 39setup_hook() 40{ 41 hook_type="$1" # "pre-commit" or "post-commit" 42 skip_revs="$2" 43 [ "$hook_type" = "pre-commit" ] || 44 [ "$hook_type" = "post-commit" ] || 45 { echo "ERROR: invalid argument ($hook_type)" \ 46 "passed to setup_hook" >&2 ; return 1; } 47 echo "cnt=$skip_revs" > "$hook_type-counter" 48 rm -f "$rawsvnrepo/hooks/"*-commit # drop previous hooks 49 50 # Subversion hooks run with an empty environment by default. We thus 51 # need to propagate PATH so that we can find executables. 52 cat >"$rawsvnrepo/conf/hooks-env" <<-EOF 53 [default] 54 PATH = ${PATH} 55 EOF 56 57 hook="$rawsvnrepo/hooks/$hook_type" 58 cat > "$hook" <<- 'EOF1' 59 #!/bin/sh 60 set -e 61 cd "$1/.." # "$1" is repository location 62 exec >> svn-hook.log 2>&1 63 hook="$(basename "$0")" 64 echo "*** Executing $hook $@" 65 set -x 66 . ./$hook-counter 67 cnt="$(($cnt - 1))" 68 echo "cnt=$cnt" > ./$hook-counter 69 [ "$cnt" = "0" ] || exit 0 70EOF1 71 if [ "$hook_type" = "pre-commit" ]; then 72 echo "echo 'commit disallowed' >&2; exit 1" >>"$hook" 73 else 74 echo "svnconf=\"$svnconf\"" >>"$hook" 75 cat >>"$hook" <<- 'EOF2' 76 cd work-auto-commits.svn 77 svn up --config-dir "$svnconf" 78 echo "$$" >> auto_updated_file 79 svn commit --config-dir "$svnconf" \ 80 -m "auto-committing concurrent change" 81 exit 0 82EOF2 83 fi 84 chmod 755 "$hook" 85} 86 87check_contents() 88{ 89 gitdir="$1" 90 (cd ../work.svn && svn_cmd up) && 91 test_cmp file ../work.svn/file && 92 test_cmp auto_updated_file ../work.svn/auto_updated_file 93} 94 95test_expect_success 'check if post-commit hook creates a concurrent commit' ' 96 setup_hook post-commit 1 && 97 ( 98 cd work.svn && 99 cp auto_updated_file au_file_saved && 100 echo 1 >> file && 101 svn_cmd commit -m "changing file" && 102 svn_cmd up && 103 ! test_cmp auto_updated_file au_file_saved 104 ) 105' 106 107test_expect_success 'check if pre-commit hook fails' ' 108 setup_hook pre-commit 2 && 109 ( 110 cd work.svn && 111 echo 2 >> file && 112 svn_cmd commit -m "changing file once again" && 113 echo 3 >> file && 114 ! svn_cmd commit -m "this commit should fail" && 115 svn_cmd revert file 116 ) 117' 118 119test_expect_success 'dcommit error handling' ' 120 setup_hook pre-commit 2 && 121 next_N && git svn clone "$svnrepo" work$N.git && 122 ( 123 cd work$N.git && 124 echo 1 >> file && git commit -am "commit change $N.1" && 125 echo 2 >> file && git commit -am "commit change $N.2" && 126 echo 3 >> file && git commit -am "commit change $N.3" && 127 # should fail to dcommit 2nd and 3rd change 128 # but still should leave the repository in reasonable state 129 test_must_fail git svn dcommit && 130 git update-index --refresh && 131 git show HEAD~2 | grep -q git-svn-id && 132 ! git show HEAD~1 | grep -q git-svn-id && 133 ! git show HEAD | grep -q git-svn-id 134 ) 135' 136 137test_expect_success 'dcommit concurrent change in non-changed file' ' 138 setup_hook post-commit 2 && 139 next_N && git svn clone "$svnrepo" work$N.git && 140 ( 141 cd work$N.git && 142 echo 1 >> file && git commit -am "commit change $N.1" && 143 echo 2 >> file && git commit -am "commit change $N.2" && 144 echo 3 >> file && git commit -am "commit change $N.3" && 145 # should rebase and leave the repository in reasonable state 146 git svn dcommit && 147 git update-index --refresh && 148 check_contents && 149 git show HEAD~3 | grep -q git-svn-id && 150 git show HEAD~2 | grep -q git-svn-id && 151 git show HEAD~1 | grep -q auto-committing && 152 git show HEAD | grep -q git-svn-id 153 ) 154' 155 156# An utility function used in the following test 157delete_first_line() 158{ 159 file="$1" && 160 sed 1d < "$file" > "${file}.tmp" && 161 rm "$file" && 162 mv "${file}.tmp" "$file" 163} 164 165test_expect_success 'dcommit concurrent non-conflicting change' ' 166 setup_hook post-commit 2 && 167 next_N && git svn clone "$svnrepo" work$N.git && 168 ( 169 cd work$N.git && 170 cat file >> auto_updated_file && 171 git commit -am "commit change $N.1" && 172 delete_first_line auto_updated_file && 173 git commit -am "commit change $N.2" && 174 delete_first_line auto_updated_file && 175 git commit -am "commit change $N.3" && 176 # should rebase and leave the repository in reasonable state 177 git svn dcommit && 178 git update-index --refresh && 179 check_contents && 180 git show HEAD~3 | grep -q git-svn-id && 181 git show HEAD~2 | grep -q git-svn-id && 182 git show HEAD~1 | grep -q auto-committing && 183 git show HEAD | grep -q git-svn-id 184 ) 185' 186 187test_expect_success 'dcommit --no-rebase concurrent non-conflicting change' ' 188 setup_hook post-commit 2 && 189 next_N && git svn clone "$svnrepo" work$N.git && 190 ( 191 cd work$N.git && 192 cat file >> auto_updated_file && 193 git commit -am "commit change $N.1" && 194 delete_first_line auto_updated_file && 195 git commit -am "commit change $N.2" && 196 delete_first_line auto_updated_file && 197 git commit -am "commit change $N.3" && 198 # should fail as rebase is needed 199 test_must_fail git svn dcommit --no-rebase && 200 # but should leave HEAD unchanged 201 git update-index --refresh && 202 ! git show HEAD~2 | grep -q git-svn-id && 203 ! git show HEAD~1 | grep -q git-svn-id && 204 ! git show HEAD | grep -q git-svn-id 205 ) 206' 207 208test_expect_success 'dcommit fails on concurrent conflicting change' ' 209 setup_hook post-commit 1 && 210 next_N && git svn clone "$svnrepo" work$N.git && 211 ( 212 cd work$N.git && 213 echo a >> file && 214 git commit -am "commit change $N.1" && 215 echo b >> auto_updated_file && 216 git commit -am "commit change $N.2" && 217 echo c >> auto_updated_file && 218 git commit -am "commit change $N.3" && 219 test_must_fail git svn dcommit && # rebase should fail 220 test_must_fail git update-index --refresh 221 ) 222' 223 224test_done