t / t7405-submodule-merge.shon commit Implement automatic fast-forward merge for submodules (68d03e4)
   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#   a     d
  62#    \   /
  63#      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 add sub &&
  80        git commit -m "a" &&
  81        git branch a &&
  82
  83        git checkout -b b &&
  84        (cd sub &&
  85         git checkout -b sub-b &&
  86         echo "file-b" > file-b &&
  87         git add file-b &&
  88         git commit -m "sub-b") &&
  89        git commit -a -m "b" &&
  90
  91        git checkout -b c a &&
  92        (cd sub &&
  93         git checkout -b sub-c sub-a &&
  94         echo "file-c" > file-c &&
  95         git add file-c &&
  96         git commit -m "sub-c") &&
  97        git commit -a -m "c" &&
  98
  99        git checkout -b d a &&
 100        (cd sub &&
 101         git checkout -b sub-d sub-b &&
 102         git merge sub-c) &&
 103        git commit -a -m "d" &&
 104        git branch test b &&
 105        cd ..
 106'
 107
 108test_expect_success 'merge with one side as a fast-forward of the other' '
 109        (cd merge-search &&
 110         git checkout -b test-forward b &&
 111         git merge d &&
 112         git ls-tree test-forward sub | cut -f1 | cut -f3 -d" " > actual &&
 113         (cd sub &&
 114          git rev-parse sub-d > ../expect) &&
 115         test_cmp actual expect)
 116'
 117
 118test_expect_success 'merging should conflict for non fast-forward' '
 119        (cd merge-search &&
 120         git checkout -b test-nonforward b &&
 121         (cd sub &&
 122          git rev-parse sub-d > ../expect) &&
 123         test_must_fail git merge c 2> actual  &&
 124         grep $(cat expect) actual > /dev/null &&
 125         git reset --hard)
 126'
 127
 128test_expect_success 'merging should fail for ambiguous common parent' '
 129        cd merge-search &&
 130        git checkout -b test-ambiguous b &&
 131        (cd sub &&
 132         git checkout -b ambiguous sub-b &&
 133         git merge sub-c &&
 134         git rev-parse sub-d > ../expect1 &&
 135         git rev-parse ambiguous > ../expect2) &&
 136        test_must_fail git merge c 2> actual &&
 137        grep $(cat expect1) actual > /dev/null &&
 138        grep $(cat expect2) actual > /dev/null &&
 139        git reset --hard &&
 140        cd ..
 141'
 142
 143# in a situation like this
 144#
 145# submodule tree:
 146#
 147#    sub-a --- sub-b --- sub-d
 148#
 149# main tree:
 150#
 151#    e (sub-a)
 152#   /
 153#  bb (sub-b)
 154#   \
 155#    f (sub-d)
 156#
 157# A merge between e and f should fail because one of the submodule
 158# commits (sub-a) does not descend from the submodule merge-base (sub-b).
 159#
 160test_expect_success 'merging should fail for changes that are backwards' '
 161        cd merge-search &&
 162        git checkout -b bb a &&
 163        (cd sub &&
 164         git checkout sub-b) &&
 165        git commit -a -m "bb" &&
 166
 167        git checkout -b e bb &&
 168        (cd sub &&
 169         git checkout sub-a) &&
 170        git commit -a -m "e" &&
 171
 172        git checkout -b f bb &&
 173        (cd sub &&
 174         git checkout sub-d) &&
 175        git commit -a -m "f" &&
 176
 177        git checkout -b test-backward e &&
 178        test_must_fail git merge f &&
 179        cd ..
 180'
 181
 182test_expect_success 'merging with a modify/modify conflict between merge bases' '
 183
 184        git reset --hard HEAD &&
 185        git checkout -b test2 c &&
 186        git merge d
 187
 188'
 189
 190test_done