t / t6022-merge-rename.shon commit t6022: Add test combinations of {content conflict?, D/F conflict remains?} (af6e175)
   1#!/bin/sh
   2
   3test_description='Merge-recursive merging renames'
   4. ./test-lib.sh
   5
   6modify () {
   7        sed -e "$1" <"$2" >"$2.x" &&
   8        mv "$2.x" "$2"
   9}
  10
  11test_expect_success setup \
  12'
  13cat >A <<\EOF &&
  14a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
  15b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
  16c cccccccccccccccccccccccccccccccccccccccccccccccc
  17d dddddddddddddddddddddddddddddddddddddddddddddddd
  18e eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
  19f ffffffffffffffffffffffffffffffffffffffffffffffff
  20g gggggggggggggggggggggggggggggggggggggggggggggggg
  21h hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
  22i iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
  23j jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
  24k kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
  25l llllllllllllllllllllllllllllllllllllllllllllllll
  26m mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
  27n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
  28o oooooooooooooooooooooooooooooooooooooooooooooooo
  29EOF
  30
  31cat >M <<\EOF &&
  32A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  33B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
  34C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  35D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
  36E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
  37F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  38G GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
  39H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
  40I IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
  41J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
  42K KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
  43L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
  44M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  45N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  46O OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  47EOF
  48
  49git add A M &&
  50git commit -m "initial has A and M" &&
  51git branch white &&
  52git branch red &&
  53git branch blue &&
  54git branch yellow &&
  55git branch change &&
  56git branch change+rename &&
  57
  58sed -e "/^g /s/.*/g : master changes a line/" <A >A+ &&
  59mv A+ A &&
  60git commit -a -m "master updates A" &&
  61
  62git checkout yellow &&
  63rm -f M &&
  64git commit -a -m "yellow removes M" &&
  65
  66git checkout white &&
  67sed -e "/^g /s/.*/g : white changes a line/" <A >B &&
  68sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
  69rm -f A M &&
  70git update-index --add --remove A B M N &&
  71git commit -m "white renames A->B, M->N" &&
  72
  73git checkout red &&
  74sed -e "/^g /s/.*/g : red changes a line/" <A >B &&
  75sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
  76rm -f A M &&
  77git update-index --add --remove A B M N &&
  78git commit -m "red renames A->B, M->N" &&
  79
  80git checkout blue &&
  81sed -e "/^g /s/.*/g : blue changes a line/" <A >C &&
  82sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
  83rm -f A M &&
  84git update-index --add --remove A C M N &&
  85git commit -m "blue renames A->C, M->N" &&
  86
  87git checkout change &&
  88sed -e "/^g /s/.*/g : changed line/" <A >A+ &&
  89mv A+ A &&
  90git commit -q -a -m "changed" &&
  91
  92git checkout change+rename &&
  93sed -e "/^g /s/.*/g : changed line/" <A >B &&
  94rm A &&
  95git update-index --add B &&
  96git commit -q -a -m "changed and renamed" &&
  97
  98git checkout master'
  99
 100test_expect_success 'pull renaming branch into unrenaming one' \
 101'
 102        git show-branch
 103        git pull . white && {
 104                echo "BAD: should have conflicted"
 105                return 1
 106        }
 107        git ls-files -s
 108        test "$(git ls-files -u B | wc -l)" -eq 3 || {
 109                echo "BAD: should have left stages for B"
 110                return 1
 111        }
 112        test "$(git ls-files -s N | wc -l)" -eq 1 || {
 113                echo "BAD: should have merged N"
 114                return 1
 115        }
 116        sed -ne "/^g/{
 117        p
 118        q
 119        }" B | grep master || {
 120                echo "BAD: should have listed our change first"
 121                return 1
 122        }
 123        test "$(git diff white N | wc -l)" -eq 0 || {
 124                echo "BAD: should have taken colored branch"
 125                return 1
 126        }
 127'
 128
 129test_expect_success 'pull renaming branch into another renaming one' \
 130'
 131        rm -f B
 132        git reset --hard
 133        git checkout red
 134        git pull . white && {
 135                echo "BAD: should have conflicted"
 136                return 1
 137        }
 138        test "$(git ls-files -u B | wc -l)" -eq 3 || {
 139                echo "BAD: should have left stages"
 140                return 1
 141        }
 142        test "$(git ls-files -s N | wc -l)" -eq 1 || {
 143                echo "BAD: should have merged N"
 144                return 1
 145        }
 146        sed -ne "/^g/{
 147        p
 148        q
 149        }" B | grep red || {
 150                echo "BAD: should have listed our change first"
 151                return 1
 152        }
 153        test "$(git diff white N | wc -l)" -eq 0 || {
 154                echo "BAD: should have taken colored branch"
 155                return 1
 156        }
 157'
 158
 159test_expect_success 'pull unrenaming branch into renaming one' \
 160'
 161        git reset --hard
 162        git show-branch
 163        git pull . master && {
 164                echo "BAD: should have conflicted"
 165                return 1
 166        }
 167        test "$(git ls-files -u B | wc -l)" -eq 3 || {
 168                echo "BAD: should have left stages"
 169                return 1
 170        }
 171        test "$(git ls-files -s N | wc -l)" -eq 1 || {
 172                echo "BAD: should have merged N"
 173                return 1
 174        }
 175        sed -ne "/^g/{
 176        p
 177        q
 178        }" B | grep red || {
 179                echo "BAD: should have listed our change first"
 180                return 1
 181        }
 182        test "$(git diff white N | wc -l)" -eq 0 || {
 183                echo "BAD: should have taken colored branch"
 184                return 1
 185        }
 186'
 187
 188test_expect_success 'pull conflicting renames' \
 189'
 190        git reset --hard
 191        git show-branch
 192        git pull . blue && {
 193                echo "BAD: should have conflicted"
 194                return 1
 195        }
 196        test "$(git ls-files -u A | wc -l)" -eq 1 || {
 197                echo "BAD: should have left a stage"
 198                return 1
 199        }
 200        test "$(git ls-files -u B | wc -l)" -eq 1 || {
 201                echo "BAD: should have left a stage"
 202                return 1
 203        }
 204        test "$(git ls-files -u C | wc -l)" -eq 1 || {
 205                echo "BAD: should have left a stage"
 206                return 1
 207        }
 208        test "$(git ls-files -s N | wc -l)" -eq 1 || {
 209                echo "BAD: should have merged N"
 210                return 1
 211        }
 212        sed -ne "/^g/{
 213        p
 214        q
 215        }" B | grep red || {
 216                echo "BAD: should have listed our change first"
 217                return 1
 218        }
 219        test "$(git diff white N | wc -l)" -eq 0 || {
 220                echo "BAD: should have taken colored branch"
 221                return 1
 222        }
 223'
 224
 225test_expect_success 'interference with untracked working tree file' '
 226
 227        git reset --hard
 228        git show-branch
 229        echo >A this file should not matter
 230        git pull . white && {
 231                echo "BAD: should have conflicted"
 232                return 1
 233        }
 234        test -f A || {
 235                echo "BAD: should have left A intact"
 236                return 1
 237        }
 238'
 239
 240test_expect_success 'interference with untracked working tree file' '
 241
 242        git reset --hard
 243        git checkout white
 244        git show-branch
 245        rm -f A
 246        echo >A this file should not matter
 247        git pull . red && {
 248                echo "BAD: should have conflicted"
 249                return 1
 250        }
 251        test -f A || {
 252                echo "BAD: should have left A intact"
 253                return 1
 254        }
 255'
 256
 257test_expect_success 'interference with untracked working tree file' '
 258
 259        git reset --hard
 260        rm -f A M
 261        git checkout -f master
 262        git tag -f anchor
 263        git show-branch
 264        git pull . yellow || {
 265                echo "BAD: should have cleanly merged"
 266                return 1
 267        }
 268        test -f M && {
 269                echo "BAD: should have removed M"
 270                return 1
 271        }
 272        git reset --hard anchor
 273'
 274
 275test_expect_success 'updated working tree file should prevent the merge' '
 276
 277        git reset --hard
 278        rm -f A M
 279        git checkout -f master
 280        git tag -f anchor
 281        git show-branch
 282        echo >>M one line addition
 283        cat M >M.saved
 284        git pull . yellow && {
 285                echo "BAD: should have complained"
 286                return 1
 287        }
 288        test_cmp M M.saved || {
 289                echo "BAD: should have left M intact"
 290                return 1
 291        }
 292        rm -f M.saved
 293'
 294
 295test_expect_success 'updated working tree file should prevent the merge' '
 296
 297        git reset --hard
 298        rm -f A M
 299        git checkout -f master
 300        git tag -f anchor
 301        git show-branch
 302        echo >>M one line addition
 303        cat M >M.saved
 304        git update-index M
 305        git pull . yellow && {
 306                echo "BAD: should have complained"
 307                return 1
 308        }
 309        test_cmp M M.saved || {
 310                echo "BAD: should have left M intact"
 311                return 1
 312        }
 313        rm -f M.saved
 314'
 315
 316test_expect_success 'interference with untracked working tree file' '
 317
 318        git reset --hard
 319        rm -f A M
 320        git checkout -f yellow
 321        git tag -f anchor
 322        git show-branch
 323        echo >M this file should not matter
 324        git pull . master || {
 325                echo "BAD: should have cleanly merged"
 326                return 1
 327        }
 328        test -f M || {
 329                echo "BAD: should have left M intact"
 330                return 1
 331        }
 332        git ls-files -s | grep M && {
 333                echo "BAD: M must be untracked in the result"
 334                return 1
 335        }
 336        git reset --hard anchor
 337'
 338
 339test_expect_success 'merge of identical changes in a renamed file' '
 340        rm -f A M N
 341        git reset --hard &&
 342        git checkout change+rename &&
 343        GIT_MERGE_VERBOSITY=3 git merge change | grep "^Skipped B" &&
 344        git reset --hard HEAD^ &&
 345        git checkout change &&
 346        GIT_MERGE_VERBOSITY=3 git merge change+rename | grep "^Skipped B"
 347'
 348
 349test_expect_success 'setup for rename + d/f conflicts' '
 350        git reset --hard &&
 351        git checkout --orphan dir-in-way &&
 352        git rm -rf . &&
 353
 354        mkdir sub &&
 355        mkdir dir &&
 356        printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >sub/file &&
 357        echo foo >dir/file-in-the-way &&
 358        git add -A &&
 359        git commit -m "Common commmit" &&
 360
 361        echo 11 >>sub/file &&
 362        echo more >>dir/file-in-the-way &&
 363        git add -u &&
 364        git commit -m "Commit to merge, with dir in the way" &&
 365
 366        git checkout -b dir-not-in-way &&
 367        git reset --soft HEAD^ &&
 368        git rm -rf dir &&
 369        git commit -m "Commit to merge, with dir removed" -- dir sub/file &&
 370
 371        git checkout -b renamed-file-has-no-conflicts dir-in-way~1 &&
 372        git rm -rf dir &&
 373        git rm sub/file &&
 374        printf "1\n2\n3\n4\n5555\n6\n7\n8\n9\n10\n" >dir &&
 375        git add dir &&
 376        git commit -m "Independent change" &&
 377
 378        git checkout -b renamed-file-has-conflicts dir-in-way~1 &&
 379        git rm -rf dir &&
 380        git mv sub/file dir &&
 381        echo 12 >>dir &&
 382        git add dir &&
 383        git commit -m "Conflicting change"
 384'
 385
 386printf "1\n2\n3\n4\n5555\n6\n7\n8\n9\n10\n11\n" >expected
 387
 388test_expect_success 'Rename+D/F conflict; renamed file merges + dir not in way' '
 389        git reset --hard &&
 390        git checkout -q renamed-file-has-no-conflicts^0 &&
 391        git merge --strategy=recursive dir-not-in-way &&
 392        git diff --quiet &&
 393        test -f dir &&
 394        test_cmp expected dir
 395'
 396
 397test_expect_failure 'Rename+D/F conflict; renamed file merges but dir in way' '
 398        git reset --hard &&
 399        rm -rf dir~* &&
 400        git checkout -q renamed-file-has-no-conflicts^0 &&
 401        test_must_fail git merge --strategy=recursive dir-in-way >output &&
 402
 403        grep "CONFLICT (delete/modify): dir/file-in-the-way" output &&
 404        grep "Auto-merging dir" output &&
 405        grep "Adding as dir~HEAD instead" output &&
 406
 407        test 2 = "$(git ls-files -u | wc -l)" &&
 408        test 2 = "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
 409
 410        test_must_fail git diff --quiet &&
 411        test_must_fail git diff --cached --quiet &&
 412
 413        test -f dir/file-in-the-way &&
 414        test -f dir~HEAD &&
 415        test_cmp expected dir~HEAD
 416'
 417
 418cat >expected <<\EOF &&
 4191
 4202
 4213
 4224
 4235
 4246
 4257
 4268
 4279
 42810
 429<<<<<<< HEAD
 43012
 431=======
 43211
 433>>>>>>> dir-not-in-way
 434EOF
 435
 436test_expect_failure 'Rename+D/F conflict; renamed file cannot merge, dir not in way' '
 437        git reset --hard &&
 438        rm -rf dir~* &&
 439        git checkout -q renamed-file-has-conflicts^0 &&
 440        test_must_fail git merge --strategy=recursive dir-not-in-way &&
 441
 442        test 3 = "$(git ls-files -u | wc -l)" &&
 443        test 3 = "$(git ls-files -u dir | wc -l)" &&
 444
 445        test_must_fail git diff --quiet &&
 446        test_must_fail git diff --cached --quiet &&
 447
 448        test -f dir &&
 449        test_cmp expected dir
 450'
 451
 452test_expect_failure 'Rename+D/F conflict; renamed file cannot merge and dir in the way' '
 453        modify s/dir-not-in-way/dir-in-way/ expected &&
 454
 455        git reset --hard &&
 456        rm -rf dir~* &&
 457        git checkout -q renamed-file-has-conflicts^0 &&
 458        test_must_fail git merge --strategy=recursive dir-in-way &&
 459
 460        test 5 = "$(git ls-files -u | wc -l)" &&
 461        test 3 = "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" &&
 462        test 2 = "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
 463
 464        test_must_fail git diff --quiet &&
 465        test_must_fail git diff --cached --quiet &&
 466
 467        test -f dir/file-in-the-way &&
 468        test -f dir~HEAD &&
 469        test_cmp expected dir~HEAD
 470'
 471
 472test_done