t / t5528-push-default.shon commit Merge branch 'jc/push-to-checkout' (cba07bb)
   1#!/bin/sh
   2
   3test_description='check various push.default settings'
   4. ./test-lib.sh
   5
   6test_expect_success 'setup bare remotes' '
   7        git init --bare repo1 &&
   8        git remote add parent1 repo1 &&
   9        git init --bare repo2 &&
  10        git remote add parent2 repo2 &&
  11        test_commit one &&
  12        git push parent1 HEAD &&
  13        git push parent2 HEAD
  14'
  15
  16# $1 = local revision
  17# $2 = remote revision (tested to be equal to the local one)
  18# $3 = [optional] repo to check for actual output (repo1 by default)
  19check_pushed_commit () {
  20        git log -1 --format='%h %s' "$1" >expect &&
  21        git --git-dir="${3:-repo1}" log -1 --format='%h %s' "$2" >actual &&
  22        test_cmp expect actual
  23}
  24
  25# $1 = push.default value
  26# $2 = expected target branch for the push
  27# $3 = [optional] repo to check for actual output (repo1 by default)
  28test_push_success () {
  29        git ${1:+-c push.default="$1"} push &&
  30        check_pushed_commit HEAD "$2" "$3"
  31}
  32
  33# $1 = push.default value
  34# check that push fails and does not modify any remote branch
  35test_push_failure () {
  36        git --git-dir=repo1 log --no-walk --format='%h %s' --all >expect &&
  37        test_must_fail git ${1:+-c push.default="$1"} push &&
  38        git --git-dir=repo1 log --no-walk --format='%h %s' --all >actual &&
  39        test_cmp expect actual
  40}
  41
  42# $1 = success or failure
  43# $2 = push.default value
  44# $3 = branch to check for actual output (master or foo)
  45# $4 = [optional] switch to triangular workflow
  46test_pushdefault_workflow () {
  47        workflow=central
  48        pushdefault=parent1
  49        if test -n "${4-}"; then
  50                workflow=triangular
  51                pushdefault=parent2
  52        fi
  53        test_expect_success "push.default = $2 $1 in $workflow workflows" "
  54                test_config branch.master.remote parent1 &&
  55                test_config branch.master.merge refs/heads/foo &&
  56                test_config remote.pushdefault $pushdefault &&
  57                test_commit commit-for-$2${4+-triangular} &&
  58                test_push_$1 $2 $3 ${4+repo2}
  59        "
  60}
  61
  62test_expect_success '"upstream" pushes to configured upstream' '
  63        git checkout master &&
  64        test_config branch.master.remote parent1 &&
  65        test_config branch.master.merge refs/heads/foo &&
  66        test_commit two &&
  67        test_push_success upstream foo
  68'
  69
  70test_expect_success '"upstream" does not push on unconfigured remote' '
  71        git checkout master &&
  72        test_unconfig branch.master.remote &&
  73        test_commit three &&
  74        test_push_failure upstream
  75'
  76
  77test_expect_success '"upstream" does not push on unconfigured branch' '
  78        git checkout master &&
  79        test_config branch.master.remote parent1 &&
  80        test_unconfig branch.master.merge &&
  81        test_commit four &&
  82        test_push_failure upstream
  83'
  84
  85test_expect_success '"upstream" does not push when remotes do not match' '
  86        git checkout master &&
  87        test_config branch.master.remote parent1 &&
  88        test_config branch.master.merge refs/heads/foo &&
  89        test_config push.default upstream &&
  90        test_commit five &&
  91        test_must_fail git push parent2
  92'
  93
  94test_expect_success 'push from/to new branch with upstream, matching and simple' '
  95        git checkout -b new-branch &&
  96        test_push_failure simple &&
  97        test_push_failure matching &&
  98        test_push_failure upstream
  99'
 100
 101test_expect_success 'push from/to new branch with current creates remote branch' '
 102        test_config branch.new-branch.remote repo1 &&
 103        git checkout new-branch &&
 104        test_push_success current new-branch
 105'
 106
 107test_expect_success 'push to existing branch, with no upstream configured' '
 108        test_config branch.master.remote repo1 &&
 109        git checkout master &&
 110        test_push_failure simple &&
 111        test_push_failure upstream
 112'
 113
 114test_expect_success 'push to existing branch, upstream configured with same name' '
 115        test_config branch.master.remote repo1 &&
 116        test_config branch.master.merge refs/heads/master &&
 117        git checkout master &&
 118        test_commit six &&
 119        test_push_success upstream master &&
 120        test_commit seven &&
 121        test_push_success simple master
 122'
 123
 124test_expect_success 'push to existing branch, upstream configured with different name' '
 125        test_config branch.master.remote repo1 &&
 126        test_config branch.master.merge refs/heads/other-name &&
 127        git checkout master &&
 128        test_commit eight &&
 129        test_push_success upstream other-name &&
 130        test_commit nine &&
 131        test_push_failure simple &&
 132        git --git-dir=repo1 log -1 --format="%h %s" "other-name" >expect-other-name &&
 133        test_push_success current master &&
 134        git --git-dir=repo1 log -1 --format="%h %s" "other-name" >actual-other-name &&
 135        test_cmp expect-other-name actual-other-name
 136'
 137
 138# We are on 'master', which integrates with 'foo' from parent1
 139# remote (set in test_pushdefault_workflow helper).  Push to
 140# parent1 in centralized, and push to parent2 in triangular workflow.
 141# The parent1 repository has 'master' and 'foo' branches, while
 142# the parent2 repository has only 'master' branch.
 143#
 144# test_pushdefault_workflow() arguments:
 145# $1 = success or failure
 146# $2 = push.default value
 147# $3 = branch to check for actual output (master or foo)
 148# $4 = [optional] switch to triangular workflow
 149
 150# update parent1's master (which is not our upstream)
 151test_pushdefault_workflow success current master
 152
 153# update parent1's foo (which is our upstream)
 154test_pushdefault_workflow success upstream foo
 155
 156# upsream is foo which is not the name of the current branch
 157test_pushdefault_workflow failure simple master
 158
 159# master and foo are updated
 160test_pushdefault_workflow success matching master
 161
 162# master is updated
 163test_pushdefault_workflow success current master triangular
 164
 165# upstream mode cannot be used in triangular
 166test_pushdefault_workflow failure upstream foo triangular
 167
 168# in triangular, 'simple' works as 'current' and update the branch
 169# with the same name.
 170test_pushdefault_workflow success simple master triangular
 171
 172# master is updated (parent2 does not have foo)
 173test_pushdefault_workflow success matching master triangular
 174
 175# default tests, when no push-default is specified. This
 176# should behave the same as "simple" in non-triangular
 177# settings, and as "current" otherwise.
 178
 179test_expect_success 'default behavior allows "simple" push' '
 180        test_config branch.master.remote parent1 &&
 181        test_config branch.master.merge refs/heads/master &&
 182        test_config remote.pushdefault parent1 &&
 183        test_commit default-master-master &&
 184        test_push_success "" master
 185'
 186
 187test_expect_success 'default behavior rejects non-simple push' '
 188        test_config branch.master.remote parent1 &&
 189        test_config branch.master.merge refs/heads/foo &&
 190        test_config remote.pushdefault parent1 &&
 191        test_commit default-master-foo &&
 192        test_push_failure ""
 193'
 194
 195test_expect_success 'default triangular behavior acts like "current"' '
 196        test_config branch.master.remote parent1 &&
 197        test_config branch.master.merge refs/heads/foo &&
 198        test_config remote.pushdefault parent2 &&
 199        test_commit default-triangular &&
 200        test_push_success "" master repo2
 201'
 202
 203test_done