b4656674456619b074532af531a4a66b5cc69cb0
   1#!/bin/sh
   2
   3test_description="recursive merge corner cases w/ renames but not criss-crosses"
   4# t6036 has corner cases that involve both criss-cross merges and renames
   5
   6. ./test-lib.sh
   7
   8test_expect_success 'setup rename/delete + untracked file' '
   9        echo "A pretty inscription" >ring &&
  10        git add ring &&
  11        test_tick &&
  12        git commit -m beginning &&
  13
  14        git branch people &&
  15        git checkout -b rename-the-ring &&
  16        git mv ring one-ring-to-rule-them-all &&
  17        test_tick &&
  18        git commit -m fullname &&
  19
  20        git checkout people &&
  21        git rm ring &&
  22        echo gollum >owner &&
  23        git add owner &&
  24        test_tick &&
  25        git commit -m track-people-instead-of-objects &&
  26        echo "Myyy PRECIOUSSS" >ring
  27'
  28
  29test_expect_failure "Does git preserve Gollum's precious artifact?" '
  30        test_must_fail git merge -s recursive rename-the-ring &&
  31
  32        # Make sure git did not delete an untracked file
  33        test -f ring
  34'
  35
  36# Testcase setup for rename/modify/add-source:
  37#   Commit A: new file: a
  38#   Commit B: modify a slightly
  39#   Commit C: rename a->b, add completely different a
  40#
  41# We should be able to merge B & C cleanly
  42
  43test_expect_success 'setup rename/modify/add-source conflict' '
  44        git rm -rf . &&
  45        git clean -fdqx &&
  46        rm -rf .git &&
  47        git init &&
  48
  49        printf "1\n2\n3\n4\n5\n6\n7\n" >a &&
  50        git add a &&
  51        git commit -m A &&
  52        git tag A &&
  53
  54        git checkout -b B A &&
  55        echo 8 >>a &&
  56        git add a &&
  57        git commit -m B &&
  58
  59        git checkout -b C A &&
  60        git mv a b &&
  61        echo something completely different >a &&
  62        git add a &&
  63        git commit -m C
  64'
  65
  66test_expect_failure 'rename/modify/add-source conflict resolvable' '
  67        git checkout B^0 &&
  68
  69        git merge -s recursive C^0 &&
  70
  71        test $(git rev-parse B:a) = $(git rev-parse b) &&
  72        test $(git rev-parse C:a) = $(git rev-parse a)
  73'
  74
  75test_expect_success 'setup resolvable conflict missed if rename missed' '
  76        git rm -rf . &&
  77        git clean -fdqx &&
  78        rm -rf .git &&
  79        git init &&
  80
  81        printf "1\n2\n3\n4\n5\n" >a &&
  82        echo foo >b &&
  83        git add a b &&
  84        git commit -m A &&
  85        git tag A &&
  86
  87        git checkout -b B A &&
  88        git mv a c &&
  89        echo "Completely different content" >a &&
  90        git add a &&
  91        git commit -m B &&
  92
  93        git checkout -b C A &&
  94        echo 6 >>a &&
  95        git add a &&
  96        git commit -m C
  97'
  98
  99test_expect_failure 'conflict caused if rename not detected' '
 100        git checkout -q C^0 &&
 101        git merge -s recursive B^0 &&
 102
 103        test 3 -eq $(git ls-files -s | wc -l) &&
 104        test 0 -eq $(git ls-files -u | wc -l) &&
 105        test 0 -eq $(git ls-files -o | wc -l) &&
 106
 107        test 6 -eq $(wc -l < c) &&
 108        test $(git rev-parse HEAD:a) = $(git rev-parse B:a) &&
 109        test $(git rev-parse HEAD:b) = $(git rev-parse A:b)
 110'
 111
 112test_expect_success 'setup conflict resolved wrong if rename missed' '
 113        git reset --hard &&
 114        git clean -f &&
 115
 116        git checkout -b D A &&
 117        echo 7 >>a &&
 118        git add a &&
 119        git mv a c &&
 120        echo "Completely different content" >a &&
 121        git add a &&
 122        git commit -m D &&
 123
 124        git checkout -b E A &&
 125        git rm a &&
 126        echo "Completely different content" >>a &&
 127        git add a &&
 128        git commit -m E
 129'
 130
 131test_expect_failure 'missed conflict if rename not detected' '
 132        git checkout -q E^0 &&
 133        test_must_fail git merge -s recursive D^0
 134'
 135
 136# Tests for undetected rename/add-source causing a file to erroneously be
 137# deleted (and for mishandled rename/rename(1to1) causing the same issue).
 138#
 139# This test uses a rename/rename(1to1)+add-source conflict (1to1 means the
 140# same file is renamed on both sides to the same thing; it should trigger
 141# the 1to2 logic, which it would do if the add-source didn't cause issues
 142# for git's rename detection):
 143#   Commit A: new file: a
 144#   Commit B: rename a->b
 145#   Commit C: rename a->b, add unrelated a
 146
 147test_expect_success 'setup undetected rename/add-source causes data loss' '
 148        git rm -rf . &&
 149        git clean -fdqx &&
 150        rm -rf .git &&
 151        git init &&
 152
 153        printf "1\n2\n3\n4\n5\n" >a &&
 154        git add a &&
 155        git commit -m A &&
 156        git tag A &&
 157
 158        git checkout -b B A &&
 159        git mv a b &&
 160        git commit -m B &&
 161
 162        git checkout -b C A &&
 163        git mv a b &&
 164        echo foobar >a &&
 165        git add a &&
 166        git commit -m C
 167'
 168
 169test_expect_failure 'detect rename/add-source and preserve all data' '
 170        git checkout B^0 &&
 171
 172        git merge -s recursive C^0 &&
 173
 174        test 2 -eq $(git ls-files -s | wc -l) &&
 175        test 2 -eq $(git ls-files -u | wc -l) &&
 176        test 0 -eq $(git ls-files -o | wc -l) &&
 177
 178        test -f a &&
 179        test -f b &&
 180
 181        test $(git rev-parse HEAD:b) = $(git rev-parse A:a) &&
 182        test $(git rev-parse HEAD:a) = $(git rev-parse C:a)
 183'
 184
 185test_expect_failure 'detect rename/add-source and preserve all data, merge other way' '
 186        git checkout C^0 &&
 187
 188        git merge -s recursive B^0 &&
 189
 190        test 2 -eq $(git ls-files -s | wc -l) &&
 191        test 2 -eq $(git ls-files -u | wc -l) &&
 192        test 0 -eq $(git ls-files -o | wc -l) &&
 193
 194        test -f a &&
 195        test -f b &&
 196
 197        test $(git rev-parse HEAD:b) = $(git rev-parse A:a) &&
 198        test $(git rev-parse HEAD:a) = $(git rev-parse C:a)
 199'
 200
 201test_expect_success 'setup content merge + rename/directory conflict' '
 202        git rm -rf . &&
 203        git clean -fdqx &&
 204        rm -rf .git &&
 205        git init &&
 206
 207        printf "1\n2\n3\n4\n5\n6\n" >file &&
 208        git add file &&
 209        test_tick &&
 210        git commit -m base &&
 211        git tag base &&
 212
 213        git checkout -b right &&
 214        echo 7 >>file &&
 215        mkdir newfile &&
 216        echo junk >newfile/realfile &&
 217        git add file newfile/realfile &&
 218        test_tick &&
 219        git commit -m right &&
 220
 221        git checkout -b left-conflict base &&
 222        echo 8 >>file &&
 223        git add file &&
 224        git mv file newfile &&
 225        test_tick &&
 226        git commit -m left &&
 227
 228        git checkout -b left-clean base &&
 229        echo 0 >newfile &&
 230        cat file >>newfile &&
 231        git add newfile &&
 232        git rm file &&
 233        test_tick &&
 234        git commit -m left
 235'
 236
 237test_expect_failure 'rename/directory conflict + clean content merge' '
 238        git reset --hard &&
 239        git reset --hard &&
 240        git clean -fdqx &&
 241
 242        git checkout left-clean^0 &&
 243
 244        test_must_fail git merge -s recursive right^0 &&
 245
 246        test 2 -eq $(git ls-files -s | wc -l) &&
 247        test 1 -eq $(git ls-files -u | wc -l) &&
 248        test 1 -eq $(git ls-files -o | wc -l) &&
 249
 250        echo 0 >expect &&
 251        git cat-file -p base:file >>expect &&
 252        echo 7 >>expect &&
 253        test_cmp expect newfile~HEAD &&
 254
 255        test $(git rev-parse :2:newfile) = $(git hash-object expect) &&
 256
 257        test -f newfile/realfile &&
 258        test -f newfile~HEAD
 259'
 260
 261test_expect_failure 'rename/directory conflict + content merge conflict' '
 262        git reset --hard &&
 263        git reset --hard &&
 264        git clean -fdqx &&
 265
 266        git checkout left-conflict^0 &&
 267
 268        test_must_fail git merge -s recursive right^0 &&
 269
 270        test 4 -eq $(git ls-files -s | wc -l) &&
 271        test 3 -eq $(git ls-files -u | wc -l) &&
 272        test 1 -eq $(git ls-files -o | wc -l) &&
 273
 274        git cat-file -p left-conflict:newfile >left &&
 275        git cat-file -p base:file    >base &&
 276        git cat-file -p right:file   >right &&
 277        test_must_fail git merge-file \
 278                -L "HEAD:newfile" \
 279                -L "" \
 280                -L "right^0:file" \
 281                left base right &&
 282        test_cmp left newfile~HEAD &&
 283
 284        test $(git rev-parse :1:newfile) = $(git rev-parse base:file) &&
 285        test $(git rev-parse :2:newfile) = $(git rev-parse left-conflict:newfile) &&
 286        test $(git rev-parse :3:newfile) = $(git rev-parse right:file) &&
 287
 288        test -f newfile/realfile &&
 289        test -f newfile~HEAD
 290'
 291
 292test_expect_success 'setup content merge + rename/directory conflict w/ disappearing dir' '
 293        git reset --hard &&
 294        git rm -rf . &&
 295        git clean -fdqx &&
 296        rm -rf .git &&
 297        git init &&
 298
 299        mkdir sub &&
 300        printf "1\n2\n3\n4\n5\n6\n" >sub/file &&
 301        git add sub/file &&
 302        test_tick &&
 303        git commit -m base &&
 304        git tag base &&
 305
 306        git checkout -b right &&
 307        echo 7 >>sub/file &&
 308        git add sub/file &&
 309        test_tick &&
 310        git commit -m right &&
 311
 312        git checkout -b left base &&
 313        echo 0 >newfile &&
 314        cat sub/file >>newfile &&
 315        git rm sub/file &&
 316        mv newfile sub &&
 317        git add sub &&
 318        test_tick &&
 319        git commit -m left
 320'
 321
 322test_expect_success 'disappearing dir in rename/directory conflict handled' '
 323        git reset --hard &&
 324        git clean -fdqx &&
 325
 326        git checkout left^0 &&
 327
 328        git merge -s recursive right^0 &&
 329
 330        test 1 -eq $(git ls-files -s | wc -l) &&
 331        test 0 -eq $(git ls-files -u | wc -l) &&
 332        test 0 -eq $(git ls-files -o | wc -l) &&
 333
 334        echo 0 >expect &&
 335        git cat-file -p base:sub/file >>expect &&
 336        echo 7 >>expect &&
 337        test_cmp expect sub &&
 338
 339        test -f sub
 340'
 341
 342test_done