Merge branch 'jc/push-2.0-default-to-simple' (early part)
authorJunio C Hamano <gitster@pobox.com>
Thu, 18 Apr 2013 18:47:59 +0000 (11:47 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 18 Apr 2013 18:47:59 +0000 (11:47 -0700)
Adjust our tests for upcoming migration of the default value for the
"push.default" configuration variable to "simple" from "mixed".

* 'jc/push-2.0-default-to-simple' (early part):
t5570: do not assume the "matching" push is the default
t5551: do not assume the "matching" push is the default
t5550: do not assume the "matching" push is the default
t9401: do not assume the "matching" push is the default
t9400: do not assume the "matching" push is the default
t7406: do not assume the "matching" push is the default
t5531: do not assume the "matching" push is the default
t5519: do not assume the "matching" push is the default
t5517: do not assume the "matching" push is the default
t5516: do not assume the "matching" push is the default
t5505: do not assume the "matching" push is the default
t5404: do not assume the "matching" push is the default

1  2 
t/t5516-fetch-push.sh
t/t5551-http-fetch.sh
t/t7406-submodule-update.sh
diff --combined t/t5516-fetch-push.sh
index 838e71dafea8388cbe18c82b26f58f074f56abbd,1a8753d2ebc3d7b8b494ca3d3a935f7b8bb0b7c0..4691d51b8cde48dbb97ac5dfc1e3b75fe90f8da3
@@@ -1,28 -1,16 +1,28 @@@
  #!/bin/sh
  
 -test_description='fetching and pushing, with or without wildcard'
 +test_description='Basic fetch/push functionality.
 +
 +This test checks the following functionality:
 +
 +* command-line syntax
 +* refspecs
 +* fast-forward detection, and overriding it
 +* configuration
 +* hooks
 +* --porcelain output format
 +* hiderefs
 +'
  
  . ./test-lib.sh
  
  D=`pwd`
  
  mk_empty () {
 -      rm -fr testrepo &&
 -      mkdir testrepo &&
 +      repo_name="$1"
 +      rm -fr "$repo_name" &&
 +      mkdir "$repo_name" &&
        (
 -              cd testrepo &&
 +              cd "$repo_name" &&
                git init &&
                git config receive.denyCurrentBranch warn &&
                mv .git/hooks .git/hooks-disabled
  }
  
  mk_test () {
 -      mk_empty &&
 +      repo_name="$1"
 +      shift
 +
 +      mk_empty "$repo_name" &&
        (
                for ref in "$@"
                do
 -                      git push testrepo $the_first_commit:refs/$ref || {
 -                              echo "Oops, push refs/$ref failure"
 -                              exit 1
 -                      }
 +                      git push "$repo_name" $the_first_commit:refs/$ref ||
 +                      exit
                done &&
 -              cd testrepo &&
 +              cd "$repo_name" &&
                for ref in "$@"
                do
 -                      r=$(git show-ref -s --verify refs/$ref) &&
 -                      test "z$r" = "z$the_first_commit" || {
 -                              echo "Oops, refs/$ref is wrong"
 -                              exit 1
 -                      }
 +                      echo "$the_first_commit" >expect &&
 +                      git show-ref -s --verify refs/$ref >actual &&
 +                      test_cmp expect actual ||
 +                      exit
                done &&
                git fsck --full
        )
  }
  
  mk_test_with_hooks() {
 +      repo_name=$1
        mk_test "$@" &&
        (
 -              cd testrepo &&
 +              cd "$repo_name" &&
                mkdir .git/hooks &&
                cd .git/hooks &&
  
  }
  
  mk_child() {
 -      rm -rf "$1" &&
 -      git clone testrepo "$1"
 +      rm -rf "$2" &&
 +      git clone "$1" "$2"
  }
  
  check_push_result () {
 +      repo_name="$1"
 +      shift
 +
        (
 -              cd testrepo &&
 -              it="$1" &&
 -              shift
 +              cd "$repo_name" &&
 +              echo "$1" >expect &&
 +              shift &&
                for ref in "$@"
                do
 -                      r=$(git show-ref -s --verify refs/$ref) &&
 -                      test "z$r" = "z$it" || {
 -                              echo "Oops, refs/$ref is wrong"
 -                              exit 1
 -                      }
 +                      git show-ref -s --verify refs/$ref >actual &&
 +                      test_cmp expect actual ||
 +                      exit
                done &&
                git fsck --full
        )
@@@ -127,33 -113,35 +127,33 @@@ test_expect_success setup 
  '
  
  test_expect_success 'fetch without wildcard' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        (
                cd testrepo &&
                git fetch .. refs/heads/master:refs/remotes/origin/master &&
  
 -              r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 -              test "z$r" = "z$the_commit" &&
 -
 -              test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 +              echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 +              git for-each-ref refs/remotes/origin >actual &&
 +              test_cmp expect actual
        )
  '
  
  test_expect_success 'fetch with wildcard' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        (
                cd testrepo &&
                git config remote.up.url .. &&
                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
                git fetch up &&
  
 -              r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 -              test "z$r" = "z$the_commit" &&
 -
 -              test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 +              echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 +              git for-each-ref refs/remotes/origin >actual &&
 +              test_cmp expect actual
        )
  '
  
  test_expect_success 'fetch with insteadOf' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        (
                TRASH=$(pwd)/ &&
                cd testrepo &&
                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
                git fetch up &&
  
 -              r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 -              test "z$r" = "z$the_commit" &&
 -
 -              test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 +              echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 +              git for-each-ref refs/remotes/origin >actual &&
 +              test_cmp expect actual
        )
  '
  
  test_expect_success 'fetch with pushInsteadOf (should not rewrite)' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        (
                TRASH=$(pwd)/ &&
                cd testrepo &&
                git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
                git fetch up &&
  
 -              r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 -              test "z$r" = "z$the_commit" &&
 -
 -              test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 +              echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 +              git for-each-ref refs/remotes/origin >actual &&
 +              test_cmp expect actual
        )
  '
  
  test_expect_success 'push without wildcard' '
 -      mk_empty &&
 +      mk_empty testrepo &&
  
        git push testrepo refs/heads/master:refs/remotes/origin/master &&
        (
                cd testrepo &&
 -              r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 -              test "z$r" = "z$the_commit" &&
 -
 -              test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 +              echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 +              git for-each-ref refs/remotes/origin >actual &&
 +              test_cmp expect actual
        )
  '
  
  test_expect_success 'push with wildcard' '
 -      mk_empty &&
 +      mk_empty testrepo &&
  
        git push testrepo "refs/heads/*:refs/remotes/origin/*" &&
        (
                cd testrepo &&
 -              r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 -              test "z$r" = "z$the_commit" &&
 -
 -              test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 +              echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 +              git for-each-ref refs/remotes/origin >actual &&
 +              test_cmp expect actual
        )
  '
  
  test_expect_success 'push with insteadOf' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        TRASH="$(pwd)/" &&
 -      git config "url.$TRASH.insteadOf" trash/ &&
 +      test_config "url.$TRASH.insteadOf" trash/ &&
        git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
        (
                cd testrepo &&
 -              r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 -              test "z$r" = "z$the_commit" &&
 -
 -              test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 +              echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 +              git for-each-ref refs/remotes/origin >actual &&
 +              test_cmp expect actual
        )
  '
  
  test_expect_success 'push with pushInsteadOf' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        TRASH="$(pwd)/" &&
 -      git config "url.$TRASH.pushInsteadOf" trash/ &&
 +      test_config "url.$TRASH.pushInsteadOf" trash/ &&
        git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
        (
                cd testrepo &&
 -              r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 -              test "z$r" = "z$the_commit" &&
 -
 -              test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 +              echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 +              git for-each-ref refs/remotes/origin >actual &&
 +              test_cmp expect actual
        )
  '
  
  test_expect_success 'push with pushInsteadOf and explicit pushurl (pushInsteadOf should not rewrite)' '
 -      mk_empty &&
 -      TRASH="$(pwd)/" &&
 -      git config "url.trash2/.pushInsteadOf" trash/ &&
 -      git config remote.r.url trash/wrong &&
 -      git config remote.r.pushurl "$TRASH/testrepo" &&
 +      mk_empty testrepo &&
 +      test_config "url.trash2/.pushInsteadOf" testrepo/ &&
 +      test_config "url.trash3/.pusnInsteadOf" trash/wrong &&
 +      test_config remote.r.url trash/wrong &&
 +      test_config remote.r.pushurl "testrepo/" &&
        git push r refs/heads/master:refs/remotes/origin/master &&
        (
                cd testrepo &&
 -              r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 -              test "z$r" = "z$the_commit" &&
 -
 -              test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 +              echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 +              git for-each-ref refs/remotes/origin >actual &&
 +              test_cmp expect actual
        )
  '
  
  test_expect_success 'push with matching heads' '
  
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
-       git push testrepo &&
+       git push testrepo &&
 -      check_push_result $the_commit heads/master
 +      check_push_result testrepo $the_commit heads/master
  
  '
  
  test_expect_success 'push with matching heads on the command line' '
  
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        git push testrepo : &&
 -      check_push_result $the_commit heads/master
 +      check_push_result testrepo $the_commit heads/master
  
  '
  
  test_expect_success 'failed (non-fast-forward) push with matching heads' '
  
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        git push testrepo : &&
        git commit --amend -massaged &&
        test_must_fail git push testrepo &&
 -      check_push_result $the_commit heads/master &&
 +      check_push_result testrepo $the_commit heads/master &&
        git reset --hard $the_commit
  
  '
  
  test_expect_success 'push --force with matching heads' '
  
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        git push testrepo : &&
        git commit --amend -massaged &&
-       git push --force testrepo &&
+       git push --force testrepo &&
 -      ! check_push_result $the_commit heads/master &&
 +      ! check_push_result testrepo $the_commit heads/master &&
        git reset --hard $the_commit
  
  '
  
  test_expect_success 'push with matching heads and forced update' '
  
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        git push testrepo : &&
        git commit --amend -massaged &&
        git push testrepo +: &&
 -      ! check_push_result $the_commit heads/master &&
 +      ! check_push_result testrepo $the_commit heads/master &&
        git reset --hard $the_commit
  
  '
  
  test_expect_success 'push with no ambiguity (1)' '
  
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        git push testrepo master:master &&
 -      check_push_result $the_commit heads/master
 +      check_push_result testrepo $the_commit heads/master
  
  '
  
  test_expect_success 'push with no ambiguity (2)' '
  
 -      mk_test remotes/origin/master &&
 +      mk_test testrepo remotes/origin/master &&
        git push testrepo master:origin/master &&
 -      check_push_result $the_commit remotes/origin/master
 +      check_push_result testrepo $the_commit remotes/origin/master
  
  '
  
  test_expect_success 'push with colon-less refspec, no ambiguity' '
  
 -      mk_test heads/master heads/t/master &&
 +      mk_test testrepo heads/master heads/t/master &&
        git branch -f t/master master &&
        git push testrepo master &&
 -      check_push_result $the_commit heads/master &&
 -      check_push_result $the_first_commit heads/t/master
 +      check_push_result testrepo $the_commit heads/master &&
 +      check_push_result testrepo $the_first_commit heads/t/master
  
  '
  
  test_expect_success 'push with weak ambiguity (1)' '
  
 -      mk_test heads/master remotes/origin/master &&
 +      mk_test testrepo heads/master remotes/origin/master &&
        git push testrepo master:master &&
 -      check_push_result $the_commit heads/master &&
 -      check_push_result $the_first_commit remotes/origin/master
 +      check_push_result testrepo $the_commit heads/master &&
 +      check_push_result testrepo $the_first_commit remotes/origin/master
  
  '
  
  test_expect_success 'push with weak ambiguity (2)' '
  
 -      mk_test heads/master remotes/origin/master remotes/another/master &&
 +      mk_test testrepo heads/master remotes/origin/master remotes/another/master &&
        git push testrepo master:master &&
 -      check_push_result $the_commit heads/master &&
 -      check_push_result $the_first_commit remotes/origin/master remotes/another/master
 +      check_push_result testrepo $the_commit heads/master &&
 +      check_push_result testrepo $the_first_commit remotes/origin/master remotes/another/master
  
  '
  
  test_expect_success 'push with ambiguity' '
  
 -      mk_test heads/frotz tags/frotz &&
 -      if git push testrepo master:frotz
 -      then
 -              echo "Oops, should have failed"
 -              false
 -      else
 -              check_push_result $the_first_commit heads/frotz tags/frotz
 -      fi
 +      mk_test testrepo heads/frotz tags/frotz &&
 +      test_must_fail git push testrepo master:frotz &&
 +      check_push_result testrepo $the_first_commit heads/frotz tags/frotz
  
  '
  
  test_expect_success 'push with colon-less refspec (1)' '
  
 -      mk_test heads/frotz tags/frotz &&
 +      mk_test testrepo heads/frotz tags/frotz &&
        git branch -f frotz master &&
        git push testrepo frotz &&
 -      check_push_result $the_commit heads/frotz &&
 -      check_push_result $the_first_commit tags/frotz
 +      check_push_result testrepo $the_commit heads/frotz &&
 +      check_push_result testrepo $the_first_commit tags/frotz
  
  '
  
  test_expect_success 'push with colon-less refspec (2)' '
  
 -      mk_test heads/frotz tags/frotz &&
 +      mk_test testrepo heads/frotz tags/frotz &&
        if git show-ref --verify -q refs/heads/frotz
        then
                git branch -D frotz
        fi &&
        git tag -f frotz &&
 -      git push testrepo frotz &&
 -      check_push_result $the_commit tags/frotz &&
 -      check_push_result $the_first_commit heads/frotz
 +      git push -f testrepo frotz &&
 +      check_push_result testrepo $the_commit tags/frotz &&
 +      check_push_result testrepo $the_first_commit heads/frotz
  
  '
  
  test_expect_success 'push with colon-less refspec (3)' '
  
 -      mk_test &&
 +      mk_test testrepo &&
        if git show-ref --verify -q refs/tags/frotz
        then
                git tag -d frotz
        fi &&
        git branch -f frotz master &&
        git push testrepo frotz &&
 -      check_push_result $the_commit heads/frotz &&
 +      check_push_result testrepo $the_commit heads/frotz &&
        test 1 = $( cd testrepo && git show-ref | wc -l )
  '
  
  test_expect_success 'push with colon-less refspec (4)' '
  
 -      mk_test &&
 +      mk_test testrepo &&
        if git show-ref --verify -q refs/heads/frotz
        then
                git branch -D frotz
        fi &&
        git tag -f frotz &&
        git push testrepo frotz &&
 -      check_push_result $the_commit tags/frotz &&
 +      check_push_result testrepo $the_commit tags/frotz &&
        test 1 = $( cd testrepo && git show-ref | wc -l )
  
  '
  
  test_expect_success 'push head with non-existent, incomplete dest' '
  
 -      mk_test &&
 +      mk_test testrepo &&
        git push testrepo master:branch &&
 -      check_push_result $the_commit heads/branch
 +      check_push_result testrepo $the_commit heads/branch
  
  '
  
  test_expect_success 'push tag with non-existent, incomplete dest' '
  
 -      mk_test &&
 +      mk_test testrepo &&
        git tag -f v1.0 &&
        git push testrepo v1.0:tag &&
 -      check_push_result $the_commit tags/tag
 +      check_push_result testrepo $the_commit tags/tag
  
  '
  
  test_expect_success 'push sha1 with non-existent, incomplete dest' '
  
 -      mk_test &&
 +      mk_test testrepo &&
        test_must_fail git push testrepo `git rev-parse master`:foo
  
  '
  
  test_expect_success 'push ref expression with non-existent, incomplete dest' '
  
 -      mk_test &&
 +      mk_test testrepo &&
        test_must_fail git push testrepo master^:branch
  
  '
  
  test_expect_success 'push with HEAD' '
  
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        git checkout master &&
        git push testrepo HEAD &&
 -      check_push_result $the_commit heads/master
 +      check_push_result testrepo $the_commit heads/master
  
  '
  
  test_expect_success 'push with HEAD nonexisting at remote' '
  
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        git checkout -b local master &&
        git push testrepo HEAD &&
 -      check_push_result $the_commit heads/local
 +      check_push_result testrepo $the_commit heads/local
  '
  
  test_expect_success 'push with +HEAD' '
  
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        git checkout master &&
        git branch -D local &&
        git checkout -b local &&
        git push testrepo master local &&
 -      check_push_result $the_commit heads/master &&
 -      check_push_result $the_commit heads/local &&
 +      check_push_result testrepo $the_commit heads/master &&
 +      check_push_result testrepo $the_commit heads/local &&
  
        # Without force rewinding should fail
        git reset --hard HEAD^ &&
        test_must_fail git push testrepo HEAD &&
 -      check_push_result $the_commit heads/local &&
 +      check_push_result testrepo $the_commit heads/local &&
  
        # With force rewinding should succeed
        git push testrepo +HEAD &&
 -      check_push_result $the_first_commit heads/local
 +      check_push_result testrepo $the_first_commit heads/local
  
  '
  
  test_expect_success 'push HEAD with non-existent, incomplete dest' '
  
 -      mk_test &&
 +      mk_test testrepo &&
        git checkout master &&
        git push testrepo HEAD:branch &&
 -      check_push_result $the_commit heads/branch
 +      check_push_result testrepo $the_commit heads/branch
  
  '
  
  test_expect_success 'push with config remote.*.push = HEAD' '
  
 -      mk_test heads/local &&
 +      mk_test testrepo heads/local &&
        git checkout master &&
        git branch -f local $the_commit &&
        (
                git checkout local &&
                git reset --hard $the_first_commit
        ) &&
 -      git config remote.there.url testrepo &&
 -      git config remote.there.push HEAD &&
 -      git config branch.master.remote there &&
 +      test_config remote.there.url testrepo &&
 +      test_config remote.there.push HEAD &&
 +      test_config branch.master.remote there &&
 +      git push &&
 +      check_push_result testrepo $the_commit heads/master &&
 +      check_push_result testrepo $the_first_commit heads/local
 +'
 +
 +test_expect_success 'push with remote.pushdefault' '
 +      mk_test up_repo heads/master &&
 +      mk_test down_repo heads/master &&
 +      test_config remote.up.url up_repo &&
 +      test_config remote.down.url down_repo &&
 +      test_config branch.master.remote up &&
 +      test_config remote.pushdefault down &&
++      test_config push.default matching &&
        git push &&
 -      check_push_result $the_commit heads/master &&
 -      check_push_result $the_first_commit heads/local
 +      check_push_result up_repo $the_first_commit heads/master &&
 +      check_push_result down_repo $the_commit heads/master
  '
  
 -# clean up the cruft left with the previous one
 -git config --remove-section remote.there
 -git config --remove-section branch.master
 -
  test_expect_success 'push with config remote.*.pushurl' '
  
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        git checkout master &&
 -      git config remote.there.url test2repo &&
 -      git config remote.there.pushurl testrepo &&
 +      test_config remote.there.url test2repo &&
 +      test_config remote.there.pushurl testrepo &&
-       git push there &&
+       git push there &&
 -      check_push_result $the_commit heads/master
 +      check_push_result testrepo $the_commit heads/master
 +'
 +
 +test_expect_success 'push with config branch.*.pushremote' '
 +      mk_test up_repo heads/master &&
 +      mk_test side_repo heads/master &&
 +      mk_test down_repo heads/master &&
 +      test_config remote.up.url up_repo &&
 +      test_config remote.pushdefault side_repo &&
 +      test_config remote.down.url down_repo &&
 +      test_config branch.master.remote up &&
 +      test_config branch.master.pushremote down &&
++      test_config push.default matching &&
 +      git push &&
 +      check_push_result up_repo $the_first_commit heads/master &&
 +      check_push_result side_repo $the_first_commit heads/master &&
 +      check_push_result down_repo $the_commit heads/master
  '
  
 -# clean up the cruft left with the previous one
 -git config --remove-section remote.there
 -
  test_expect_success 'push with dry-run' '
  
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        (
                cd testrepo &&
                old_commit=$(git show-ref -s --verify refs/heads/master)
        ) &&
-       git push --dry-run testrepo &&
+       git push --dry-run testrepo &&
 -      check_push_result $old_commit heads/master
 +      check_push_result testrepo $old_commit heads/master
  '
  
  test_expect_success 'push updates local refs' '
  
 -      mk_test heads/master &&
 -      mk_child child &&
 +      mk_test testrepo heads/master &&
 +      mk_child testrepo child &&
        (
                cd child &&
                git pull .. master &&
  
  test_expect_success 'push updates up-to-date local refs' '
  
 -      mk_test heads/master &&
 -      mk_child child1 &&
 -      mk_child child2 &&
 +      mk_test testrepo heads/master &&
 +      mk_child testrepo child1 &&
 +      mk_child testrepo child2 &&
        (cd child1 && git pull .. master && git push) &&
        (
                cd child2 &&
  
  test_expect_success 'push preserves up-to-date packed refs' '
  
 -      mk_test heads/master &&
 -      mk_child child &&
 +      mk_test testrepo heads/master &&
 +      mk_child testrepo child &&
        (
                cd child &&
                git push &&
  
  test_expect_success 'push does not update local refs on failure' '
  
 -      mk_test heads/master &&
 -      mk_child child &&
 +      mk_test testrepo heads/master &&
 +      mk_child testrepo child &&
        mkdir testrepo/.git/hooks &&
        echo "#!/no/frobnication/today" >testrepo/.git/hooks/pre-receive &&
        chmod +x testrepo/.git/hooks/pre-receive &&
  
  test_expect_success 'allow deleting an invalid remote ref' '
  
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        rm -f testrepo/.git/objects/??/* &&
        git push testrepo :refs/heads/master &&
        (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
  '
  
  test_expect_success 'pushing valid refs triggers post-receive and post-update hooks' '
 -      mk_test_with_hooks heads/master heads/next &&
 +      mk_test_with_hooks testrepo heads/master heads/next &&
        orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) &&
        newmaster=$(git show-ref -s --verify refs/heads/master) &&
        orgnext=$(cd testrepo && git show-ref -s --verify refs/heads/next) &&
  '
  
  test_expect_success 'deleting dangling ref triggers hooks with correct args' '
 -      mk_test_with_hooks heads/master &&
 +      mk_test_with_hooks testrepo heads/master &&
        rm -f testrepo/.git/objects/??/* &&
        git push testrepo :refs/heads/master &&
        (
  '
  
  test_expect_success 'deletion of a non-existent ref is not fed to post-receive and post-update hooks' '
 -      mk_test_with_hooks heads/master &&
 +      mk_test_with_hooks testrepo heads/master &&
        orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) &&
        newmaster=$(git show-ref -s --verify refs/heads/master) &&
        git push testrepo master :refs/heads/nonexistent &&
  '
  
  test_expect_success 'deletion of a non-existent ref alone does trigger post-receive and post-update hooks' '
 -      mk_test_with_hooks heads/master &&
 +      mk_test_with_hooks testrepo heads/master &&
        git push testrepo :refs/heads/nonexistent &&
        (
                cd testrepo/.git &&
  '
  
  test_expect_success 'mixed ref updates, deletes, invalid deletes trigger hooks with correct input' '
 -      mk_test_with_hooks heads/master heads/next heads/pu &&
 +      mk_test_with_hooks testrepo heads/master heads/next heads/pu &&
        orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) &&
        newmaster=$(git show-ref -s --verify refs/heads/master) &&
        orgnext=$(cd testrepo && git show-ref -s --verify refs/heads/next) &&
  '
  
  test_expect_success 'allow deleting a ref using --delete' '
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        (cd testrepo && git config receive.denyDeleteCurrent warn) &&
        git push testrepo --delete master &&
        (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
  '
  
  test_expect_success 'allow deleting a tag using --delete' '
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        git tag -a -m dummy_message deltag heads/master &&
        git push testrepo --tags &&
        (cd testrepo && git rev-parse --verify -q refs/tags/deltag) &&
  '
  
  test_expect_success 'push --delete without args aborts' '
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        test_must_fail git push testrepo --delete
  '
  
  test_expect_success 'push --delete refuses src:dest refspecs' '
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        test_must_fail git push testrepo --delete master:foo
  '
  
  test_expect_success 'warn on push to HEAD of non-bare repository' '
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        (
                cd testrepo &&
                git checkout master &&
  '
  
  test_expect_success 'deny push to HEAD of non-bare repository' '
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        (
                cd testrepo &&
                git checkout master &&
  '
  
  test_expect_success 'allow push to HEAD of bare repository (bare)' '
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        (
                cd testrepo &&
                git checkout master &&
  '
  
  test_expect_success 'allow push to HEAD of non-bare repository (config)' '
 -      mk_test heads/master &&
 +      mk_test testrepo heads/master &&
        (
                cd testrepo &&
                git checkout master &&
  '
  
  test_expect_success 'fetch with branches' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        git branch second $the_first_commit &&
        git checkout second &&
        echo ".." > testrepo/.git/branches/branch1 &&
        (
                cd testrepo &&
                git fetch branch1 &&
 -              r=$(git show-ref -s --verify refs/heads/branch1) &&
 -              test "z$r" = "z$the_commit" &&
 -              test 1 = $(git for-each-ref refs/heads | wc -l)
 +              echo "$the_commit commit        refs/heads/branch1" >expect &&
 +              git for-each-ref refs/heads >actual &&
 +              test_cmp expect actual
        ) &&
        git checkout master
  '
  
  test_expect_success 'fetch with branches containing #' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        echo "..#second" > testrepo/.git/branches/branch2 &&
        (
                cd testrepo &&
                git fetch branch2 &&
 -              r=$(git show-ref -s --verify refs/heads/branch2) &&
 -              test "z$r" = "z$the_first_commit" &&
 -              test 1 = $(git for-each-ref refs/heads | wc -l)
 +              echo "$the_first_commit commit  refs/heads/branch2" >expect &&
 +              git for-each-ref refs/heads >actual &&
 +              test_cmp expect actual
        ) &&
        git checkout master
  '
  
  test_expect_success 'push with branches' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        git checkout second &&
        echo "testrepo" > .git/branches/branch1 &&
        git push branch1 &&
        (
                cd testrepo &&
 -              r=$(git show-ref -s --verify refs/heads/master) &&
 -              test "z$r" = "z$the_first_commit" &&
 -              test 1 = $(git for-each-ref refs/heads | wc -l)
 +              echo "$the_first_commit commit  refs/heads/master" >expect &&
 +              git for-each-ref refs/heads >actual &&
 +              test_cmp expect actual
        )
  '
  
  test_expect_success 'push with branches containing #' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        echo "testrepo#branch3" > .git/branches/branch2 &&
        git push branch2 &&
        (
                cd testrepo &&
 -              r=$(git show-ref -s --verify refs/heads/branch3) &&
 -              test "z$r" = "z$the_first_commit" &&
 -              test 1 = $(git for-each-ref refs/heads | wc -l)
 +              echo "$the_first_commit commit  refs/heads/branch3" >expect &&
 +              git for-each-ref refs/heads >actual &&
 +              test_cmp expect actual
        ) &&
        git checkout master
  '
  
  test_expect_success 'push into aliased refs (consistent)' '
 -      mk_test heads/master &&
 -      mk_child child1 &&
 -      mk_child child2 &&
 +      mk_test testrepo heads/master &&
 +      mk_child testrepo child1 &&
 +      mk_child testrepo child2 &&
        (
                cd child1 &&
                git branch foo &&
  '
  
  test_expect_success 'push into aliased refs (inconsistent)' '
 -      mk_test heads/master &&
 -      mk_child child1 &&
 -      mk_child child2 &&
 +      mk_test testrepo heads/master &&
 +      mk_child testrepo child1 &&
 +      mk_child testrepo child2 &&
        (
                cd child1 &&
                git branch foo &&
        )
  '
  
 +test_expect_success 'push requires --force to update lightweight tag' '
 +      mk_test testrepo heads/master &&
 +      mk_child testrepo child1 &&
 +      mk_child testrepo child2 &&
 +      (
 +              cd child1 &&
 +              git tag Tag &&
 +              git push ../child2 Tag &&
 +              git push ../child2 Tag &&
 +              >file1 &&
 +              git add file1 &&
 +              git commit -m "file1" &&
 +              git tag -f Tag &&
 +              test_must_fail git push ../child2 Tag &&
 +              git push --force ../child2 Tag &&
 +              git tag -f Tag &&
 +              test_must_fail git push ../child2 Tag HEAD~ &&
 +              git push --force ../child2 Tag
 +      )
 +'
 +
  test_expect_success 'push --porcelain' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        echo >.git/foo  "To testrepo" &&
        echo >>.git/foo "*      refs/heads/master:refs/remotes/origin/master    [new branch]"  &&
        echo >>.git/foo "Done" &&
        git push >.git/bar --porcelain  testrepo refs/heads/master:refs/remotes/origin/master &&
        (
                cd testrepo &&
 -              r=$(git show-ref -s --verify refs/remotes/origin/master) &&
 -              test "z$r" = "z$the_commit" &&
 -              test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
 +              echo "$the_commit commit        refs/remotes/origin/master" >expect &&
 +              git for-each-ref refs/remotes/origin >actual &&
 +              test_cmp expect actual
        ) &&
        test_cmp .git/foo .git/bar
  '
  
  test_expect_success 'push --porcelain bad url' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        test_must_fail git push >.git/bar --porcelain asdfasdfasd refs/heads/master:refs/remotes/origin/master &&
        test_must_fail grep -q Done .git/bar
  '
  
  test_expect_success 'push --porcelain rejected' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        git push testrepo refs/heads/master:refs/remotes/origin/master &&
        (cd testrepo &&
                git reset --hard origin/master^
  '
  
  test_expect_success 'push --porcelain --dry-run rejected' '
 -      mk_empty &&
 +      mk_empty testrepo &&
        git push testrepo refs/heads/master:refs/remotes/origin/master &&
        (cd testrepo &&
                git reset --hard origin/master
  '
  
  test_expect_success 'push --prune' '
 -      mk_test heads/master heads/second heads/foo heads/bar &&
 +      mk_test testrepo heads/master heads/second heads/foo heads/bar &&
-       git push --prune testrepo &&
+       git push --prune testrepo &&
 -      check_push_result $the_commit heads/master &&
 -      check_push_result $the_first_commit heads/second &&
 -      ! check_push_result $the_first_commit heads/foo heads/bar
 +      check_push_result testrepo $the_commit heads/master &&
 +      check_push_result testrepo $the_first_commit heads/second &&
 +      ! check_push_result testrepo $the_first_commit heads/foo heads/bar
  '
  
  test_expect_success 'push --prune refspec' '
 -      mk_test tmp/master tmp/second tmp/foo tmp/bar &&
 +      mk_test testrepo tmp/master tmp/second tmp/foo tmp/bar &&
        git push --prune testrepo "refs/heads/*:refs/tmp/*" &&
 -      check_push_result $the_commit tmp/master &&
 -      check_push_result $the_first_commit tmp/second &&
 -      ! check_push_result $the_first_commit tmp/foo tmp/bar
 +      check_push_result testrepo $the_commit tmp/master &&
 +      check_push_result testrepo $the_first_commit tmp/second &&
 +      ! check_push_result testrepo $the_first_commit tmp/foo tmp/bar
 +'
 +
 +for configsection in transfer receive
 +do
 +      test_expect_success "push to update a ref hidden by $configsection.hiderefs" '
 +              mk_test testrepo heads/master hidden/one hidden/two hidden/three &&
 +              (
 +                      cd testrepo &&
 +                      git config $configsection.hiderefs refs/hidden
 +              ) &&
 +
 +              # push to unhidden ref succeeds normally
 +              git push testrepo master:refs/heads/master &&
 +              check_push_result testrepo $the_commit heads/master &&
 +
 +              # push to update a hidden ref should fail
 +              test_must_fail git push testrepo master:refs/hidden/one &&
 +              check_push_result testrepo $the_first_commit hidden/one &&
 +
 +              # push to delete a hidden ref should fail
 +              test_must_fail git push testrepo :refs/hidden/two &&
 +              check_push_result testrepo $the_first_commit hidden/two &&
 +
 +              # idempotent push to update a hidden ref should fail
 +              test_must_fail git push testrepo $the_first_commit:refs/hidden/three &&
 +              check_push_result testrepo $the_first_commit hidden/three
 +      '
 +done
 +
 +test_expect_success 'fetch exact SHA1' '
 +      mk_test testrepo heads/master hidden/one &&
 +      git push testrepo master:refs/hidden/one &&
 +      (
 +              cd testrepo &&
 +              git config transfer.hiderefs refs/hidden
 +      ) &&
 +      check_push_result testrepo $the_commit hidden/one &&
 +
 +      mk_child testrepo child &&
 +      (
 +              cd child &&
 +
 +              # make sure $the_commit does not exist here
 +              git repack -a -d &&
 +              git prune &&
 +              test_must_fail git cat-file -t $the_commit &&
 +
 +              # fetching the hidden object should fail by default
 +              test_must_fail git fetch -v ../testrepo $the_commit:refs/heads/copy &&
 +              test_must_fail git rev-parse --verify refs/heads/copy &&
 +
 +              # the server side can allow it to succeed
 +              (
 +                      cd ../testrepo &&
 +                      git config uploadpack.allowtipsha1inwant true
 +              ) &&
 +
 +              git fetch -v ../testrepo $the_commit:refs/heads/copy &&
 +              result=$(git rev-parse --verify refs/heads/copy) &&
 +              test "$the_commit" = "$result"
 +      )
 +'
 +
 +test_expect_success 'fetch follows tags by default' '
 +      mk_test testrepo heads/master &&
 +      rm -fr src dst &&
 +      git init src &&
 +      (
 +              cd src &&
 +              git pull ../testrepo master &&
 +              git tag -m "annotated" tag &&
 +              git for-each-ref >tmp1 &&
 +              (
 +                      cat tmp1
 +                      sed -n "s|refs/heads/master$|refs/remotes/origin/master|p" tmp1
 +              ) |
 +              sort -k 3 >../expect
 +      ) &&
 +      git init dst &&
 +      (
 +              cd dst &&
 +              git remote add origin ../src &&
 +              git config branch.master.remote origin &&
 +              git config branch.master.merge refs/heads/master &&
 +              git pull &&
 +              git for-each-ref >../actual
 +      ) &&
 +      test_cmp expect actual
 +'
 +
 +test_expect_success 'push does not follow tags by default' '
 +      mk_test testrepo heads/master &&
 +      rm -fr src dst &&
 +      git init src &&
 +      git init --bare dst &&
 +      (
 +              cd src &&
 +              git pull ../testrepo master &&
 +              git tag -m "annotated" tag &&
 +              git checkout -b another &&
 +              git commit --allow-empty -m "future commit" &&
 +              git tag -m "future" future &&
 +              git checkout master &&
 +              git for-each-ref refs/heads/master >../expect &&
 +              git push ../dst master
 +      ) &&
 +      (
 +              cd dst &&
 +              git for-each-ref >../actual
 +      ) &&
 +      test_cmp expect actual
 +'
 +
 +test_expect_success 'push --follow-tag only pushes relevant tags' '
 +      mk_test testrepo heads/master &&
 +      rm -fr src dst &&
 +      git init src &&
 +      git init --bare dst &&
 +      (
 +              cd src &&
 +              git pull ../testrepo master &&
 +              git tag -m "annotated" tag &&
 +              git checkout -b another &&
 +              git commit --allow-empty -m "future commit" &&
 +              git tag -m "future" future &&
 +              git checkout master &&
 +              git for-each-ref refs/heads/master refs/tags/tag >../expect
 +              git push --follow-tag ../dst master
 +      ) &&
 +      (
 +              cd dst &&
 +              git for-each-ref >../actual
 +      ) &&
 +      test_cmp expect actual
  '
  
  test_done
diff --combined t/t5551-http-fetch.sh
index 47eb76921ddd53acb63573f9af75e41ab5067f5c,1b5508667f88886d0a2af5ff446673cd3f03c423..f0f313fb7cba3ff57a327bf96dad32dc55f77b72
@@@ -13,6 -13,7 +13,7 @@@ LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5551'
  start_httpd
  
  test_expect_success 'setup repository' '
+       git config push.default matching &&
        echo content >file &&
        git add file &&
        git commit -m one
@@@ -157,11 -158,6 +158,11 @@@ test_expect_success 'GIT_SMART_HTTP ca
         test_must_fail git fetch)
  '
  
 +test_expect_success 'invalid Content-Type rejected' '
 +      test_must_fail git clone $HTTPD_URL/broken_smart/repo.git 2>actual
 +      grep "not valid:" actual
 +'
 +
  test -n "$GIT_TEST_LONG" && test_set_prereq EXPENSIVE
  
  test_expect_success EXPENSIVE 'create 50,000 tags in the repo' '
index 2a0cfaac329c6c0974f205c81c45a0304a04897d,c675ce62970c14676754082c4c779972196eab1e..a4ffea0dbe743a1bbe4c5512037a6b1ffde1c313
@@@ -135,37 -135,6 +135,37 @@@ test_expect_success 'submodule update -
        )
  '
  
 +test_expect_success 'submodule update --remote should fetch upstream changes' '
 +      (cd submodule &&
 +       echo line4 >> file &&
 +       git add file &&
 +       test_tick &&
 +       git commit -m "upstream line4"
 +      ) &&
 +      (cd super &&
 +       git submodule update --remote --force submodule &&
 +       cd submodule &&
 +       test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline)"
 +      )
 +'
 +
 +test_expect_success 'local config should override .gitmodules branch' '
 +      (cd submodule &&
 +       git checkout -b test-branch &&
 +       echo line5 >> file &&
 +       git add file &&
 +       test_tick &&
 +       git commit -m "upstream line5" &&
 +       git checkout master
 +      ) &&
 +      (cd super &&
 +       git config submodule.submodule.branch test-branch &&
 +       git submodule update --remote --force submodule &&
 +       cd submodule &&
 +       test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline test-branch)"
 +      )
 +'
 +
  test_expect_success 'submodule update --rebase staying on master' '
        (cd super/submodule &&
          git checkout master
@@@ -596,14 -565,14 +596,14 @@@ test_expect_success 'submodule add plac
           git log > ../../../expected
          ) &&
          git commit -m "added subsubmodule" &&
-         git push
+         git push origin :
         ) &&
         (cd .git/modules/deeper/submodule/modules/subsubmodule &&
          git log > ../../../../../actual
         ) &&
         git add deeper/submodule &&
         git commit -m "update submodule" &&
-        git push &&
+        git push origin : &&
         test_cmp actual expected
        )
  '
@@@ -643,8 -612,7 +643,8 @@@ test_expect_success 'submodule update p
        rm -rf super_update_r2 &&
        git clone super_update_r super_update_r2 &&
        (cd super_update_r2 &&
 -       git submodule update --init --recursive &&
 +       git submodule update --init --recursive >actual &&
 +       test_i18ngrep "Submodule path .submodule/subsubmodule.: checked out" actual &&
         (cd submodule/subsubmodule &&
          git log > ../../expected
         ) &&
@@@ -665,10 -633,8 +665,10 @@@ test_expect_success 'submodule add prop
  
  test_expect_success 'submodule update properly revives a moved submodule' '
        (cd super &&
 +       H=$(git rev-parse --short HEAD) &&
         git commit -am "pre move" &&
 -       git status >expect&&
 +       H2=$(git rev-parse --short HEAD) &&
 +       git status | sed "s/$H/XXX/" >expect &&
         H=$(cd submodule2; git rev-parse HEAD) &&
         git rm --cached submodule2 &&
         rm -rf submodule2 &&
         git config -f .gitmodules submodule.submodule2.path "moved/sub module"
         git commit -am "post move" &&
         git submodule update &&
 -       git status >actual &&
 +       git status | sed "s/$H2/XXX/" >actual &&
         test_cmp expect actual
        )
  '