04ee20e642387e75e031f4c68ff126c06220c620
   1#!/bin/sh
   2
   3test_description='git-p4 tests'
   4
   5. ./lib-git-p4.sh
   6
   7test_expect_success 'start p4d' '
   8        start_p4d
   9'
  10
  11test_expect_success 'add p4 files' '
  12        (
  13                cd "$cli" &&
  14                echo file1 >file1 &&
  15                p4 add file1 &&
  16                p4 submit -d "file1" &&
  17                echo file2 >file2 &&
  18                p4 add file2 &&
  19                p4 submit -d "file2"
  20        )
  21'
  22
  23test_expect_success 'basic git-p4 clone' '
  24        "$GITP4" clone --dest="$git" //depot &&
  25        test_when_finished cleanup_git &&
  26        (
  27                cd "$git" &&
  28                git log --oneline >lines &&
  29                test_line_count = 1 lines
  30        )
  31'
  32
  33test_expect_success 'git-p4 clone @all' '
  34        "$GITP4" clone --dest="$git" //depot@all &&
  35        test_when_finished cleanup_git &&
  36        (
  37                cd "$git" &&
  38                git log --oneline >lines &&
  39                test_line_count = 2 lines
  40        )
  41'
  42
  43test_expect_success 'git-p4 sync uninitialized repo' '
  44        test_create_repo "$git" &&
  45        test_when_finished cleanup_git &&
  46        (
  47                cd "$git" &&
  48                test_must_fail "$GITP4" sync
  49        )
  50'
  51
  52#
  53# Create a git repo by hand.  Add a commit so that HEAD is valid.
  54# Test imports a new p4 repository into a new git branch.
  55#
  56test_expect_success 'git-p4 sync new branch' '
  57        test_create_repo "$git" &&
  58        test_when_finished cleanup_git &&
  59        (
  60                cd "$git" &&
  61                test_commit head &&
  62                "$GITP4" sync --branch=refs/remotes/p4/depot //depot@all &&
  63                git log --oneline p4/depot >lines &&
  64                test_line_count = 2 lines
  65        )
  66'
  67
  68test_expect_success 'clone two dirs' '
  69        (
  70                cd "$cli" &&
  71                mkdir sub1 sub2 &&
  72                echo sub1/f1 >sub1/f1 &&
  73                echo sub2/f2 >sub2/f2 &&
  74                p4 add sub1/f1 &&
  75                p4 submit -d "sub1/f1" &&
  76                p4 add sub2/f2 &&
  77                p4 submit -d "sub2/f2"
  78        ) &&
  79        "$GITP4" clone --dest="$git" //depot/sub1 //depot/sub2 &&
  80        test_when_finished cleanup_git &&
  81        (
  82                cd "$git" &&
  83                git ls-files >lines &&
  84                test_line_count = 2 lines &&
  85                git log --oneline p4/master >lines &&
  86                test_line_count = 1 lines
  87        )
  88'
  89
  90test_expect_success 'clone two dirs, @all' '
  91        (
  92                cd "$cli" &&
  93                echo sub1/f3 >sub1/f3 &&
  94                p4 add sub1/f3 &&
  95                p4 submit -d "sub1/f3"
  96        ) &&
  97        "$GITP4" clone --dest="$git" //depot/sub1@all //depot/sub2@all &&
  98        test_when_finished cleanup_git &&
  99        (
 100                cd "$git" &&
 101                git ls-files >lines &&
 102                test_line_count = 3 lines &&
 103                git log --oneline p4/master >lines &&
 104                test_line_count = 3 lines
 105        )
 106'
 107
 108test_expect_success 'clone two dirs, @all, conflicting files' '
 109        (
 110                cd "$cli" &&
 111                echo sub2/f3 >sub2/f3 &&
 112                p4 add sub2/f3 &&
 113                p4 submit -d "sub2/f3"
 114        ) &&
 115        "$GITP4" clone --dest="$git" //depot/sub1@all //depot/sub2@all &&
 116        test_when_finished cleanup_git &&
 117        (
 118                cd "$git" &&
 119                git ls-files >lines &&
 120                test_line_count = 3 lines &&
 121                git log --oneline p4/master >lines &&
 122                test_line_count = 4 lines &&
 123                echo sub2/f3 >expected &&
 124                test_cmp expected f3
 125        )
 126'
 127
 128test_expect_success 'exit when p4 fails to produce marshaled output' '
 129        badp4dir="$TRASH_DIRECTORY/badp4dir" &&
 130        mkdir "$badp4dir" &&
 131        test_when_finished "rm \"$badp4dir/p4\" && rmdir \"$badp4dir\"" &&
 132        cat >"$badp4dir"/p4 <<-EOF &&
 133        #!$SHELL_PATH
 134        exit 1
 135        EOF
 136        chmod 755 "$badp4dir"/p4 &&
 137        PATH="$badp4dir:$PATH" "$GITP4" clone --dest="$git" //depot >errs 2>&1 ; retval=$? &&
 138        test $retval -eq 1 &&
 139        test_must_fail grep -q Traceback errs
 140'
 141
 142test_expect_success 'add p4 files with wildcards in the names' '
 143        (
 144                cd "$cli" &&
 145                echo file-wild-hash >file-wild#hash &&
 146                echo file-wild-star >file-wild\*star &&
 147                echo file-wild-at >file-wild@at &&
 148                echo file-wild-percent >file-wild%percent &&
 149                p4 add -f file-wild* &&
 150                p4 submit -d "file wildcards"
 151        )
 152'
 153
 154test_expect_success 'wildcard files git-p4 clone' '
 155        "$GITP4" clone --dest="$git" //depot &&
 156        test_when_finished cleanup_git &&
 157        (
 158                cd "$git" &&
 159                test -f file-wild#hash &&
 160                test -f file-wild\*star &&
 161                test -f file-wild@at &&
 162                test -f file-wild%percent
 163        )
 164'
 165
 166test_expect_success 'clone bare' '
 167        "$GITP4" clone --dest="$git" --bare //depot &&
 168        test_when_finished cleanup_git &&
 169        (
 170                cd "$git" &&
 171                test ! -d .git &&
 172                bare=`git config --get core.bare` &&
 173                test "$bare" = true
 174        )
 175'
 176
 177p4_add_user() {
 178        name=$1 fullname=$2 &&
 179        p4 user -f -i <<-EOF &&
 180        User: $name
 181        Email: $name@localhost
 182        FullName: $fullname
 183        EOF
 184        p4 passwd -P secret $name
 185}
 186
 187p4_grant_admin() {
 188        name=$1 &&
 189        {
 190                p4 protect -o &&
 191                echo "    admin user $name * //depot/..."
 192        } | p4 protect -i
 193}
 194
 195p4_check_commit_author() {
 196        file=$1 user=$2 &&
 197        p4 changes -m 1 //depot/$file | grep -q $user
 198}
 199
 200make_change_by_user() {
 201        file=$1 name=$2 email=$3 &&
 202        echo "username: a change by $name" >>"$file" &&
 203        git add "$file" &&
 204        git commit --author "$name <$email>" -m "a change by $name"
 205}
 206
 207# Test username support, submitting as user 'alice'
 208test_expect_success 'preserve users' '
 209        p4_add_user alice Alice &&
 210        p4_add_user bob Bob &&
 211        p4_grant_admin alice &&
 212        "$GITP4" clone --dest="$git" //depot &&
 213        test_when_finished cleanup_git &&
 214        (
 215                cd "$git" &&
 216                echo "username: a change by alice" >>file1 &&
 217                echo "username: a change by bob" >>file2 &&
 218                git commit --author "Alice <alice@localhost>" -m "a change by alice" file1 &&
 219                git commit --author "Bob <bob@localhost>" -m "a change by bob" file2 &&
 220                git config git-p4.skipSubmitEditCheck true &&
 221                P4EDITOR=touch P4USER=alice P4PASSWD=secret "$GITP4" commit --preserve-user &&
 222                p4_check_commit_author file1 alice &&
 223                p4_check_commit_author file2 bob
 224        )
 225'
 226
 227# Test username support, submitting as bob, who lacks admin rights. Should
 228# not submit change to p4 (git diff should show deltas).
 229test_expect_success 'refuse to preserve users without perms' '
 230        "$GITP4" clone --dest="$git" //depot &&
 231        test_when_finished cleanup_git &&
 232        (
 233                cd "$git" &&
 234                git config git-p4.skipSubmitEditCheck true &&
 235                echo "username-noperms: a change by alice" >>file1 &&
 236                git commit --author "Alice <alice@localhost>" -m "perms: a change by alice" file1 &&
 237                P4EDITOR=touch P4USER=bob P4PASSWD=secret test_must_fail "$GITP4" commit --preserve-user &&
 238                test_must_fail git diff --exit-code HEAD..p4/master
 239        )
 240'
 241
 242# What happens with unknown author? Without allowMissingP4Users it should fail.
 243test_expect_success 'preserve user where author is unknown to p4' '
 244        "$GITP4" clone --dest="$git" //depot &&
 245        test_when_finished cleanup_git &&
 246        (
 247                cd "$git" &&
 248                git config git-p4.skipSubmitEditCheck true &&
 249                echo "username-bob: a change by bob" >>file1 &&
 250                git commit --author "Bob <bob@localhost>" -m "preserve: a change by bob" file1 &&
 251                echo "username-unknown: a change by charlie" >>file1 &&
 252                git commit --author "Charlie <charlie@localhost>" -m "preserve: a change by charlie" file1 &&
 253                P4EDITOR=touch P4USER=alice P4PASSWD=secret test_must_fail "$GITP4" commit --preserve-user &&
 254                test_must_fail git diff --exit-code HEAD..p4/master &&
 255
 256                echo "$0: repeat with allowMissingP4Users enabled" &&
 257                git config git-p4.allowMissingP4Users true &&
 258                git config git-p4.preserveUser true &&
 259                P4EDITOR=touch P4USER=alice P4PASSWD=secret "$GITP4" commit &&
 260                git diff --exit-code HEAD..p4/master &&
 261                p4_check_commit_author file1 alice
 262        )
 263'
 264
 265# If we're *not* using --preserve-user, git-p4 should warn if we're submitting
 266# changes that are not all ours.
 267# Test: user in p4 and user unknown to p4.
 268# Test: warning disabled and user is the same.
 269test_expect_success 'not preserving user with mixed authorship' '
 270        "$GITP4" clone --dest="$git" //depot &&
 271        test_when_finished cleanup_git &&
 272        (
 273                cd "$git" &&
 274                git config git-p4.skipSubmitEditCheck true &&
 275                p4_add_user derek Derek &&
 276
 277                make_change_by_user usernamefile3 Derek derek@localhost &&
 278                P4EDITOR=cat P4USER=alice P4PASSWD=secret "$GITP4" commit |\
 279                grep "git author derek@localhost does not match" &&
 280
 281                make_change_by_user usernamefile3 Charlie charlie@localhost &&
 282                P4EDITOR=cat P4USER=alice P4PASSWD=secret "$GITP4" commit |\
 283                grep "git author charlie@localhost does not match" &&
 284
 285                make_change_by_user usernamefile3 alice alice@localhost &&
 286                P4EDITOR=cat P4USER=alice P4PASSWD=secret "$GITP4" |\
 287                test_must_fail grep "git author.*does not match" &&
 288
 289                git config git-p4.skipUserNameCheck true &&
 290                make_change_by_user usernamefile3 Charlie charlie@localhost &&
 291                P4EDITOR=cat P4USER=alice P4PASSWD=secret "$GITP4" commit |\
 292                test_must_fail grep "git author.*does not match" &&
 293
 294                p4_check_commit_author usernamefile3 alice
 295        )
 296'
 297
 298marshal_dump() {
 299        what=$1
 300        "$PYTHON_PATH" -c 'import marshal, sys; d = marshal.load(sys.stdin); print d["'$what'"]'
 301}
 302
 303# Sleep a bit so that the top-most p4 change did not happen "now".  Then
 304# import the repo and make sure that the initial import has the same time
 305# as the top-most change.
 306test_expect_success 'initial import time from top change time' '
 307        p4change=$(p4 -G changes -m 1 //depot/... | marshal_dump change) &&
 308        p4time=$(p4 -G changes -m 1 //depot/... | marshal_dump time) &&
 309        sleep 3 &&
 310        "$GITP4" clone --dest="$git" //depot &&
 311        test_when_finished cleanup_git &&
 312        (
 313                cd "$git" &&
 314                gittime=$(git show -s --raw --pretty=format:%at HEAD) &&
 315                echo $p4time $gittime &&
 316                test $p4time = $gittime
 317        )
 318'
 319
 320# Rename a file and confirm that rename is not detected in P4.
 321# Rename the new file again with detectRenames option enabled and confirm that
 322# this is detected in P4.
 323# Rename the new file again adding an extra line, configure a big threshold in
 324# detectRenames and confirm that rename is not detected in P4.
 325# Repeat, this time with a smaller threshold and confirm that the rename is
 326# detected in P4.
 327test_expect_success 'detect renames' '
 328        "$GITP4" clone --dest="$git" //depot@all &&
 329        test_when_finished cleanup_git &&
 330        (
 331                cd "$git" &&
 332                git config git-p4.skipSubmitEditCheck true &&
 333
 334                git mv file1 file4 &&
 335                git commit -a -m "Rename file1 to file4" &&
 336                git diff-tree -r -M HEAD &&
 337                "$GITP4" submit &&
 338                p4 filelog //depot/file4 &&
 339                p4 filelog //depot/file4 | test_must_fail grep -q "branch from" &&
 340
 341                git mv file4 file5 &&
 342                git commit -a -m "Rename file4 to file5" &&
 343                git diff-tree -r -M HEAD &&
 344                git config git-p4.detectRenames true &&
 345                "$GITP4" submit &&
 346                p4 filelog //depot/file5 &&
 347                p4 filelog //depot/file5 | grep -q "branch from //depot/file4" &&
 348
 349                git mv file5 file6 &&
 350                echo update >>file6 &&
 351                git add file6 &&
 352                git commit -a -m "Rename file5 to file6 with changes" &&
 353                git diff-tree -r -M HEAD &&
 354                level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
 355                test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
 356                git config git-p4.detectRenames $(($level + 2)) &&
 357                "$GITP4" submit &&
 358                p4 filelog //depot/file6 &&
 359                p4 filelog //depot/file6 | test_must_fail grep -q "branch from" &&
 360
 361                git mv file6 file7 &&
 362                echo update >>file7 &&
 363                git add file7 &&
 364                git commit -a -m "Rename file6 to file7 with changes" &&
 365                git diff-tree -r -M HEAD &&
 366                level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
 367                test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
 368                git config git-p4.detectRenames $(($level - 2)) &&
 369                "$GITP4" submit &&
 370                p4 filelog //depot/file7 &&
 371                p4 filelog //depot/file7 | grep -q "branch from //depot/file6"
 372        )
 373'
 374
 375# Copy a file and confirm that copy is not detected in P4.
 376# Copy a file with detectCopies option enabled and confirm that copy is not
 377# detected in P4.
 378# Modify and copy a file with detectCopies option enabled and confirm that copy
 379# is detected in P4.
 380# Copy a file with detectCopies and detectCopiesHarder options enabled and
 381# confirm that copy is detected in P4.
 382# Modify and copy a file, configure a bigger threshold in detectCopies and
 383# confirm that copy is not detected in P4.
 384# Modify and copy a file, configure a smaller threshold in detectCopies and
 385# confirm that copy is detected in P4.
 386test_expect_success 'detect copies' '
 387        "$GITP4" clone --dest="$git" //depot@all &&
 388        test_when_finished cleanup_git &&
 389        (
 390                cd "$git" &&
 391                git config git-p4.skipSubmitEditCheck true &&
 392
 393                cp file2 file8 &&
 394                git add file8 &&
 395                git commit -a -m "Copy file2 to file8" &&
 396                git diff-tree -r -C HEAD &&
 397                "$GITP4" submit &&
 398                p4 filelog //depot/file8 &&
 399                p4 filelog //depot/file8 | test_must_fail grep -q "branch from" &&
 400
 401                cp file2 file9 &&
 402                git add file9 &&
 403                git commit -a -m "Copy file2 to file9" &&
 404                git diff-tree -r -C HEAD &&
 405                git config git-p4.detectCopies true &&
 406                "$GITP4" submit &&
 407                p4 filelog //depot/file9 &&
 408                p4 filelog //depot/file9 | test_must_fail grep -q "branch from" &&
 409
 410                echo "file2" >>file2 &&
 411                cp file2 file10 &&
 412                git add file2 file10 &&
 413                git commit -a -m "Modify and copy file2 to file10" &&
 414                git diff-tree -r -C HEAD &&
 415                "$GITP4" submit &&
 416                p4 filelog //depot/file10 &&
 417                p4 filelog //depot/file10 | grep -q "branch from //depot/file" &&
 418
 419                cp file2 file11 &&
 420                git add file11 &&
 421                git commit -a -m "Copy file2 to file11" &&
 422                git diff-tree -r -C --find-copies-harder HEAD &&
 423                src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
 424                test "$src" = file10 &&
 425                git config git-p4.detectCopiesHarder true &&
 426                "$GITP4" submit &&
 427                p4 filelog //depot/file11 &&
 428                p4 filelog //depot/file11 | grep -q "branch from //depot/file" &&
 429
 430                cp file2 file12 &&
 431                echo "some text" >>file12 &&
 432                git add file12 &&
 433                git commit -a -m "Copy file2 to file12 with changes" &&
 434                git diff-tree -r -C --find-copies-harder HEAD &&
 435                level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
 436                test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
 437                src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
 438                test "$src" = file10 &&
 439                git config git-p4.detectCopies $(($level + 2)) &&
 440                "$GITP4" submit &&
 441                p4 filelog //depot/file12 &&
 442                p4 filelog //depot/file12 | test_must_fail grep -q "branch from" &&
 443
 444                cp file2 file13 &&
 445                echo "different text" >>file13 &&
 446                git add file13 &&
 447                git commit -a -m "Copy file2 to file13 with changes" &&
 448                git diff-tree -r -C --find-copies-harder HEAD &&
 449                level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
 450                test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
 451                src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
 452                test "$src" = file10 &&
 453                git config git-p4.detectCopies $(($level - 2)) &&
 454                "$GITP4" submit &&
 455                p4 filelog //depot/file13 &&
 456                p4 filelog //depot/file13 | grep -q "branch from //depot/file"
 457        )
 458'
 459
 460test_expect_success 'kill p4d' '
 461        kill_p4d
 462'
 463
 464test_done