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