t / t6022-merge-rename.shon commit unpack-trees.c: look ahead in the index (730f728)
   1#!/bin/sh
   2
   3test_description='Merge-recursive merging renames'
   4. ./test-lib.sh
   5
   6test_expect_success setup \
   7'
   8cat >A <<\EOF &&
   9a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
  10b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
  11c cccccccccccccccccccccccccccccccccccccccccccccccc
  12d dddddddddddddddddddddddddddddddddddddddddddddddd
  13e eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
  14f ffffffffffffffffffffffffffffffffffffffffffffffff
  15g gggggggggggggggggggggggggggggggggggggggggggggggg
  16h hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
  17i iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
  18j jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
  19k kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
  20l llllllllllllllllllllllllllllllllllllllllllllllll
  21m mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
  22n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
  23o oooooooooooooooooooooooooooooooooooooooooooooooo
  24EOF
  25
  26cat >M <<\EOF &&
  27A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  28B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
  29C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  30D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
  31E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
  32F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  33G GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
  34H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
  35I IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
  36J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
  37K KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
  38L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
  39M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  40N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  41O OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  42EOF
  43
  44git add A M &&
  45git commit -m "initial has A and M" &&
  46git branch white &&
  47git branch red &&
  48git branch blue &&
  49git branch yellow &&
  50git branch change &&
  51git branch change+rename &&
  52
  53sed -e "/^g /s/.*/g : master changes a line/" <A >A+ &&
  54mv A+ A &&
  55git commit -a -m "master updates A" &&
  56
  57git checkout yellow &&
  58rm -f M &&
  59git commit -a -m "yellow removes M" &&
  60
  61git checkout white &&
  62sed -e "/^g /s/.*/g : white changes a line/" <A >B &&
  63sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
  64rm -f A M &&
  65git update-index --add --remove A B M N &&
  66git commit -m "white renames A->B, M->N" &&
  67
  68git checkout red &&
  69sed -e "/^g /s/.*/g : red changes a line/" <A >B &&
  70sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
  71rm -f A M &&
  72git update-index --add --remove A B M N &&
  73git commit -m "red renames A->B, M->N" &&
  74
  75git checkout blue &&
  76sed -e "/^g /s/.*/g : blue changes a line/" <A >C &&
  77sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
  78rm -f A M &&
  79git update-index --add --remove A C M N &&
  80git commit -m "blue renames A->C, M->N" &&
  81
  82git checkout change &&
  83sed -e "/^g /s/.*/g : changed line/" <A >A+ &&
  84mv A+ A &&
  85git commit -q -a -m "changed" &&
  86
  87git checkout change+rename &&
  88sed -e "/^g /s/.*/g : changed line/" <A >B &&
  89rm A &&
  90git update-index --add B &&
  91git commit -q -a -m "changed and renamed" &&
  92
  93git checkout master'
  94
  95test_expect_success 'pull renaming branch into unrenaming one' \
  96'
  97        git show-branch
  98        git pull . white && {
  99                echo "BAD: should have conflicted"
 100                return 1
 101        }
 102        git ls-files -s
 103        test "$(git ls-files -u B | wc -l)" -eq 3 || {
 104                echo "BAD: should have left stages for B"
 105                return 1
 106        }
 107        test "$(git ls-files -s N | wc -l)" -eq 1 || {
 108                echo "BAD: should have merged N"
 109                return 1
 110        }
 111        sed -ne "/^g/{
 112        p
 113        q
 114        }" B | grep master || {
 115                echo "BAD: should have listed our change first"
 116                return 1
 117        }
 118        test "$(git diff white N | wc -l)" -eq 0 || {
 119                echo "BAD: should have taken colored branch"
 120                return 1
 121        }
 122'
 123
 124test_expect_success 'pull renaming branch into another renaming one' \
 125'
 126        rm -f B
 127        git reset --hard
 128        git checkout red
 129        git pull . white && {
 130                echo "BAD: should have conflicted"
 131                return 1
 132        }
 133        test "$(git ls-files -u B | wc -l)" -eq 3 || {
 134                echo "BAD: should have left stages"
 135                return 1
 136        }
 137        test "$(git ls-files -s N | wc -l)" -eq 1 || {
 138                echo "BAD: should have merged N"
 139                return 1
 140        }
 141        sed -ne "/^g/{
 142        p
 143        q
 144        }" B | grep red || {
 145                echo "BAD: should have listed our change first"
 146                return 1
 147        }
 148        test "$(git diff white N | wc -l)" -eq 0 || {
 149                echo "BAD: should have taken colored branch"
 150                return 1
 151        }
 152'
 153
 154test_expect_success 'pull unrenaming branch into renaming one' \
 155'
 156        git reset --hard
 157        git show-branch
 158        git pull . master && {
 159                echo "BAD: should have conflicted"
 160                return 1
 161        }
 162        test "$(git ls-files -u B | wc -l)" -eq 3 || {
 163                echo "BAD: should have left stages"
 164                return 1
 165        }
 166        test "$(git ls-files -s N | wc -l)" -eq 1 || {
 167                echo "BAD: should have merged N"
 168                return 1
 169        }
 170        sed -ne "/^g/{
 171        p
 172        q
 173        }" B | grep red || {
 174                echo "BAD: should have listed our change first"
 175                return 1
 176        }
 177        test "$(git diff white N | wc -l)" -eq 0 || {
 178                echo "BAD: should have taken colored branch"
 179                return 1
 180        }
 181'
 182
 183test_expect_success 'pull conflicting renames' \
 184'
 185        git reset --hard
 186        git show-branch
 187        git pull . blue && {
 188                echo "BAD: should have conflicted"
 189                return 1
 190        }
 191        test "$(git ls-files -u A | wc -l)" -eq 1 || {
 192                echo "BAD: should have left a stage"
 193                return 1
 194        }
 195        test "$(git ls-files -u B | wc -l)" -eq 1 || {
 196                echo "BAD: should have left a stage"
 197                return 1
 198        }
 199        test "$(git ls-files -u C | wc -l)" -eq 1 || {
 200                echo "BAD: should have left a stage"
 201                return 1
 202        }
 203        test "$(git ls-files -s N | wc -l)" -eq 1 || {
 204                echo "BAD: should have merged N"
 205                return 1
 206        }
 207        sed -ne "/^g/{
 208        p
 209        q
 210        }" B | grep red || {
 211                echo "BAD: should have listed our change first"
 212                return 1
 213        }
 214        test "$(git diff white N | wc -l)" -eq 0 || {
 215                echo "BAD: should have taken colored branch"
 216                return 1
 217        }
 218'
 219
 220test_expect_success 'interference with untracked working tree file' '
 221
 222        git reset --hard
 223        git show-branch
 224        echo >A this file should not matter
 225        git pull . white && {
 226                echo "BAD: should have conflicted"
 227                return 1
 228        }
 229        test -f A || {
 230                echo "BAD: should have left A intact"
 231                return 1
 232        }
 233'
 234
 235test_expect_success 'interference with untracked working tree file' '
 236
 237        git reset --hard
 238        git checkout white
 239        git show-branch
 240        rm -f A
 241        echo >A this file should not matter
 242        git pull . red && {
 243                echo "BAD: should have conflicted"
 244                return 1
 245        }
 246        test -f A || {
 247                echo "BAD: should have left A intact"
 248                return 1
 249        }
 250'
 251
 252test_expect_success 'interference with untracked working tree file' '
 253
 254        git reset --hard
 255        rm -f A M
 256        git checkout -f master
 257        git tag -f anchor
 258        git show-branch
 259        git pull . yellow || {
 260                echo "BAD: should have cleanly merged"
 261                return 1
 262        }
 263        test -f M && {
 264                echo "BAD: should have removed M"
 265                return 1
 266        }
 267        git reset --hard anchor
 268'
 269
 270test_expect_success 'updated working tree file should prevent the merge' '
 271
 272        git reset --hard
 273        rm -f A M
 274        git checkout -f master
 275        git tag -f anchor
 276        git show-branch
 277        echo >>M one line addition
 278        cat M >M.saved
 279        git pull . yellow && {
 280                echo "BAD: should have complained"
 281                return 1
 282        }
 283        diff M M.saved || {
 284                echo "BAD: should have left M intact"
 285                return 1
 286        }
 287        rm -f M.saved
 288'
 289
 290test_expect_success 'updated working tree file should prevent the merge' '
 291
 292        git reset --hard
 293        rm -f A M
 294        git checkout -f master
 295        git tag -f anchor
 296        git show-branch
 297        echo >>M one line addition
 298        cat M >M.saved
 299        git update-index M
 300        git pull . yellow && {
 301                echo "BAD: should have complained"
 302                return 1
 303        }
 304        diff M M.saved || {
 305                echo "BAD: should have left M intact"
 306                return 1
 307        }
 308        rm -f M.saved
 309'
 310
 311test_expect_success 'interference with untracked working tree file' '
 312
 313        git reset --hard
 314        rm -f A M
 315        git checkout -f yellow
 316        git tag -f anchor
 317        git show-branch
 318        echo >M this file should not matter
 319        git pull . master || {
 320                echo "BAD: should have cleanly merged"
 321                return 1
 322        }
 323        test -f M || {
 324                echo "BAD: should have left M intact"
 325                return 1
 326        }
 327        git ls-files -s | grep M && {
 328                echo "BAD: M must be untracked in the result"
 329                return 1
 330        }
 331        git reset --hard anchor
 332'
 333
 334test_expect_success 'merge of identical changes in a renamed file' '
 335        rm -f A M N
 336        git reset --hard &&
 337        git checkout change+rename &&
 338        GIT_MERGE_VERBOSITY=3 git merge change | grep "^Skipped B" &&
 339        git reset --hard HEAD^ &&
 340        git checkout change &&
 341        GIT_MERGE_VERBOSITY=3 git merge change+rename | grep "^Skipped B"
 342'
 343
 344test_done