0f410c45f7005e7de1237e556396db5726a22e50
   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        git p4 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        git p4 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 git p4 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                git p4 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        git p4 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        git p4 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        git p4 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" git p4 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        git p4 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 'wildcard files submit back to p4, add' '
 167        test_when_finished cleanup_git &&
 168        git p4 clone --dest="$git" //depot &&
 169        (
 170                cd "$git" &&
 171                echo git-wild-hash >git-wild#hash &&
 172                echo git-wild-star >git-wild\*star &&
 173                echo git-wild-at >git-wild@at &&
 174                echo git-wild-percent >git-wild%percent &&
 175                git add git-wild* &&
 176                git commit -m "add some wildcard filenames" &&
 177                git config git-p4.skipSubmitEdit true &&
 178                git p4 submit
 179        ) &&
 180        (
 181                cd "$cli" &&
 182                test_path_is_file git-wild#hash &&
 183                test_path_is_file git-wild\*star &&
 184                test_path_is_file git-wild@at &&
 185                test_path_is_file git-wild%percent
 186        )
 187'
 188
 189test_expect_success 'wildcard files submit back to p4, modify' '
 190        test_when_finished cleanup_git &&
 191        git p4 clone --dest="$git" //depot &&
 192        (
 193                cd "$git" &&
 194                echo new-line >>git-wild#hash &&
 195                echo new-line >>git-wild\*star &&
 196                echo new-line >>git-wild@at &&
 197                echo new-line >>git-wild%percent &&
 198                git add git-wild* &&
 199                git commit -m "modify the wildcard files" &&
 200                git config git-p4.skipSubmitEdit true &&
 201                git p4 submit
 202        ) &&
 203        (
 204                cd "$cli" &&
 205                test_line_count = 2 git-wild#hash &&
 206                test_line_count = 2 git-wild\*star &&
 207                test_line_count = 2 git-wild@at &&
 208                test_line_count = 2 git-wild%percent
 209        )
 210'
 211
 212test_expect_success 'wildcard files submit back to p4, copy' '
 213        test_when_finished cleanup_git &&
 214        git p4 clone --dest="$git" //depot &&
 215        (
 216                cd "$git" &&
 217                cp file2 git-wild-cp#hash &&
 218                git add git-wild-cp#hash &&
 219                cp git-wild\*star file-wild-3 &&
 220                git add file-wild-3 &&
 221                git commit -m "wildcard copies" &&
 222                git config git-p4.detectCopies true &&
 223                git config git-p4.detectCopiesHarder true &&
 224                git config git-p4.skipSubmitEdit true &&
 225                git p4 submit
 226        ) &&
 227        (
 228                cd "$cli" &&
 229                test_path_is_file git-wild-cp#hash &&
 230                test_path_is_file file-wild-3
 231        )
 232'
 233
 234test_expect_success 'wildcard files submit back to p4, rename' '
 235        test_when_finished cleanup_git &&
 236        git p4 clone --dest="$git" //depot &&
 237        (
 238                cd "$git" &&
 239                git mv git-wild@at file-wild-4 &&
 240                git mv file-wild-3 git-wild-cp%percent &&
 241                git commit -m "wildcard renames" &&
 242                git config git-p4.detectRenames true &&
 243                git config git-p4.skipSubmitEdit true &&
 244                git p4 submit
 245        ) &&
 246        (
 247                cd "$cli" &&
 248                test_path_is_missing git-wild@at &&
 249                test_path_is_file git-wild-cp%percent
 250        )
 251'
 252
 253test_expect_success 'wildcard files submit back to p4, delete' '
 254        test_when_finished cleanup_git &&
 255        git p4 clone --dest="$git" //depot &&
 256        (
 257                cd "$git" &&
 258                git rm git-wild* &&
 259                git commit -m "delete the wildcard files" &&
 260                git config git-p4.skipSubmitEdit true &&
 261                git p4 submit
 262        ) &&
 263        (
 264                cd "$cli" &&
 265                test_path_is_missing git-wild#hash &&
 266                test_path_is_missing git-wild\*star &&
 267                test_path_is_missing git-wild@at &&
 268                test_path_is_missing git-wild%percent
 269        )
 270'
 271
 272test_expect_success 'clone bare' '
 273        git p4 clone --dest="$git" --bare //depot &&
 274        test_when_finished cleanup_git &&
 275        (
 276                cd "$git" &&
 277                test ! -d .git &&
 278                bare=`git config --get core.bare` &&
 279                test "$bare" = true
 280        )
 281'
 282
 283p4_add_user() {
 284        name=$1 fullname=$2 &&
 285        p4 user -f -i <<-EOF &&
 286        User: $name
 287        Email: $name@localhost
 288        FullName: $fullname
 289        EOF
 290        p4 passwd -P secret $name
 291}
 292
 293p4_grant_admin() {
 294        name=$1 &&
 295        {
 296                p4 protect -o &&
 297                echo "    admin user $name * //depot/..."
 298        } | p4 protect -i
 299}
 300
 301p4_check_commit_author() {
 302        file=$1 user=$2 &&
 303        p4 changes -m 1 //depot/$file | grep -q $user
 304}
 305
 306make_change_by_user() {
 307        file=$1 name=$2 email=$3 &&
 308        echo "username: a change by $name" >>"$file" &&
 309        git add "$file" &&
 310        git commit --author "$name <$email>" -m "a change by $name"
 311}
 312
 313# Test username support, submitting as user 'alice'
 314test_expect_success 'preserve users' '
 315        p4_add_user alice Alice &&
 316        p4_add_user bob Bob &&
 317        p4_grant_admin alice &&
 318        git p4 clone --dest="$git" //depot &&
 319        test_when_finished cleanup_git &&
 320        (
 321                cd "$git" &&
 322                echo "username: a change by alice" >>file1 &&
 323                echo "username: a change by bob" >>file2 &&
 324                git commit --author "Alice <alice@localhost>" -m "a change by alice" file1 &&
 325                git commit --author "Bob <bob@localhost>" -m "a change by bob" file2 &&
 326                git config git-p4.skipSubmitEditCheck true &&
 327                P4EDITOR=touch P4USER=alice P4PASSWD=secret git p4 commit --preserve-user &&
 328                p4_check_commit_author file1 alice &&
 329                p4_check_commit_author file2 bob
 330        )
 331'
 332
 333# Test username support, submitting as bob, who lacks admin rights. Should
 334# not submit change to p4 (git diff should show deltas).
 335test_expect_success 'refuse to preserve users without perms' '
 336        git p4 clone --dest="$git" //depot &&
 337        test_when_finished cleanup_git &&
 338        (
 339                cd "$git" &&
 340                git config git-p4.skipSubmitEditCheck true &&
 341                echo "username-noperms: a change by alice" >>file1 &&
 342                git commit --author "Alice <alice@localhost>" -m "perms: a change by alice" file1 &&
 343                P4EDITOR=touch P4USER=bob P4PASSWD=secret &&
 344                export P4EDITOR P4USER P4PASSWD &&
 345                test_must_fail git p4 commit --preserve-user &&
 346                ! git diff --exit-code HEAD..p4/master
 347        )
 348'
 349
 350# What happens with unknown author? Without allowMissingP4Users it should fail.
 351test_expect_success 'preserve user where author is unknown to p4' '
 352        git p4 clone --dest="$git" //depot &&
 353        test_when_finished cleanup_git &&
 354        (
 355                cd "$git" &&
 356                git config git-p4.skipSubmitEditCheck true &&
 357                echo "username-bob: a change by bob" >>file1 &&
 358                git commit --author "Bob <bob@localhost>" -m "preserve: a change by bob" file1 &&
 359                echo "username-unknown: a change by charlie" >>file1 &&
 360                git commit --author "Charlie <charlie@localhost>" -m "preserve: a change by charlie" file1 &&
 361                P4EDITOR=touch P4USER=alice P4PASSWD=secret &&
 362                export P4EDITOR P4USER P4PASSWD &&
 363                test_must_fail git p4 commit --preserve-user &&
 364                ! git diff --exit-code HEAD..p4/master &&
 365
 366                echo "$0: repeat with allowMissingP4Users enabled" &&
 367                git config git-p4.allowMissingP4Users true &&
 368                git config git-p4.preserveUser true &&
 369                git p4 commit &&
 370                git diff --exit-code HEAD..p4/master &&
 371                p4_check_commit_author file1 alice
 372        )
 373'
 374
 375# If we're *not* using --preserve-user, git p4 should warn if we're submitting
 376# changes that are not all ours.
 377# Test: user in p4 and user unknown to p4.
 378# Test: warning disabled and user is the same.
 379test_expect_success 'not preserving user with mixed authorship' '
 380        git p4 clone --dest="$git" //depot &&
 381        test_when_finished cleanup_git &&
 382        (
 383                cd "$git" &&
 384                git config git-p4.skipSubmitEditCheck true &&
 385                p4_add_user derek Derek &&
 386
 387                make_change_by_user usernamefile3 Derek derek@localhost &&
 388                P4EDITOR=cat P4USER=alice P4PASSWD=secret &&
 389                export P4EDITOR P4USER P4PASSWD &&
 390                git p4 commit |\
 391                grep "git author derek@localhost does not match" &&
 392
 393                make_change_by_user usernamefile3 Charlie charlie@localhost &&
 394                git p4 commit |\
 395                grep "git author charlie@localhost does not match" &&
 396
 397                make_change_by_user usernamefile3 alice alice@localhost &&
 398                git p4 commit |\
 399                test_must_fail grep "git author.*does not match" &&
 400
 401                git config git-p4.skipUserNameCheck true &&
 402                make_change_by_user usernamefile3 Charlie charlie@localhost &&
 403                git p4 commit |\
 404                test_must_fail grep "git author.*does not match" &&
 405
 406                p4_check_commit_author usernamefile3 alice
 407        )
 408'
 409
 410marshal_dump() {
 411        what=$1
 412        "$PYTHON_PATH" -c 'import marshal, sys; d = marshal.load(sys.stdin); print d["'$what'"]'
 413}
 414
 415# Sleep a bit so that the top-most p4 change did not happen "now".  Then
 416# import the repo and make sure that the initial import has the same time
 417# as the top-most change.
 418test_expect_success 'initial import time from top change time' '
 419        p4change=$(p4 -G changes -m 1 //depot/... | marshal_dump change) &&
 420        p4time=$(p4 -G changes -m 1 //depot/... | marshal_dump time) &&
 421        sleep 3 &&
 422        git p4 clone --dest="$git" //depot &&
 423        test_when_finished cleanup_git &&
 424        (
 425                cd "$git" &&
 426                gittime=$(git show -s --raw --pretty=format:%at HEAD) &&
 427                echo $p4time $gittime &&
 428                test $p4time = $gittime
 429        )
 430'
 431
 432# Rename a file and confirm that rename is not detected in P4.
 433# Rename the new file again with detectRenames option enabled and confirm that
 434# this is detected in P4.
 435# Rename the new file again adding an extra line, configure a big threshold in
 436# detectRenames and confirm that rename is not detected in P4.
 437# Repeat, this time with a smaller threshold and confirm that the rename is
 438# detected in P4.
 439test_expect_success 'detect renames' '
 440        git p4 clone --dest="$git" //depot@all &&
 441        test_when_finished cleanup_git &&
 442        (
 443                cd "$git" &&
 444                git config git-p4.skipSubmitEdit true &&
 445
 446                git mv file1 file4 &&
 447                git commit -a -m "Rename file1 to file4" &&
 448                git diff-tree -r -M HEAD &&
 449                git p4 submit &&
 450                p4 filelog //depot/file4 &&
 451                p4 filelog //depot/file4 | test_must_fail grep -q "branch from" &&
 452
 453                git mv file4 file5 &&
 454                git commit -a -m "Rename file4 to file5" &&
 455                git diff-tree -r -M HEAD &&
 456                git config git-p4.detectRenames true &&
 457                git p4 submit &&
 458                p4 filelog //depot/file5 &&
 459                p4 filelog //depot/file5 | grep -q "branch from //depot/file4" &&
 460
 461                git mv file5 file6 &&
 462                echo update >>file6 &&
 463                git add file6 &&
 464                git commit -a -m "Rename file5 to file6 with changes" &&
 465                git diff-tree -r -M HEAD &&
 466                level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
 467                test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
 468                git config git-p4.detectRenames $(($level + 2)) &&
 469                git p4 submit &&
 470                p4 filelog //depot/file6 &&
 471                p4 filelog //depot/file6 | test_must_fail grep -q "branch from" &&
 472
 473                git mv file6 file7 &&
 474                echo update >>file7 &&
 475                git add file7 &&
 476                git commit -a -m "Rename file6 to file7 with changes" &&
 477                git diff-tree -r -M HEAD &&
 478                level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
 479                test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
 480                git config git-p4.detectRenames $(($level - 2)) &&
 481                git p4 submit &&
 482                p4 filelog //depot/file7 &&
 483                p4 filelog //depot/file7 | grep -q "branch from //depot/file6"
 484        )
 485'
 486
 487# Copy a file and confirm that copy is not detected in P4.
 488# Copy a file with detectCopies option enabled and confirm that copy is not
 489# detected in P4.
 490# Modify and copy a file with detectCopies option enabled and confirm that copy
 491# is detected in P4.
 492# Copy a file with detectCopies and detectCopiesHarder options enabled and
 493# confirm that copy is detected in P4.
 494# Modify and copy a file, configure a bigger threshold in detectCopies and
 495# confirm that copy is not detected in P4.
 496# Modify and copy a file, configure a smaller threshold in detectCopies and
 497# confirm that copy is detected in P4.
 498test_expect_success 'detect copies' '
 499        git p4 clone --dest="$git" //depot@all &&
 500        test_when_finished cleanup_git &&
 501        (
 502                cd "$git" &&
 503                git config git-p4.skipSubmitEdit true &&
 504
 505                cp file2 file8 &&
 506                git add file8 &&
 507                git commit -a -m "Copy file2 to file8" &&
 508                git diff-tree -r -C HEAD &&
 509                git p4 submit &&
 510                p4 filelog //depot/file8 &&
 511                p4 filelog //depot/file8 | test_must_fail grep -q "branch from" &&
 512
 513                cp file2 file9 &&
 514                git add file9 &&
 515                git commit -a -m "Copy file2 to file9" &&
 516                git diff-tree -r -C HEAD &&
 517                git config git-p4.detectCopies true &&
 518                git p4 submit &&
 519                p4 filelog //depot/file9 &&
 520                p4 filelog //depot/file9 | test_must_fail grep -q "branch from" &&
 521
 522                echo "file2" >>file2 &&
 523                cp file2 file10 &&
 524                git add file2 file10 &&
 525                git commit -a -m "Modify and copy file2 to file10" &&
 526                git diff-tree -r -C HEAD &&
 527                git p4 submit &&
 528                p4 filelog //depot/file10 &&
 529                p4 filelog //depot/file10 | grep -q "branch from //depot/file" &&
 530
 531                cp file2 file11 &&
 532                git add file11 &&
 533                git commit -a -m "Copy file2 to file11" &&
 534                git diff-tree -r -C --find-copies-harder HEAD &&
 535                src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
 536                test "$src" = file10 &&
 537                git config git-p4.detectCopiesHarder true &&
 538                git p4 submit &&
 539                p4 filelog //depot/file11 &&
 540                p4 filelog //depot/file11 | grep -q "branch from //depot/file" &&
 541
 542                cp file2 file12 &&
 543                echo "some text" >>file12 &&
 544                git add file12 &&
 545                git commit -a -m "Copy file2 to file12 with changes" &&
 546                git diff-tree -r -C --find-copies-harder HEAD &&
 547                level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
 548                test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
 549                src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
 550                test "$src" = file10 &&
 551                git config git-p4.detectCopies $(($level + 2)) &&
 552                git p4 submit &&
 553                p4 filelog //depot/file12 &&
 554                p4 filelog //depot/file12 | test_must_fail grep -q "branch from" &&
 555
 556                cp file2 file13 &&
 557                echo "different text" >>file13 &&
 558                git add file13 &&
 559                git commit -a -m "Copy file2 to file13 with changes" &&
 560                git diff-tree -r -C --find-copies-harder HEAD &&
 561                level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
 562                test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
 563                src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
 564                test "$src" = file10 &&
 565                git config git-p4.detectCopies $(($level - 2)) &&
 566                git p4 submit &&
 567                p4 filelog //depot/file13 &&
 568                p4 filelog //depot/file13 | grep -q "branch from //depot/file"
 569        )
 570'
 571
 572test_expect_success 'kill p4d' '
 573        kill_p4d
 574'
 575
 576test_done