t / t7405-submodule-merge.shon commit Merge branch 'js/test-with-ws-in-path' (91ec08a)
   1#!/bin/sh
   2
   3test_description='merging with submodules'
   4
   5. ./test-lib.sh
   6
   7#
   8# history
   9#
  10#        a --- c
  11#      /   \ /
  12# root      X
  13#      \   / \
  14#        b --- d
  15#
  16
  17test_expect_success setup '
  18
  19        mkdir sub &&
  20        (cd sub &&
  21         git init &&
  22         echo original > file &&
  23         git add file &&
  24         test_tick &&
  25         git commit -m sub-root) &&
  26        git add sub &&
  27        test_tick &&
  28        git commit -m root &&
  29
  30        git checkout -b a master &&
  31        (cd sub &&
  32         echo A > file &&
  33         git add file &&
  34         test_tick &&
  35         git commit -m sub-a) &&
  36        git add sub &&
  37        test_tick &&
  38        git commit -m a &&
  39
  40        git checkout -b b master &&
  41        (cd sub &&
  42         echo B > file &&
  43         git add file &&
  44         test_tick &&
  45         git commit -m sub-b) &&
  46        git add sub &&
  47        test_tick &&
  48        git commit -m b &&
  49
  50        git checkout -b c a &&
  51        git merge -s ours b &&
  52
  53        git checkout -b d b &&
  54        git merge -s ours a
  55'
  56
  57# History setup
  58#
  59#             b
  60#           /   \
  61#  init -- a     d
  62#    \      \   /
  63#     g       c
  64#
  65# a in the main repository records to sub-a in the submodule and
  66# analogous b and c. d should be automatically found by merging c into
  67# b in the main repository.
  68test_expect_success 'setup for merge search' '
  69        mkdir merge-search &&
  70        (cd merge-search &&
  71        git init &&
  72        mkdir sub &&
  73        (cd sub &&
  74         git init &&
  75         echo "file-a" > file-a &&
  76         git add file-a &&
  77         git commit -m "sub-a" &&
  78         git branch sub-a) &&
  79        git commit --allow-empty -m init &&
  80        git branch init &&
  81        git add sub &&
  82        git commit -m "a" &&
  83        git branch a &&
  84
  85        git checkout -b b &&
  86        (cd sub &&
  87         git checkout -b sub-b &&
  88         echo "file-b" > file-b &&
  89         git add file-b &&
  90         git commit -m "sub-b") &&
  91        git commit -a -m "b" &&
  92
  93        git checkout -b c a &&
  94        (cd sub &&
  95         git checkout -b sub-c sub-a &&
  96         echo "file-c" > file-c &&
  97         git add file-c &&
  98         git commit -m "sub-c") &&
  99        git commit -a -m "c" &&
 100
 101        git checkout -b d a &&
 102        (cd sub &&
 103         git checkout -b sub-d sub-b &&
 104         git merge sub-c) &&
 105        git commit -a -m "d" &&
 106        git branch test b &&
 107
 108        git checkout -b g init &&
 109        (cd sub &&
 110         git checkout -b sub-g sub-c) &&
 111        git add sub &&
 112        git commit -a -m "g")
 113'
 114
 115test_expect_success 'merge with one side as a fast-forward of the other' '
 116        (cd merge-search &&
 117         git checkout -b test-forward b &&
 118         git merge d &&
 119         git ls-tree test-forward sub | cut -f1 | cut -f3 -d" " > actual &&
 120         (cd sub &&
 121          git rev-parse sub-d > ../expect) &&
 122         test_cmp expect actual)
 123'
 124
 125test_expect_success 'merging should conflict for non fast-forward' '
 126        (cd merge-search &&
 127         git checkout -b test-nonforward b &&
 128         (cd sub &&
 129          git rev-parse sub-d > ../expect) &&
 130         test_must_fail git merge c 2> actual  &&
 131         grep $(cat expect) actual > /dev/null &&
 132         git reset --hard)
 133'
 134
 135test_expect_success 'merging should fail for ambiguous common parent' '
 136        (cd merge-search &&
 137        git checkout -b test-ambiguous b &&
 138        (cd sub &&
 139         git checkout -b ambiguous sub-b &&
 140         git merge sub-c &&
 141         git rev-parse sub-d > ../expect1 &&
 142         git rev-parse ambiguous > ../expect2) &&
 143        test_must_fail git merge c 2> actual &&
 144        grep $(cat expect1) actual > /dev/null &&
 145        grep $(cat expect2) actual > /dev/null &&
 146        git reset --hard)
 147'
 148
 149# in a situation like this
 150#
 151# submodule tree:
 152#
 153#    sub-a --- sub-b --- sub-d
 154#
 155# main tree:
 156#
 157#    e (sub-a)
 158#   /
 159#  bb (sub-b)
 160#   \
 161#    f (sub-d)
 162#
 163# A merge between e and f should fail because one of the submodule
 164# commits (sub-a) does not descend from the submodule merge-base (sub-b).
 165#
 166test_expect_success 'merging should fail for changes that are backwards' '
 167        (cd merge-search &&
 168        git checkout -b bb a &&
 169        (cd sub &&
 170         git checkout sub-b) &&
 171        git commit -a -m "bb" &&
 172
 173        git checkout -b e bb &&
 174        (cd sub &&
 175         git checkout sub-a) &&
 176        git commit -a -m "e" &&
 177
 178        git checkout -b f bb &&
 179        (cd sub &&
 180         git checkout sub-d) &&
 181        git commit -a -m "f" &&
 182
 183        git checkout -b test-backward e &&
 184        test_must_fail git merge f)
 185'
 186
 187
 188# Check that the conflicting submodule is detected when it is
 189# in the common ancestor. status should be 'U00...00"
 190test_expect_success 'git submodule status should display the merge conflict properly with merge base' '
 191       (cd merge-search &&
 192       cat >.gitmodules <<EOF &&
 193[submodule "sub"]
 194       path = sub
 195       url = $TRASH_DIRECTORY/sub
 196EOF
 197       cat >expect <<EOF &&
 198U0000000000000000000000000000000000000000 sub
 199EOF
 200       git submodule status > actual &&
 201       test_cmp expect actual &&
 202        git reset --hard)
 203'
 204
 205# Check that the conflicting submodule is detected when it is
 206# not in the common ancestor. status should be 'U00...00"
 207test_expect_success 'git submodule status should display the merge conflict properly without merge-base' '
 208       (cd merge-search &&
 209        git checkout -b test-no-merge-base g &&
 210        test_must_fail git merge b &&
 211       cat >.gitmodules <<EOF &&
 212[submodule "sub"]
 213       path = sub
 214       url = $TRASH_DIRECTORY/sub
 215EOF
 216       cat >expect <<EOF &&
 217U0000000000000000000000000000000000000000 sub
 218EOF
 219       git submodule status > actual &&
 220       test_cmp expect actual &&
 221       git reset --hard)
 222'
 223
 224
 225test_expect_success 'merging with a modify/modify conflict between merge bases' '
 226        git reset --hard HEAD &&
 227        git checkout -b test2 c &&
 228        git merge d
 229'
 230
 231# canonical criss-cross history in top and submodule
 232test_expect_success 'setup for recursive merge with submodule' '
 233        mkdir merge-recursive &&
 234        (cd merge-recursive &&
 235         git init &&
 236         mkdir sub &&
 237         (cd sub &&
 238          git init &&
 239          test_commit a &&
 240          git checkout -b sub-b master &&
 241          test_commit b &&
 242          git checkout -b sub-c master &&
 243          test_commit c &&
 244          git checkout -b sub-bc sub-b &&
 245          git merge sub-c &&
 246          git checkout -b sub-cb sub-c &&
 247          git merge sub-b &&
 248          git checkout master) &&
 249         git add sub &&
 250         git commit -m a &&
 251         git checkout -b top-b master &&
 252         (cd sub && git checkout sub-b) &&
 253         git add sub &&
 254         git commit -m b &&
 255         git checkout -b top-c master &&
 256         (cd sub && git checkout sub-c) &&
 257         git add sub &&
 258         git commit -m c &&
 259         git checkout -b top-bc top-b &&
 260         git merge -s ours --no-commit top-c &&
 261         (cd sub && git checkout sub-bc) &&
 262         git add sub &&
 263         git commit -m bc &&
 264         git checkout -b top-cb top-c &&
 265         git merge -s ours --no-commit top-b &&
 266         (cd sub && git checkout sub-cb) &&
 267         git add sub &&
 268         git commit -m cb)
 269'
 270
 271# merge should leave submodule unmerged in index
 272test_expect_success 'recursive merge with submodule' '
 273        (cd merge-recursive &&
 274         test_must_fail git merge top-bc &&
 275         echo "160000 $(git rev-parse top-cb:sub) 2     sub" > expect2 &&
 276         echo "160000 $(git rev-parse top-bc:sub) 3     sub" > expect3 &&
 277         git ls-files -u > actual &&
 278         grep "$(cat expect2)" actual > /dev/null &&
 279         grep "$(cat expect3)" actual > /dev/null)
 280'
 281
 282test_done