1#!/bin/sh
2
3test_description='git p4 rcs keywords'
4
5. ./lib-git-p4.sh
6
7test_expect_success 'start p4d' '
8 start_p4d
9'
10
11#
12# Make one file with keyword lines at the top, and
13# enough plain text to be able to test modifications
14# far away from the keywords.
15#
16test_expect_success 'init depot' '
17 (
18 cd "$cli" &&
19 cat <<-\EOF >filek &&
20 $Id$
21 /* $Revision$ */
22 # $Change$
23 line4
24 line5
25 line6
26 line7
27 line8
28 EOF
29 cp filek fileko &&
30 sed -i "s/Revision/Revision: do not scrub me/" fileko
31 cp fileko file_text &&
32 sed -i "s/Id/Id: do not scrub me/" file_text
33 p4 add -t text+k filek &&
34 p4 submit -d "filek" &&
35 p4 add -t text+ko fileko &&
36 p4 submit -d "fileko" &&
37 p4 add -t text file_text &&
38 p4 submit -d "file_text"
39 )
40'
41
42#
43# Generate these in a function to make it easy to use single quote marks.
44#
45write_scrub_scripts () {
46 cat >"$TRASH_DIRECTORY/scrub_k.py" <<-\EOF &&
47 import re, sys
48 sys.stdout.write(re.sub(r'(?i)\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$]*\$', r'$\1$', sys.stdin.read()))
49 EOF
50 cat >"$TRASH_DIRECTORY/scrub_ko.py" <<-\EOF
51 import re, sys
52 sys.stdout.write(re.sub(r'(?i)\$(Id|Header):[^$]*\$', r'$\1$', sys.stdin.read()))
53 EOF
54}
55
56test_expect_success 'scrub scripts' '
57 write_scrub_scripts
58'
59
60#
61# Compare $cli/file to its scrubbed version, should be different.
62# Compare scrubbed $cli/file to $git/file, should be same.
63#
64scrub_k_check () {
65 file="$1" &&
66 scrub="$TRASH_DIRECTORY/$file" &&
67 "$PYTHON_PATH" "$TRASH_DIRECTORY/scrub_k.py" <"$git/$file" >"$scrub" &&
68 ! test_cmp "$cli/$file" "$scrub" &&
69 test_cmp "$git/$file" "$scrub" &&
70 rm "$scrub"
71}
72scrub_ko_check () {
73 file="$1" &&
74 scrub="$TRASH_DIRECTORY/$file" &&
75 "$PYTHON_PATH" "$TRASH_DIRECTORY/scrub_ko.py" <"$git/$file" >"$scrub" &&
76 ! test_cmp "$cli/$file" "$scrub" &&
77 test_cmp "$git/$file" "$scrub" &&
78 rm "$scrub"
79}
80
81#
82# Modify far away from keywords. If no RCS lines show up
83# in the diff, there is no conflict.
84#
85test_expect_success 'edit far away from RCS lines' '
86 test_when_finished cleanup_git &&
87 git p4 clone --dest="$git" //depot &&
88 (
89 cd "$git" &&
90 git config git-p4.skipSubmitEdit true &&
91 sed -i "s/^line7/line7 edit/" filek &&
92 git commit -m "filek line7 edit" filek &&
93 git p4 submit &&
94 scrub_k_check filek
95 )
96'
97
98#
99# Modify near the keywords. This will require RCS scrubbing.
100#
101test_expect_success 'edit near RCS lines' '
102 test_when_finished cleanup_git &&
103 git p4 clone --dest="$git" //depot &&
104 (
105 cd "$git" &&
106 git config git-p4.skipSubmitEdit true &&
107 git config git-p4.attemptRCSCleanup true &&
108 sed -i "s/^line4/line4 edit/" filek &&
109 git commit -m "filek line4 edit" filek &&
110 git p4 submit &&
111 scrub_k_check filek
112 )
113'
114
115#
116# Modify the keywords themselves. This also will require RCS scrubbing.
117#
118test_expect_success 'edit keyword lines' '
119 test_when_finished cleanup_git &&
120 git p4 clone --dest="$git" //depot &&
121 (
122 cd "$git" &&
123 git config git-p4.skipSubmitEdit true &&
124 git config git-p4.attemptRCSCleanup true &&
125 sed -i "/Revision/d" filek &&
126 git commit -m "filek remove Revision line" filek &&
127 git p4 submit &&
128 scrub_k_check filek
129 )
130'
131
132#
133# Scrubbing text+ko files should not alter all keywords, just Id, Header.
134#
135test_expect_success 'scrub ko files differently' '
136 test_when_finished cleanup_git &&
137 git p4 clone --dest="$git" //depot &&
138 (
139 cd "$git" &&
140 git config git-p4.skipSubmitEdit true &&
141 git config git-p4.attemptRCSCleanup true &&
142 sed -i "s/^line4/line4 edit/" fileko &&
143 git commit -m "fileko line4 edit" fileko &&
144 git p4 submit &&
145 scrub_ko_check fileko &&
146 ! scrub_k_check fileko
147 )
148'
149
150# hack; git p4 submit should do it on its own
151test_expect_success 'cleanup after failure' '
152 (
153 cd "$cli" &&
154 p4 revert ...
155 )
156'
157
158# perl $File:: bug check
159test_expect_success 'ktext expansion should not expand multi-line $File::' '
160 (
161 cd "$cli" &&
162 cat >lv.pm <<-\EOF
163 my $wanted = sub { my $f = $File::Find::name;
164 if ( -f && $f =~ /foo/ ) {
165 EOF
166 p4 add -t ktext lv.pm &&
167 p4 submit -d "lv.pm"
168 ) &&
169 test_when_finished cleanup_git &&
170 git p4 clone --dest="$git" //depot &&
171 (
172 cd "$git" &&
173 test_cmp "$cli/lv.pm" lv.pm
174 )
175'
176
177#
178# Do not scrub anything but +k or +ko files. Sneak a change into
179# the cli file so that submit will get a conflict. Make sure that
180# scrubbing doesn't make a mess of things.
181#
182# Assumes that git-p4 exits leaving the p4 file open, with the
183# conflict-generating patch unapplied.
184#
185# This might happen only if the git repo is behind the p4 repo at
186# submit time, and there is a conflict.
187#
188test_expect_success 'do not scrub plain text' '
189 test_when_finished cleanup_git &&
190 git p4 clone --dest="$git" //depot &&
191 (
192 cd "$git" &&
193 git config git-p4.skipSubmitEdit true &&
194 git config git-p4.attemptRCSCleanup true &&
195 sed -i "s/^line4/line4 edit/" file_text &&
196 git commit -m "file_text line4 edit" file_text &&
197 (
198 cd "$cli" &&
199 p4 open file_text &&
200 sed -i "s/^line5/line5 p4 edit/" file_text &&
201 p4 submit -d "file5 p4 edit"
202 ) &&
203 ! git p4 submit &&
204 (
205 # exepct something like:
206 # file_text - file(s) not opened on this client
207 # but not copious diff output
208 cd "$cli" &&
209 p4 diff file_text >wc &&
210 test_line_count = 1 wc
211 )
212 )
213'
214
215# hack; git p4 submit should do it on its own
216test_expect_success 'cleanup after failure 2' '
217 (
218 cd "$cli" &&
219 p4 revert ...
220 )
221'
222
223create_kw_file () {
224 cat <<\EOF >"$1"
225/* A file
226 Id: $Id$
227 Revision: $Revision$
228 File: $File$
229 */
230int main(int argc, const char **argv) {
231 return 0;
232}
233EOF
234}
235
236test_expect_success 'add kwfile' '
237 (
238 cd "$cli" &&
239 echo file1 >file1 &&
240 p4 add file1 &&
241 p4 submit -d "file 1" &&
242 create_kw_file kwfile1.c &&
243 p4 add kwfile1.c &&
244 p4 submit -d "Add rcw kw file" kwfile1.c
245 )
246'
247
248p4_append_to_file () {
249 f="$1" &&
250 p4 edit -t ktext "$f" &&
251 echo "/* $(date) */" >>"$f" &&
252 p4 submit -d "appending a line in p4"
253}
254
255# Create some files with RCS keywords. If they get modified
256# elsewhere then the version number gets bumped which then
257# results in a merge conflict if we touch the RCS kw lines,
258# even though the change itself would otherwise apply cleanly.
259test_expect_success 'cope with rcs keyword expansion damage' '
260 test_when_finished cleanup_git &&
261 git p4 clone --dest="$git" //depot &&
262 (
263 cd "$git" &&
264 git config git-p4.skipSubmitEdit true &&
265 git config git-p4.attemptRCSCleanup true &&
266 (cd "$cli" && p4_append_to_file kwfile1.c) &&
267 old_lines=$(wc -l <kwfile1.c) &&
268 "$PERL_PATH" -n -i -e "print unless m/Revision:/" kwfile1.c &&
269 new_lines=$(wc -l <kwfile1.c) &&
270 test $new_lines = $(($old_lines - 1)) &&
271
272 git add kwfile1.c &&
273 git commit -m "Zap an RCS kw line" &&
274 git p4 submit &&
275 git p4 rebase &&
276 git diff p4/master &&
277 git p4 commit &&
278 echo "try modifying in both" &&
279 cd "$cli" &&
280 p4 edit kwfile1.c &&
281 echo "line from p4" >>kwfile1.c &&
282 p4 submit -d "add a line in p4" kwfile1.c &&
283 cd "$git" &&
284 echo "line from git at the top" | cat - kwfile1.c >kwfile1.c.new &&
285 mv kwfile1.c.new kwfile1.c &&
286 git commit -m "Add line in git at the top" kwfile1.c &&
287 git p4 rebase &&
288 git p4 submit
289 )
290'
291
292test_expect_success 'cope with rcs keyword file deletion' '
293 test_when_finished cleanup_git &&
294 (
295 cd "$cli" &&
296 echo "\$Revision\$" >kwdelfile.c &&
297 p4 add -t ktext kwdelfile.c &&
298 p4 submit -d "Add file to be deleted" &&
299 cat kwdelfile.c &&
300 grep 1 kwdelfile.c
301 ) &&
302 git p4 clone --dest="$git" //depot &&
303 (
304 cd "$git" &&
305 grep Revision kwdelfile.c &&
306 git rm -f kwdelfile.c &&
307 git commit -m "Delete a file containing RCS keywords" &&
308 git config git-p4.skipSubmitEdit true &&
309 git config git-p4.attemptRCSCleanup true &&
310 git p4 submit
311 ) &&
312 (
313 cd "$cli" &&
314 p4 sync &&
315 ! test -f kwdelfile.c
316 )
317'
318
319# If you add keywords in git of the form $Header$ then everything should
320# work fine without any special handling.
321test_expect_success 'Add keywords in git which match the default p4 values' '
322 test_when_finished cleanup_git &&
323 git p4 clone --dest="$git" //depot &&
324 (
325 cd "$git" &&
326 echo "NewKW: \$Revision\$" >>kwfile1.c &&
327 git add kwfile1.c &&
328 git commit -m "Adding RCS keywords in git" &&
329 git config git-p4.skipSubmitEdit true &&
330 git config git-p4.attemptRCSCleanup true &&
331 git p4 submit
332 ) &&
333 (
334 cd "$cli" &&
335 p4 sync &&
336 test -f kwfile1.c &&
337 grep "NewKW.*Revision.*[0-9]" kwfile1.c
338
339 )
340'
341
342# If you add keywords in git of the form $Header:#1$ then things will fail
343# unless git-p4 takes steps to scrub the *git* commit.
344#
345test_expect_failure 'Add keywords in git which do not match the default p4 values' '
346 test_when_finished cleanup_git &&
347 git p4 clone --dest="$git" //depot &&
348 (
349 cd "$git" &&
350 echo "NewKW2: \$Revision:1\$" >>kwfile1.c &&
351 git add kwfile1.c &&
352 git commit -m "Adding RCS keywords in git" &&
353 git config git-p4.skipSubmitEdit true &&
354 git config git-p4.attemptRCSCleanup true &&
355 git p4 submit
356 ) &&
357 (
358 cd "$cli" &&
359 p4 sync &&
360 grep "NewKW2.*Revision.*[0-9]" kwfile1.c
361
362 )
363'
364
365# Check that the existing merge conflict handling still works.
366# Modify kwfile1.c in git, and delete in p4. We should be able
367# to skip the git commit.
368#
369test_expect_success 'merge conflict handling still works' '
370 test_when_finished cleanup_git &&
371 (
372 cd "$cli" &&
373 echo "Hello:\$Id\$" >merge2.c &&
374 echo "World" >>merge2.c &&
375 p4 add -t ktext merge2.c &&
376 p4 submit -d "add merge test file"
377 ) &&
378 git p4 clone --dest="$git" //depot &&
379 (
380 cd "$git" &&
381 sed -e "/Hello/d" merge2.c >merge2.c.tmp &&
382 mv merge2.c.tmp merge2.c &&
383 git add merge2.c &&
384 git commit -m "Modifying merge2.c"
385 ) &&
386 (
387 cd "$cli" &&
388 p4 delete merge2.c &&
389 p4 submit -d "remove merge test file"
390 ) &&
391 (
392 cd "$git" &&
393 test -f merge2.c &&
394 git config git-p4.skipSubmitEdit true &&
395 git config git-p4.attemptRCSCleanup true &&
396 !(echo "s" | git p4 submit) &&
397 git rebase --skip &&
398 ! test -f merge2.c
399 )
400'
401
402
403test_expect_success 'kill p4d' '
404 kill_p4d
405'
406
407test_done