t / t9810-git-p4-rcs.shon commit git p4: RCS expansion should not span newlines (6b2bf41)
   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