t / t5528-push-default.shon commit untracked-cache: be defensive about missing NULs in index (c6909f9)
   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} ${1:+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} ${1:+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 ambiguously named branch with upstream, matching and simple' '
 102        git checkout -b ambiguous &&
 103        test_config branch.ambiguous.remote parent1 &&
 104        test_config branch.ambiguous.merge refs/heads/ambiguous &&
 105        git tag ambiguous &&
 106        test_push_success simple ambiguous &&
 107        test_push_success matching ambiguous &&
 108        test_push_success upstream ambiguous
 109'
 110
 111test_expect_success 'push from/to new branch with current creates remote branch' '
 112        test_config branch.new-branch.remote repo1 &&
 113        git checkout new-branch &&
 114        test_push_success current new-branch
 115'
 116
 117test_expect_success 'push to existing branch, with no upstream configured' '
 118        test_config branch.master.remote repo1 &&
 119        git checkout master &&
 120        test_push_failure simple &&
 121        test_push_failure upstream
 122'
 123
 124test_expect_success 'push to existing branch, upstream configured with same name' '
 125        test_config branch.master.remote repo1 &&
 126        test_config branch.master.merge refs/heads/master &&
 127        git checkout master &&
 128        test_commit six &&
 129        test_push_success upstream master &&
 130        test_commit seven &&
 131        test_push_success simple master
 132'
 133
 134test_expect_success 'push to existing branch, upstream configured with different name' '
 135        test_config branch.master.remote repo1 &&
 136        test_config branch.master.merge refs/heads/other-name &&
 137        git checkout master &&
 138        test_commit eight &&
 139        test_push_success upstream other-name &&
 140        test_commit nine &&
 141        test_push_failure simple &&
 142        git --git-dir=repo1 log -1 --format="%h %s" "other-name" >expect-other-name &&
 143        test_push_success current master &&
 144        git --git-dir=repo1 log -1 --format="%h %s" "other-name" >actual-other-name &&
 145        test_cmp expect-other-name actual-other-name
 146'
 147
 148# We are on 'master', which integrates with 'foo' from parent1
 149# remote (set in test_pushdefault_workflow helper).  Push to
 150# parent1 in centralized, and push to parent2 in triangular workflow.
 151# The parent1 repository has 'master' and 'foo' branches, while
 152# the parent2 repository has only 'master' branch.
 153#
 154# test_pushdefault_workflow() arguments:
 155# $1 = success or failure
 156# $2 = push.default value
 157# $3 = branch to check for actual output (master or foo)
 158# $4 = [optional] switch to triangular workflow
 159
 160# update parent1's master (which is not our upstream)
 161test_pushdefault_workflow success current master
 162
 163# update parent1's foo (which is our upstream)
 164test_pushdefault_workflow success upstream foo
 165
 166# upsream is foo which is not the name of the current branch
 167test_pushdefault_workflow failure simple master
 168
 169# master and foo are updated
 170test_pushdefault_workflow success matching master
 171
 172# master is updated
 173test_pushdefault_workflow success current master triangular
 174
 175# upstream mode cannot be used in triangular
 176test_pushdefault_workflow failure upstream foo triangular
 177
 178# in triangular, 'simple' works as 'current' and update the branch
 179# with the same name.
 180test_pushdefault_workflow success simple master triangular
 181
 182# master is updated (parent2 does not have foo)
 183test_pushdefault_workflow success matching master triangular
 184
 185# default tests, when no push-default is specified. This
 186# should behave the same as "simple" in non-triangular
 187# settings, and as "current" otherwise.
 188
 189test_expect_success 'default behavior allows "simple" push' '
 190        test_config branch.master.remote parent1 &&
 191        test_config branch.master.merge refs/heads/master &&
 192        test_config remote.pushdefault parent1 &&
 193        test_commit default-master-master &&
 194        test_push_success "" master
 195'
 196
 197test_expect_success 'default behavior rejects non-simple push' '
 198        test_config branch.master.remote parent1 &&
 199        test_config branch.master.merge refs/heads/foo &&
 200        test_config remote.pushdefault parent1 &&
 201        test_commit default-master-foo &&
 202        test_push_failure ""
 203'
 204
 205test_expect_success 'default triangular behavior acts like "current"' '
 206        test_config branch.master.remote parent1 &&
 207        test_config branch.master.merge refs/heads/foo &&
 208        test_config remote.pushdefault parent2 &&
 209        test_commit default-triangular &&
 210        test_push_success "" master repo2
 211'
 212
 213test_done