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