t / t5533-push-cas.shon commit t4000: make hash size independent (8cc5ff8)
   1#!/bin/sh
   2
   3test_description='compare & swap push force/delete safety'
   4
   5. ./test-lib.sh
   6
   7setup_srcdst_basic () {
   8        rm -fr src dst &&
   9        git clone --no-local . src &&
  10        git clone --no-local src dst &&
  11        (
  12                cd src && git checkout HEAD^0
  13        )
  14}
  15
  16test_expect_success setup '
  17        # create template repository
  18        test_commit A &&
  19        test_commit B &&
  20        test_commit C
  21'
  22
  23test_expect_success 'push to update (protected)' '
  24        setup_srcdst_basic &&
  25        (
  26                cd dst &&
  27                test_commit D &&
  28                test_must_fail git push --force-with-lease=master:master origin master 2>err &&
  29                grep "stale info" err
  30        ) &&
  31        git ls-remote . refs/heads/master >expect &&
  32        git ls-remote src refs/heads/master >actual &&
  33        test_cmp expect actual
  34'
  35
  36test_expect_success 'push to update (protected, forced)' '
  37        setup_srcdst_basic &&
  38        (
  39                cd dst &&
  40                test_commit D &&
  41                git push --force --force-with-lease=master:master origin master 2>err &&
  42                grep "forced update" err
  43        ) &&
  44        git ls-remote dst refs/heads/master >expect &&
  45        git ls-remote src refs/heads/master >actual &&
  46        test_cmp expect actual
  47'
  48
  49test_expect_success 'push to update (protected, tracking)' '
  50        setup_srcdst_basic &&
  51        (
  52                cd src &&
  53                git checkout master &&
  54                test_commit D &&
  55                git checkout HEAD^0
  56        ) &&
  57        git ls-remote src refs/heads/master >expect &&
  58        (
  59                cd dst &&
  60                test_commit E &&
  61                git ls-remote . refs/remotes/origin/master >expect &&
  62                test_must_fail git push --force-with-lease=master origin master &&
  63                git ls-remote . refs/remotes/origin/master >actual &&
  64                test_cmp expect actual
  65        ) &&
  66        git ls-remote src refs/heads/master >actual &&
  67        test_cmp expect actual
  68'
  69
  70test_expect_success 'push to update (protected, tracking, forced)' '
  71        setup_srcdst_basic &&
  72        (
  73                cd src &&
  74                git checkout master &&
  75                test_commit D &&
  76                git checkout HEAD^0
  77        ) &&
  78        (
  79                cd dst &&
  80                test_commit E &&
  81                git ls-remote . refs/remotes/origin/master >expect &&
  82                git push --force --force-with-lease=master origin master
  83        ) &&
  84        git ls-remote dst refs/heads/master >expect &&
  85        git ls-remote src refs/heads/master >actual &&
  86        test_cmp expect actual
  87'
  88
  89test_expect_success 'push to update (allowed)' '
  90        setup_srcdst_basic &&
  91        (
  92                cd dst &&
  93                test_commit D &&
  94                git push --force-with-lease=master:master^ origin master
  95        ) &&
  96        git ls-remote dst refs/heads/master >expect &&
  97        git ls-remote src refs/heads/master >actual &&
  98        test_cmp expect actual
  99'
 100
 101test_expect_success 'push to update (allowed, tracking)' '
 102        setup_srcdst_basic &&
 103        (
 104                cd dst &&
 105                test_commit D &&
 106                git push --force-with-lease=master origin master 2>err &&
 107                ! grep "forced update" err
 108        ) &&
 109        git ls-remote dst refs/heads/master >expect &&
 110        git ls-remote src refs/heads/master >actual &&
 111        test_cmp expect actual
 112'
 113
 114test_expect_success 'push to update (allowed even though no-ff)' '
 115        setup_srcdst_basic &&
 116        (
 117                cd dst &&
 118                git reset --hard HEAD^ &&
 119                test_commit D &&
 120                git push --force-with-lease=master origin master 2>err &&
 121                grep "forced update" err
 122        ) &&
 123        git ls-remote dst refs/heads/master >expect &&
 124        git ls-remote src refs/heads/master >actual &&
 125        test_cmp expect actual
 126'
 127
 128test_expect_success 'push to delete (protected)' '
 129        setup_srcdst_basic &&
 130        git ls-remote src refs/heads/master >expect &&
 131        (
 132                cd dst &&
 133                test_must_fail git push --force-with-lease=master:master^ origin :master
 134        ) &&
 135        git ls-remote src refs/heads/master >actual &&
 136        test_cmp expect actual
 137'
 138
 139test_expect_success 'push to delete (protected, forced)' '
 140        setup_srcdst_basic &&
 141        (
 142                cd dst &&
 143                git push --force --force-with-lease=master:master^ origin :master
 144        ) &&
 145        git ls-remote src refs/heads/master >actual &&
 146        test_must_be_empty actual
 147'
 148
 149test_expect_success 'push to delete (allowed)' '
 150        setup_srcdst_basic &&
 151        (
 152                cd dst &&
 153                git push --force-with-lease=master origin :master 2>err &&
 154                grep deleted err
 155        ) &&
 156        git ls-remote src refs/heads/master >actual &&
 157        test_must_be_empty actual
 158'
 159
 160test_expect_success 'cover everything with default force-with-lease (protected)' '
 161        setup_srcdst_basic &&
 162        (
 163                cd src &&
 164                git branch naster master^
 165        ) &&
 166        git ls-remote src refs/heads/\* >expect &&
 167        (
 168                cd dst &&
 169                test_must_fail git push --force-with-lease origin master master:naster
 170        ) &&
 171        git ls-remote src refs/heads/\* >actual &&
 172        test_cmp expect actual
 173'
 174
 175test_expect_success 'cover everything with default force-with-lease (allowed)' '
 176        setup_srcdst_basic &&
 177        (
 178                cd src &&
 179                git branch naster master^
 180        ) &&
 181        (
 182                cd dst &&
 183                git fetch &&
 184                git push --force-with-lease origin master master:naster
 185        ) &&
 186        git ls-remote dst refs/heads/master |
 187        sed -e "s/master/naster/" >expect &&
 188        git ls-remote src refs/heads/naster >actual &&
 189        test_cmp expect actual
 190'
 191
 192test_expect_success 'new branch covered by force-with-lease' '
 193        setup_srcdst_basic &&
 194        (
 195                cd dst &&
 196                git branch branch master &&
 197                git push --force-with-lease=branch origin branch
 198        ) &&
 199        git ls-remote dst refs/heads/branch >expect &&
 200        git ls-remote src refs/heads/branch >actual &&
 201        test_cmp expect actual
 202'
 203
 204test_expect_success 'new branch covered by force-with-lease (explicit)' '
 205        setup_srcdst_basic &&
 206        (
 207                cd dst &&
 208                git branch branch master &&
 209                git push --force-with-lease=branch: origin branch
 210        ) &&
 211        git ls-remote dst refs/heads/branch >expect &&
 212        git ls-remote src refs/heads/branch >actual &&
 213        test_cmp expect actual
 214'
 215
 216test_expect_success 'new branch already exists' '
 217        setup_srcdst_basic &&
 218        (
 219                cd src &&
 220                git checkout -b branch master &&
 221                test_commit F
 222        ) &&
 223        (
 224                cd dst &&
 225                git branch branch master &&
 226                test_must_fail git push --force-with-lease=branch: origin branch
 227        )
 228'
 229
 230test_expect_success 'background updates of REMOTE can be mitigated with a non-updated REMOTE-push' '
 231        rm -rf src dst &&
 232        git init --bare src.bare &&
 233        test_when_finished "rm -rf src.bare" &&
 234        git clone --no-local src.bare dst &&
 235        test_when_finished "rm -rf dst" &&
 236        (
 237                cd dst &&
 238                test_commit G &&
 239                git remote add origin-push ../src.bare &&
 240                git push origin-push master:master
 241        ) &&
 242        git clone --no-local src.bare dst2 &&
 243        test_when_finished "rm -rf dst2" &&
 244        (
 245                cd dst2 &&
 246                test_commit H &&
 247                git push
 248        ) &&
 249        (
 250                cd dst &&
 251                test_commit I &&
 252                git fetch origin &&
 253                test_must_fail git push --force-with-lease origin-push &&
 254                git fetch origin-push &&
 255                git push --force-with-lease origin-push
 256        )
 257'
 258
 259test_done