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