5e4db67b0121e76556c202af9566ca5c98e9fd6c
   1#!/bin/sh
   2
   3test_description='pulling into void'
   4
   5. ./test-lib.sh
   6
   7modify () {
   8        sed -e "$1" <"$2" >"$2.x" &&
   9        mv "$2.x" "$2"
  10}
  11
  12test_expect_success setup '
  13        echo file >file &&
  14        git add file &&
  15        git commit -a -m original
  16'
  17
  18test_expect_success 'pulling into void' '
  19        git init cloned &&
  20        (
  21                cd cloned &&
  22                git pull ..
  23        ) &&
  24        test -f file &&
  25        test -f cloned/file &&
  26        test_cmp file cloned/file
  27'
  28
  29test_expect_success 'pulling into void using master:master' '
  30        git init cloned-uho &&
  31        (
  32                cd cloned-uho &&
  33                git pull .. master:master
  34        ) &&
  35        test -f file &&
  36        test -f cloned-uho/file &&
  37        test_cmp file cloned-uho/file
  38'
  39
  40test_expect_success 'pulling into void does not overwrite untracked files' '
  41        git init cloned-untracked &&
  42        (
  43                cd cloned-untracked &&
  44                echo untracked >file &&
  45                test_must_fail git pull .. master &&
  46                echo untracked >expect &&
  47                test_cmp expect file
  48        )
  49'
  50
  51test_expect_success 'pulling into void does not overwrite staged files' '
  52        git init cloned-staged-colliding &&
  53        (
  54                cd cloned-staged-colliding &&
  55                echo "alternate content" >file &&
  56                git add file &&
  57                test_must_fail git pull .. master &&
  58                echo "alternate content" >expect &&
  59                test_cmp expect file &&
  60                git cat-file blob :file >file.index &&
  61                test_cmp expect file.index
  62        )
  63'
  64
  65test_expect_success 'pulling into void does not remove new staged files' '
  66        git init cloned-staged-new &&
  67        (
  68                cd cloned-staged-new &&
  69                echo "new tracked file" >newfile &&
  70                git add newfile &&
  71                git pull .. master &&
  72                echo "new tracked file" >expect &&
  73                test_cmp expect newfile &&
  74                git cat-file blob :newfile >newfile.index &&
  75                test_cmp expect newfile.index
  76        )
  77'
  78
  79test_expect_success 'pulling into void must not create an octopus' '
  80        git init cloned-octopus &&
  81        (
  82                cd cloned-octopus &&
  83                test_must_fail git pull .. master master &&
  84                ! test -f file
  85        )
  86'
  87
  88test_expect_success 'test . as a remote' '
  89
  90        git branch copy master &&
  91        git config branch.copy.remote . &&
  92        git config branch.copy.merge refs/heads/master &&
  93        echo updated >file &&
  94        git commit -a -m updated &&
  95        git checkout copy &&
  96        test "$(cat file)" = file &&
  97        git pull &&
  98        test "$(cat file)" = updated
  99'
 100
 101test_expect_success 'the default remote . should not break explicit pull' '
 102        git checkout -b second master^ &&
 103        echo modified >file &&
 104        git commit -a -m modified &&
 105        git checkout copy &&
 106        git reset --hard HEAD^ &&
 107        test "$(cat file)" = file &&
 108        git pull . second &&
 109        test "$(cat file)" = modified
 110'
 111
 112test_expect_success '--rebase' '
 113        git branch to-rebase &&
 114        echo modified again > file &&
 115        git commit -m file file &&
 116        git checkout to-rebase &&
 117        echo new > file2 &&
 118        git add file2 &&
 119        git commit -m "new file" &&
 120        git tag before-rebase &&
 121        git pull --rebase . copy &&
 122        test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
 123        test new = "$(git show HEAD:file2)"
 124'
 125test_expect_success 'pull.rebase' '
 126        git reset --hard before-rebase &&
 127        test_config pull.rebase true &&
 128        git pull . copy &&
 129        test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
 130        test new = "$(git show HEAD:file2)"
 131'
 132
 133test_expect_success 'branch.to-rebase.rebase' '
 134        git reset --hard before-rebase &&
 135        test_config branch.to-rebase.rebase true &&
 136        git pull . copy &&
 137        test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
 138        test new = "$(git show HEAD:file2)"
 139'
 140
 141test_expect_success 'branch.to-rebase.rebase should override pull.rebase' '
 142        git reset --hard before-rebase &&
 143        test_config pull.rebase true &&
 144        test_config branch.to-rebase.rebase false &&
 145        git pull . copy &&
 146        test "$(git rev-parse HEAD^)" != "$(git rev-parse copy)" &&
 147        test new = "$(git show HEAD:file2)"
 148'
 149
 150# add a feature branch, keep-merge, that is merged into master, so the
 151# test can try preserving the merge commit (or not) with various
 152# --rebase flags/pull.rebase settings.
 153test_expect_success 'preserve merge setup' '
 154        git reset --hard before-rebase &&
 155        git checkout -b keep-merge second^ &&
 156        test_commit file3 &&
 157        git checkout to-rebase &&
 158        git merge keep-merge &&
 159        git tag before-preserve-rebase
 160'
 161
 162test_expect_success 'pull.rebase=false create a new merge commit' '
 163        git reset --hard before-preserve-rebase &&
 164        test_config pull.rebase false &&
 165        git pull . copy &&
 166        test "$(git rev-parse HEAD^1)" = "$(git rev-parse before-preserve-rebase)" &&
 167        test "$(git rev-parse HEAD^2)" = "$(git rev-parse copy)" &&
 168        test file3 = "$(git show HEAD:file3.t)"
 169'
 170
 171test_expect_success 'pull.rebase=true flattens keep-merge' '
 172        git reset --hard before-preserve-rebase &&
 173        test_config pull.rebase true &&
 174        git pull . copy &&
 175        test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
 176        test file3 = "$(git show HEAD:file3.t)"
 177'
 178
 179test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' '
 180        git reset --hard before-preserve-rebase &&
 181        test_config pull.rebase 1 &&
 182        git pull . copy &&
 183        test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
 184        test file3 = "$(git show HEAD:file3.t)"
 185'
 186
 187test_expect_success 'pull.rebase=preserve rebases and merges keep-merge' '
 188        git reset --hard before-preserve-rebase &&
 189        test_config pull.rebase preserve &&
 190        git pull . copy &&
 191        test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
 192        test "$(git rev-parse HEAD^2)" = "$(git rev-parse keep-merge)"
 193'
 194
 195test_expect_success 'pull.rebase=invalid fails' '
 196        git reset --hard before-preserve-rebase &&
 197        test_config pull.rebase invalid &&
 198        ! git pull . copy
 199'
 200
 201test_expect_success '--rebase=false create a new merge commit' '
 202        git reset --hard before-preserve-rebase &&
 203        test_config pull.rebase true &&
 204        git pull --rebase=false . copy &&
 205        test "$(git rev-parse HEAD^1)" = "$(git rev-parse before-preserve-rebase)" &&
 206        test "$(git rev-parse HEAD^2)" = "$(git rev-parse copy)" &&
 207        test file3 = "$(git show HEAD:file3.t)"
 208'
 209
 210test_expect_success '--rebase=true rebases and flattens keep-merge' '
 211        git reset --hard before-preserve-rebase &&
 212        test_config pull.rebase preserve &&
 213        git pull --rebase=true . copy &&
 214        test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
 215        test file3 = "$(git show HEAD:file3.t)"
 216'
 217
 218test_expect_success '--rebase=preserve rebases and merges keep-merge' '
 219        git reset --hard before-preserve-rebase &&
 220        test_config pull.rebase true &&
 221        git pull --rebase=preserve . copy &&
 222        test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
 223        test "$(git rev-parse HEAD^2)" = "$(git rev-parse keep-merge)"
 224'
 225
 226test_expect_success '--rebase=invalid fails' '
 227        git reset --hard before-preserve-rebase &&
 228        ! git pull --rebase=invalid . copy
 229'
 230
 231test_expect_success '--rebase overrides pull.rebase=preserve and flattens keep-merge' '
 232        git reset --hard before-preserve-rebase &&
 233        test_config pull.rebase preserve &&
 234        git pull --rebase . copy &&
 235        test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
 236        test file3 = "$(git show HEAD:file3.t)"
 237'
 238
 239test_expect_success '--rebase with rebased upstream' '
 240
 241        git remote add -f me . &&
 242        git checkout copy &&
 243        git tag copy-orig &&
 244        git reset --hard HEAD^ &&
 245        echo conflicting modification > file &&
 246        git commit -m conflict file &&
 247        git checkout to-rebase &&
 248        echo file > file2 &&
 249        git commit -m to-rebase file2 &&
 250        git tag to-rebase-orig &&
 251        git pull --rebase me copy &&
 252        test "conflicting modification" = "$(cat file)" &&
 253        test file = "$(cat file2)"
 254
 255'
 256
 257test_expect_success '--rebase with rebased default upstream' '
 258
 259        git update-ref refs/remotes/me/copy copy-orig &&
 260        git checkout --track -b to-rebase2 me/copy &&
 261        git reset --hard to-rebase-orig &&
 262        git pull --rebase &&
 263        test "conflicting modification" = "$(cat file)" &&
 264        test file = "$(cat file2)"
 265
 266'
 267
 268test_expect_success 'rebased upstream + fetch + pull --rebase' '
 269
 270        git update-ref refs/remotes/me/copy copy-orig &&
 271        git reset --hard to-rebase-orig &&
 272        git checkout --track -b to-rebase3 me/copy &&
 273        git reset --hard to-rebase-orig &&
 274        git fetch &&
 275        git pull --rebase &&
 276        test "conflicting modification" = "$(cat file)" &&
 277        test file = "$(cat file2)"
 278
 279'
 280
 281test_expect_success 'pull --rebase dies early with dirty working directory' '
 282
 283        git checkout to-rebase &&
 284        git update-ref refs/remotes/me/copy copy^ &&
 285        COPY="$(git rev-parse --verify me/copy)" &&
 286        git rebase --onto $COPY copy &&
 287        test_config branch.to-rebase.remote me &&
 288        test_config branch.to-rebase.merge refs/heads/copy &&
 289        test_config branch.to-rebase.rebase true &&
 290        echo dirty >> file &&
 291        git add file &&
 292        test_must_fail git pull &&
 293        test "$COPY" = "$(git rev-parse --verify me/copy)" &&
 294        git checkout HEAD -- file &&
 295        git pull &&
 296        test "$COPY" != "$(git rev-parse --verify me/copy)"
 297
 298'
 299
 300test_expect_success 'pull --rebase works on branch yet to be born' '
 301        git rev-parse master >expect &&
 302        mkdir empty_repo &&
 303        (cd empty_repo &&
 304         git init &&
 305         git pull --rebase .. master &&
 306         git rev-parse HEAD >../actual
 307        ) &&
 308        test_cmp expect actual
 309'
 310
 311test_expect_success 'setup for detecting upstreamed changes' '
 312        mkdir src &&
 313        (cd src &&
 314         git init &&
 315         printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" > stuff &&
 316         git add stuff &&
 317         git commit -m "Initial revision"
 318        ) &&
 319        git clone src dst &&
 320        (cd src &&
 321         modify s/5/43/ stuff &&
 322         git commit -a -m "5->43" &&
 323         modify s/6/42/ stuff &&
 324         git commit -a -m "Make it bigger"
 325        ) &&
 326        (cd dst &&
 327         modify s/5/43/ stuff &&
 328         git commit -a -m "Independent discovery of 5->43"
 329        )
 330'
 331
 332test_expect_success 'git pull --rebase detects upstreamed changes' '
 333        (cd dst &&
 334         git pull --rebase &&
 335         test -z "$(git ls-files -u)"
 336        )
 337'
 338
 339test_expect_success 'setup for avoiding reapplying old patches' '
 340        (cd dst &&
 341         test_might_fail git rebase --abort &&
 342         git reset --hard origin/master
 343        ) &&
 344        git clone --bare src src-replace.git &&
 345        rm -rf src &&
 346        mv src-replace.git src &&
 347        (cd dst &&
 348         modify s/2/22/ stuff &&
 349         git commit -a -m "Change 2" &&
 350         modify s/3/33/ stuff &&
 351         git commit -a -m "Change 3" &&
 352         modify s/4/44/ stuff &&
 353         git commit -a -m "Change 4" &&
 354         git push &&
 355
 356         modify s/44/55/ stuff &&
 357         git commit --amend -a -m "Modified Change 4"
 358        )
 359'
 360
 361test_expect_success 'git pull --rebase does not reapply old patches' '
 362        (cd dst &&
 363         test_must_fail git pull --rebase &&
 364         test 1 = $(find .git/rebase-apply -name "000*" | wc -l)
 365        )
 366'
 367
 368test_expect_success 'git pull --rebase against local branch' '
 369        git checkout -b copy2 to-rebase-orig &&
 370        git pull --rebase . to-rebase &&
 371        test "conflicting modification" = "$(cat file)" &&
 372        test file = "$(cat file2)"
 373'
 374
 375test_done