t / t9800-git-p4-basic.shon commit blame $path: avoid getting fooled by case insensitive filesystems (ffcabcc)
   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 &&
 238                export P4EDITOR P4USER P4PASSWD &&
 239                test_must_fail "$GITP4" commit --preserve-user &&
 240                ! git diff --exit-code HEAD..p4/master
 241        )
 242'
 243
 244# What happens with unknown author? Without allowMissingP4Users it should fail.
 245test_expect_success 'preserve user where author is unknown to p4' '
 246        "$GITP4" clone --dest="$git" //depot &&
 247        test_when_finished cleanup_git &&
 248        (
 249                cd "$git" &&
 250                git config git-p4.skipSubmitEditCheck true &&
 251                echo "username-bob: a change by bob" >>file1 &&
 252                git commit --author "Bob <bob@localhost>" -m "preserve: a change by bob" file1 &&
 253                echo "username-unknown: a change by charlie" >>file1 &&
 254                git commit --author "Charlie <charlie@localhost>" -m "preserve: a change by charlie" file1 &&
 255                P4EDITOR=touch P4USER=alice P4PASSWD=secret &&
 256                export P4EDITOR P4USER P4PASSWD &&
 257                test_must_fail "$GITP4" commit --preserve-user &&
 258                ! git diff --exit-code HEAD..p4/master &&
 259
 260                echo "$0: repeat with allowMissingP4Users enabled" &&
 261                git config git-p4.allowMissingP4Users true &&
 262                git config git-p4.preserveUser true &&
 263                "$GITP4" commit &&
 264                git diff --exit-code HEAD..p4/master &&
 265                p4_check_commit_author file1 alice
 266        )
 267'
 268
 269# If we're *not* using --preserve-user, git-p4 should warn if we're submitting
 270# changes that are not all ours.
 271# Test: user in p4 and user unknown to p4.
 272# Test: warning disabled and user is the same.
 273test_expect_success 'not preserving user with mixed authorship' '
 274        "$GITP4" clone --dest="$git" //depot &&
 275        test_when_finished cleanup_git &&
 276        (
 277                cd "$git" &&
 278                git config git-p4.skipSubmitEditCheck true &&
 279                p4_add_user derek Derek &&
 280
 281                make_change_by_user usernamefile3 Derek derek@localhost &&
 282                P4EDITOR=cat P4USER=alice P4PASSWD=secret &&
 283                export P4EDITOR P4USER P4PASSWD &&
 284                "$GITP4" commit |\
 285                grep "git author derek@localhost does not match" &&
 286
 287                make_change_by_user usernamefile3 Charlie charlie@localhost &&
 288                "$GITP4" commit |\
 289                grep "git author charlie@localhost does not match" &&
 290
 291                make_change_by_user usernamefile3 alice alice@localhost &&
 292                "$GITP4" commit |\
 293                test_must_fail grep "git author.*does not match" &&
 294
 295                git config git-p4.skipUserNameCheck true &&
 296                make_change_by_user usernamefile3 Charlie charlie@localhost &&
 297                "$GITP4" commit |\
 298                test_must_fail grep "git author.*does not match" &&
 299
 300                p4_check_commit_author usernamefile3 alice
 301        )
 302'
 303
 304marshal_dump() {
 305        what=$1
 306        "$PYTHON_PATH" -c 'import marshal, sys; d = marshal.load(sys.stdin); print d["'$what'"]'
 307}
 308
 309# Sleep a bit so that the top-most p4 change did not happen "now".  Then
 310# import the repo and make sure that the initial import has the same time
 311# as the top-most change.
 312test_expect_success 'initial import time from top change time' '
 313        p4change=$(p4 -G changes -m 1 //depot/... | marshal_dump change) &&
 314        p4time=$(p4 -G changes -m 1 //depot/... | marshal_dump time) &&
 315        sleep 3 &&
 316        "$GITP4" clone --dest="$git" //depot &&
 317        test_when_finished cleanup_git &&
 318        (
 319                cd "$git" &&
 320                gittime=$(git show -s --raw --pretty=format:%at HEAD) &&
 321                echo $p4time $gittime &&
 322                test $p4time = $gittime
 323        )
 324'
 325
 326# Rename a file and confirm that rename is not detected in P4.
 327# Rename the new file again with detectRenames option enabled and confirm that
 328# this is detected in P4.
 329# Rename the new file again adding an extra line, configure a big threshold in
 330# detectRenames and confirm that rename is not detected in P4.
 331# Repeat, this time with a smaller threshold and confirm that the rename is
 332# detected in P4.
 333test_expect_success 'detect renames' '
 334        "$GITP4" clone --dest="$git" //depot@all &&
 335        test_when_finished cleanup_git &&
 336        (
 337                cd "$git" &&
 338                git config git-p4.skipSubmitEditCheck true &&
 339
 340                git mv file1 file4 &&
 341                git commit -a -m "Rename file1 to file4" &&
 342                git diff-tree -r -M HEAD &&
 343                "$GITP4" submit &&
 344                p4 filelog //depot/file4 &&
 345                p4 filelog //depot/file4 | test_must_fail grep -q "branch from" &&
 346
 347                git mv file4 file5 &&
 348                git commit -a -m "Rename file4 to file5" &&
 349                git diff-tree -r -M HEAD &&
 350                git config git-p4.detectRenames true &&
 351                "$GITP4" submit &&
 352                p4 filelog //depot/file5 &&
 353                p4 filelog //depot/file5 | grep -q "branch from //depot/file4" &&
 354
 355                git mv file5 file6 &&
 356                echo update >>file6 &&
 357                git add file6 &&
 358                git commit -a -m "Rename file5 to file6 with changes" &&
 359                git diff-tree -r -M HEAD &&
 360                level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
 361                test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
 362                git config git-p4.detectRenames $(($level + 2)) &&
 363                "$GITP4" submit &&
 364                p4 filelog //depot/file6 &&
 365                p4 filelog //depot/file6 | test_must_fail grep -q "branch from" &&
 366
 367                git mv file6 file7 &&
 368                echo update >>file7 &&
 369                git add file7 &&
 370                git commit -a -m "Rename file6 to file7 with changes" &&
 371                git diff-tree -r -M HEAD &&
 372                level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
 373                test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
 374                git config git-p4.detectRenames $(($level - 2)) &&
 375                "$GITP4" submit &&
 376                p4 filelog //depot/file7 &&
 377                p4 filelog //depot/file7 | grep -q "branch from //depot/file6"
 378        )
 379'
 380
 381# Copy a file and confirm that copy is not detected in P4.
 382# Copy a file with detectCopies option enabled and confirm that copy is not
 383# detected in P4.
 384# Modify and copy a file with detectCopies option enabled and confirm that copy
 385# is detected in P4.
 386# Copy a file with detectCopies and detectCopiesHarder options enabled and
 387# confirm that copy is detected in P4.
 388# Modify and copy a file, configure a bigger threshold in detectCopies and
 389# confirm that copy is not detected in P4.
 390# Modify and copy a file, configure a smaller threshold in detectCopies and
 391# confirm that copy is detected in P4.
 392test_expect_success 'detect copies' '
 393        "$GITP4" clone --dest="$git" //depot@all &&
 394        test_when_finished cleanup_git &&
 395        (
 396                cd "$git" &&
 397                git config git-p4.skipSubmitEditCheck true &&
 398
 399                cp file2 file8 &&
 400                git add file8 &&
 401                git commit -a -m "Copy file2 to file8" &&
 402                git diff-tree -r -C HEAD &&
 403                "$GITP4" submit &&
 404                p4 filelog //depot/file8 &&
 405                p4 filelog //depot/file8 | test_must_fail grep -q "branch from" &&
 406
 407                cp file2 file9 &&
 408                git add file9 &&
 409                git commit -a -m "Copy file2 to file9" &&
 410                git diff-tree -r -C HEAD &&
 411                git config git-p4.detectCopies true &&
 412                "$GITP4" submit &&
 413                p4 filelog //depot/file9 &&
 414                p4 filelog //depot/file9 | test_must_fail grep -q "branch from" &&
 415
 416                echo "file2" >>file2 &&
 417                cp file2 file10 &&
 418                git add file2 file10 &&
 419                git commit -a -m "Modify and copy file2 to file10" &&
 420                git diff-tree -r -C HEAD &&
 421                "$GITP4" submit &&
 422                p4 filelog //depot/file10 &&
 423                p4 filelog //depot/file10 | grep -q "branch from //depot/file" &&
 424
 425                cp file2 file11 &&
 426                git add file11 &&
 427                git commit -a -m "Copy file2 to file11" &&
 428                git diff-tree -r -C --find-copies-harder HEAD &&
 429                src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
 430                test "$src" = file10 &&
 431                git config git-p4.detectCopiesHarder true &&
 432                "$GITP4" submit &&
 433                p4 filelog //depot/file11 &&
 434                p4 filelog //depot/file11 | grep -q "branch from //depot/file" &&
 435
 436                cp file2 file12 &&
 437                echo "some text" >>file12 &&
 438                git add file12 &&
 439                git commit -a -m "Copy file2 to file12 with changes" &&
 440                git diff-tree -r -C --find-copies-harder HEAD &&
 441                level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
 442                test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
 443                src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
 444                test "$src" = file10 &&
 445                git config git-p4.detectCopies $(($level + 2)) &&
 446                "$GITP4" submit &&
 447                p4 filelog //depot/file12 &&
 448                p4 filelog //depot/file12 | test_must_fail grep -q "branch from" &&
 449
 450                cp file2 file13 &&
 451                echo "different text" >>file13 &&
 452                git add file13 &&
 453                git commit -a -m "Copy file2 to file13 with changes" &&
 454                git diff-tree -r -C --find-copies-harder HEAD &&
 455                level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
 456                test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
 457                src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
 458                test "$src" = file10 &&
 459                git config git-p4.detectCopies $(($level - 2)) &&
 460                "$GITP4" submit &&
 461                p4 filelog //depot/file13 &&
 462                p4 filelog //depot/file13 | grep -q "branch from //depot/file"
 463        )
 464'
 465
 466test_expect_success 'kill p4d' '
 467        kill_p4d
 468'
 469
 470test_done