t/t0211-trace2-perf.sh: fix typo patern -> pattern
[alt-git.git] / t / t9164-git-svn-dcommit-concurrent.sh
blob1465156072e32a75fb759784e65f9f7e2ca4c84a
1 #!/bin/sh
3 # Copyright (c) 2012 Robert Luberda
6 test_description='concurrent git svn dcommit'
8 TEST_FAILS_SANITIZE_LEAK=true
9 . ./lib-git-svn.sh
13 test_expect_success 'setup svn repository' '
14 svn_cmd checkout "$svnrepo" work.svn &&
16 cd work.svn &&
17 echo >file && echo > auto_updated_file &&
18 svn_cmd add file auto_updated_file &&
19 svn_cmd commit -m "initial commit"
20 ) &&
21 svn_cmd checkout "$svnrepo" work-auto-commits.svn
23 N=0
24 next_N()
26 N=$(( $N + 1 ))
29 # Setup SVN repository hooks to emulate SVN failures or concurrent commits
30 # The function adds
31 # either pre-commit hook, which causes SVN commit given in second argument
32 # to fail
33 # or post-commit hook, which creates a new commit (a new line added to
34 # auto_updated_file) after given SVN commit
35 # The first argument contains a type of the hook
36 # The second argument contains a number (not SVN revision) of commit
37 # the hook should be applied for (each time the hook is run, the given
38 # number is decreased by one until it gets 0, in which case the hook
39 # will execute its real action)
40 setup_hook()
42 hook_type="$1" # "pre-commit" or "post-commit"
43 skip_revs="$2"
44 [ "$hook_type" = "pre-commit" ] ||
45 [ "$hook_type" = "post-commit" ] ||
46 { echo "ERROR: invalid argument ($hook_type)" \
47 "passed to setup_hook" >&2 ; return 1; }
48 echo "cnt=$skip_revs" > "$hook_type-counter"
49 rm -f "$rawsvnrepo/hooks/"*-commit # drop previous hooks
50 hook="$rawsvnrepo/hooks/$hook_type"
51 cat > "$hook" <<- 'EOF1'
52 #!/bin/sh
53 set -e
54 cd "$1/.." # "$1" is repository location
55 exec >> svn-hook.log 2>&1
56 hook="$(basename "$0")"
57 echo "*** Executing $hook $@"
58 set -x
59 . ./$hook-counter
60 cnt="$(($cnt - 1))"
61 echo "cnt=$cnt" > ./$hook-counter
62 [ "$cnt" = "0" ] || exit 0
63 EOF1
64 if [ "$hook_type" = "pre-commit" ]; then
65 echo "echo 'commit disallowed' >&2; exit 1" >>"$hook"
66 else
67 echo "PATH=\"$PATH\"; export PATH" >>"$hook"
68 echo "svnconf=\"$svnconf\"" >>"$hook"
69 cat >>"$hook" <<- 'EOF2'
70 cd work-auto-commits.svn
71 svn up --config-dir "$svnconf"
72 echo "$$" >> auto_updated_file
73 svn commit --config-dir "$svnconf" \
74 -m "auto-committing concurrent change"
75 exit 0
76 EOF2
78 chmod 755 "$hook"
81 check_contents()
83 gitdir="$1"
84 (cd ../work.svn && svn_cmd up) &&
85 test_cmp file ../work.svn/file &&
86 test_cmp auto_updated_file ../work.svn/auto_updated_file
89 test_expect_success 'check if post-commit hook creates a concurrent commit' '
90 setup_hook post-commit 1 &&
92 cd work.svn &&
93 cp auto_updated_file au_file_saved &&
94 echo 1 >> file &&
95 svn_cmd commit -m "changing file" &&
96 svn_cmd up &&
97 ! test_cmp auto_updated_file au_file_saved
101 test_expect_success 'check if pre-commit hook fails' '
102 setup_hook pre-commit 2 &&
104 cd work.svn &&
105 echo 2 >> file &&
106 svn_cmd commit -m "changing file once again" &&
107 echo 3 >> file &&
108 ! svn_cmd commit -m "this commit should fail" &&
109 svn_cmd revert file
113 test_expect_success 'dcommit error handling' '
114 setup_hook pre-commit 2 &&
115 next_N && git svn clone "$svnrepo" work$N.git &&
117 cd work$N.git &&
118 echo 1 >> file && git commit -am "commit change $N.1" &&
119 echo 2 >> file && git commit -am "commit change $N.2" &&
120 echo 3 >> file && git commit -am "commit change $N.3" &&
121 # should fail to dcommit 2nd and 3rd change
122 # but still should leave the repository in reasonable state
123 test_must_fail git svn dcommit &&
124 git update-index --refresh &&
125 git show HEAD~2 | grep -q git-svn-id &&
126 ! git show HEAD~1 | grep -q git-svn-id &&
127 ! git show HEAD | grep -q git-svn-id
131 test_expect_success 'dcommit concurrent change in non-changed file' '
132 setup_hook post-commit 2 &&
133 next_N && git svn clone "$svnrepo" work$N.git &&
135 cd work$N.git &&
136 echo 1 >> file && git commit -am "commit change $N.1" &&
137 echo 2 >> file && git commit -am "commit change $N.2" &&
138 echo 3 >> file && git commit -am "commit change $N.3" &&
139 # should rebase and leave the repository in reasonable state
140 git svn dcommit &&
141 git update-index --refresh &&
142 check_contents &&
143 git show HEAD~3 | grep -q git-svn-id &&
144 git show HEAD~2 | grep -q git-svn-id &&
145 git show HEAD~1 | grep -q auto-committing &&
146 git show HEAD | grep -q git-svn-id
150 # An utility function used in the following test
151 delete_first_line()
153 file="$1" &&
154 sed 1d < "$file" > "${file}.tmp" &&
155 rm "$file" &&
156 mv "${file}.tmp" "$file"
159 test_expect_success 'dcommit concurrent non-conflicting change' '
160 setup_hook post-commit 2 &&
161 next_N && git svn clone "$svnrepo" work$N.git &&
163 cd work$N.git &&
164 cat file >> auto_updated_file &&
165 git commit -am "commit change $N.1" &&
166 delete_first_line auto_updated_file &&
167 git commit -am "commit change $N.2" &&
168 delete_first_line auto_updated_file &&
169 git commit -am "commit change $N.3" &&
170 # should rebase and leave the repository in reasonable state
171 git svn dcommit &&
172 git update-index --refresh &&
173 check_contents &&
174 git show HEAD~3 | grep -q git-svn-id &&
175 git show HEAD~2 | grep -q git-svn-id &&
176 git show HEAD~1 | grep -q auto-committing &&
177 git show HEAD | grep -q git-svn-id
181 test_expect_success 'dcommit --no-rebase concurrent non-conflicting change' '
182 setup_hook post-commit 2 &&
183 next_N && git svn clone "$svnrepo" work$N.git &&
185 cd work$N.git &&
186 cat file >> auto_updated_file &&
187 git commit -am "commit change $N.1" &&
188 delete_first_line auto_updated_file &&
189 git commit -am "commit change $N.2" &&
190 delete_first_line auto_updated_file &&
191 git commit -am "commit change $N.3" &&
192 # should fail as rebase is needed
193 test_must_fail git svn dcommit --no-rebase &&
194 # but should leave HEAD unchanged
195 git update-index --refresh &&
196 ! git show HEAD~2 | grep -q git-svn-id &&
197 ! git show HEAD~1 | grep -q git-svn-id &&
198 ! git show HEAD | grep -q git-svn-id
202 test_expect_success 'dcommit fails on concurrent conflicting change' '
203 setup_hook post-commit 1 &&
204 next_N && git svn clone "$svnrepo" work$N.git &&
206 cd work$N.git &&
207 echo a >> file &&
208 git commit -am "commit change $N.1" &&
209 echo b >> auto_updated_file &&
210 git commit -am "commit change $N.2" &&
211 echo c >> auto_updated_file &&
212 git commit -am "commit change $N.3" &&
213 test_must_fail git svn dcommit && # rebase should fail
214 test_must_fail git update-index --refresh
218 test_done