(CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(DQ ('recursive merge corner cases w/ renames but not criss-crosses'))} spids: [4] ) ] spids: [4] ) (C {(.)} {(./test-lib.sh)}) (C {(test_expect_success)} {(SQ <'setup rename/delete + untracked file'>)} { (SQ <'\n'> <'\techo "A pretty inscription" >ring &&\n'> <'\tgit add ring &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m beginning &&\n'> <'\n'> <'\tgit branch people &&\n'> <'\tgit checkout -b rename-the-ring &&\n'> <'\tgit mv ring one-ring-to-rule-them-all &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m fullname &&\n'> <'\n'> <'\tgit checkout people &&\n'> <'\tgit rm ring &&\n'> <'\techo gollum >owner &&\n'> <'\tgit add owner &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m track-people-instead-of-objects &&\n'> <'\techo "Myyy PRECIOUSSS" >ring\n'> ) } ) (C {(test_expect_success)} {(DQ ("Does git preserve Gollum's precious artifact?"))} { (SQ <'\n'> <'\ttest_must_fail git merge -s recursive rename-the-ring &&\n'> <'\n'> <'\t# Make sure git did not delete an untracked file\n'> <'\ttest -f ring\n'> ) } ) (C {(test_expect_success)} {(SQ <'setup rename/modify/add-source conflict'>)} { (SQ <'\n'> <'\tgit rm -rf . &&\n'> <'\tgit clean -fdqx &&\n'> <'\trm -rf .git &&\n'> <'\tgit init &&\n'> <'\n'> <'\tprintf "1\\n2\\n3\\n4\\n5\\n6\\n7\\n" >a &&\n'> <'\tgit add a &&\n'> <'\tgit commit -m A &&\n'> <'\tgit tag A &&\n'> <'\n'> <'\tgit checkout -b B A &&\n'> <'\techo 8 >>a &&\n'> <'\tgit add a &&\n'> <'\tgit commit -m B &&\n'> <'\n'> <'\tgit checkout -b C A &&\n'> <'\tgit mv a b &&\n'> <'\techo something completely different >a &&\n'> <'\tgit add a &&\n'> <'\tgit commit -m C\n'> ) } ) (C {(test_expect_failure)} {(SQ <'rename/modify/add-source conflict resolvable'>)} { (SQ <'\n'> <'\tgit checkout B^0 &&\n'> <'\n'> <'\tgit merge -s recursive C^0 &&\n'> <'\n'> <'\ttest $(git rev-parse B:a) = $(git rev-parse b) &&\n'> <'\ttest $(git rev-parse C:a) = $(git rev-parse a)\n'> ) } ) (C {(test_expect_success)} {(SQ <'setup resolvable conflict missed if rename missed'>)} { (SQ <'\n'> <'\tgit rm -rf . &&\n'> <'\tgit clean -fdqx &&\n'> <'\trm -rf .git &&\n'> <'\tgit init &&\n'> <'\n'> <'\tprintf "1\\n2\\n3\\n4\\n5\\n" >a &&\n'> <'\techo foo >b &&\n'> <'\tgit add a b &&\n'> <'\tgit commit -m A &&\n'> <'\tgit tag A &&\n'> <'\n'> <'\tgit checkout -b B A &&\n'> <'\tgit mv a c &&\n'> <'\techo "Completely different content" >a &&\n'> <'\tgit add a &&\n'> <'\tgit commit -m B &&\n'> <'\n'> <'\tgit checkout -b C A &&\n'> <'\techo 6 >>a &&\n'> <'\tgit add a &&\n'> <'\tgit commit -m C\n'> ) } ) (C {(test_expect_failure)} {(SQ <'conflict caused if rename not detected'>)} { (SQ <'\n'> <'\tgit checkout -q C^0 &&\n'> <'\tgit merge -s recursive B^0 &&\n'> <'\n'> <'\ttest 3 -eq $(git ls-files -s | wc -l) &&\n'> <'\ttest 0 -eq $(git ls-files -u | wc -l) &&\n'> <'\ttest 0 -eq $(git ls-files -o | wc -l) &&\n'> <'\n'> <'\ttest_line_count = 6 c &&\n'> <'\ttest $(git rev-parse HEAD:a) = $(git rev-parse B:a) &&\n'> <'\ttest $(git rev-parse HEAD:b) = $(git rev-parse A:b)\n'> ) } ) (C {(test_expect_success)} {(SQ <'setup conflict resolved wrong if rename missed'>)} { (SQ <'\n'> <'\tgit reset --hard &&\n'> <'\tgit clean -f &&\n'> <'\n'> <'\tgit checkout -b D A &&\n'> <'\techo 7 >>a &&\n'> <'\tgit add a &&\n'> <'\tgit mv a c &&\n'> <'\techo "Completely different content" >a &&\n'> <'\tgit add a &&\n'> <'\tgit commit -m D &&\n'> <'\n'> <'\tgit checkout -b E A &&\n'> <'\tgit rm a &&\n'> <'\techo "Completely different content" >>a &&\n'> <'\tgit add a &&\n'> <'\tgit commit -m E\n'> ) } ) (C {(test_expect_failure)} {(SQ <'missed conflict if rename not detected'>)} {(SQ <'\n'> <'\tgit checkout -q E^0 &&\n'> <'\ttest_must_fail git merge -s recursive D^0\n'>)} ) (C {(test_expect_success)} {(SQ <'setup undetected rename/add-source causes data loss'>)} { (SQ <'\n'> <'\tgit rm -rf . &&\n'> <'\tgit clean -fdqx &&\n'> <'\trm -rf .git &&\n'> <'\tgit init &&\n'> <'\n'> <'\tprintf "1\\n2\\n3\\n4\\n5\\n" >a &&\n'> <'\tgit add a &&\n'> <'\tgit commit -m A &&\n'> <'\tgit tag A &&\n'> <'\n'> <'\tgit checkout -b B A &&\n'> <'\tgit mv a b &&\n'> <'\tgit commit -m B &&\n'> <'\n'> <'\tgit checkout -b C A &&\n'> <'\tgit mv a b &&\n'> <'\techo foobar >a &&\n'> <'\tgit add a &&\n'> <'\tgit commit -m C\n'> ) } ) (C {(test_expect_failure)} {(SQ <'detect rename/add-source and preserve all data'>)} { (SQ <'\n'> <'\tgit checkout B^0 &&\n'> <'\n'> <'\tgit merge -s recursive C^0 &&\n'> <'\n'> <'\ttest 2 -eq $(git ls-files -s | wc -l) &&\n'> <'\ttest 2 -eq $(git ls-files -u | wc -l) &&\n'> <'\ttest 0 -eq $(git ls-files -o | wc -l) &&\n'> <'\n'> <'\ttest -f a &&\n'> <'\ttest -f b &&\n'> <'\n'> <'\ttest $(git rev-parse HEAD:b) = $(git rev-parse A:a) &&\n'> <'\ttest $(git rev-parse HEAD:a) = $(git rev-parse C:a)\n'> ) } ) (C {(test_expect_failure)} {(SQ <'detect rename/add-source and preserve all data, merge other way'>)} { (SQ <'\n'> <'\tgit checkout C^0 &&\n'> <'\n'> <'\tgit merge -s recursive B^0 &&\n'> <'\n'> <'\ttest 2 -eq $(git ls-files -s | wc -l) &&\n'> <'\ttest 2 -eq $(git ls-files -u | wc -l) &&\n'> <'\ttest 0 -eq $(git ls-files -o | wc -l) &&\n'> <'\n'> <'\ttest -f a &&\n'> <'\ttest -f b &&\n'> <'\n'> <'\ttest $(git rev-parse HEAD:b) = $(git rev-parse A:a) &&\n'> <'\ttest $(git rev-parse HEAD:a) = $(git rev-parse C:a)\n'> ) } ) (C {(test_expect_success)} {(SQ <'setup content merge + rename/directory conflict'>)} { (SQ <'\n'> <'\tgit rm -rf . &&\n'> <'\tgit clean -fdqx &&\n'> <'\trm -rf .git &&\n'> <'\tgit init &&\n'> <'\n'> <'\tprintf "1\\n2\\n3\\n4\\n5\\n6\\n" >file &&\n'> <'\tgit add file &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m base &&\n'> <'\tgit tag base &&\n'> <'\n'> <'\tgit checkout -b right &&\n'> <'\techo 7 >>file &&\n'> <'\tmkdir newfile &&\n'> <'\techo junk >newfile/realfile &&\n'> <'\tgit add file newfile/realfile &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m right &&\n'> <'\n'> <'\tgit checkout -b left-conflict base &&\n'> <'\techo 8 >>file &&\n'> <'\tgit add file &&\n'> <'\tgit mv file newfile &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m left &&\n'> <'\n'> <'\tgit checkout -b left-clean base &&\n'> <'\techo 0 >newfile &&\n'> <'\tcat file >>newfile &&\n'> <'\tgit add newfile &&\n'> <'\tgit rm file &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m left\n'> ) } ) (C {(test_expect_success)} {(SQ <'rename/directory conflict + clean content merge'>)} { (SQ <'\n'> <'\tgit reset --hard &&\n'> <'\tgit reset --hard &&\n'> <'\tgit clean -fdqx &&\n'> <'\n'> <'\tgit checkout left-clean^0 &&\n'> <'\n'> <'\ttest_must_fail git merge -s recursive right^0 &&\n'> <'\n'> <'\ttest 2 -eq $(git ls-files -s | wc -l) &&\n'> <'\ttest 1 -eq $(git ls-files -u | wc -l) &&\n'> <'\ttest 1 -eq $(git ls-files -o | wc -l) &&\n'> <'\n'> <'\techo 0 >expect &&\n'> <'\tgit cat-file -p base:file >>expect &&\n'> <'\techo 7 >>expect &&\n'> <'\ttest_cmp expect newfile~HEAD &&\n'> <'\n'> <'\ttest $(git rev-parse :2:newfile) = $(git hash-object expect) &&\n'> <'\n'> <'\ttest -f newfile/realfile &&\n'> <'\ttest -f newfile~HEAD\n'> ) } ) (C {(test_expect_success)} {(SQ <'rename/directory conflict + content merge conflict'>)} { (SQ <'\n'> <'\tgit reset --hard &&\n'> <'\tgit reset --hard &&\n'> <'\tgit clean -fdqx &&\n'> <'\n'> <'\tgit checkout left-conflict^0 &&\n'> <'\n'> <'\ttest_must_fail git merge -s recursive right^0 &&\n'> <'\n'> <'\ttest 4 -eq $(git ls-files -s | wc -l) &&\n'> <'\ttest 3 -eq $(git ls-files -u | wc -l) &&\n'> <'\ttest 1 -eq $(git ls-files -o | wc -l) &&\n'> <'\n'> <'\tgit cat-file -p left-conflict:newfile >left &&\n'> <'\tgit cat-file -p base:file >base &&\n'> <'\tgit cat-file -p right:file >right &&\n'> <'\ttest_must_fail git merge-file \\\n'> <'\t\t-L "HEAD:newfile" \\\n'> <'\t\t-L "" \\\n'> <'\t\t-L "right^0:file" \\\n'> <'\t\tleft base right &&\n'> <'\ttest_cmp left newfile~HEAD &&\n'> <'\n'> <'\ttest $(git rev-parse :1:newfile) = $(git rev-parse base:file) &&\n'> <'\ttest $(git rev-parse :2:newfile) = $(git rev-parse left-conflict:newfile) &&\n'> <'\ttest $(git rev-parse :3:newfile) = $(git rev-parse right:file) &&\n'> <'\n'> <'\ttest -f newfile/realfile &&\n'> <'\ttest -f newfile~HEAD\n'> ) } ) (C {(test_expect_success)} {(SQ <'setup content merge + rename/directory conflict w/ disappearing dir'>)} { (SQ <'\n'> <'\tgit reset --hard &&\n'> <'\tgit rm -rf . &&\n'> <'\tgit clean -fdqx &&\n'> <'\trm -rf .git &&\n'> <'\tgit init &&\n'> <'\n'> <'\tmkdir sub &&\n'> <'\tprintf "1\\n2\\n3\\n4\\n5\\n6\\n" >sub/file &&\n'> <'\tgit add sub/file &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m base &&\n'> <'\tgit tag base &&\n'> <'\n'> <'\tgit checkout -b right &&\n'> <'\techo 7 >>sub/file &&\n'> <'\tgit add sub/file &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m right &&\n'> <'\n'> <'\tgit checkout -b left base &&\n'> <'\techo 0 >newfile &&\n'> <'\tcat sub/file >>newfile &&\n'> <'\tgit rm sub/file &&\n'> <'\tmv newfile sub &&\n'> <'\tgit add sub &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m left\n'> ) } ) (C {(test_expect_success)} {(SQ <'disappearing dir in rename/directory conflict handled'>)} { (SQ <'\n'> <'\tgit reset --hard &&\n'> <'\tgit clean -fdqx &&\n'> <'\n'> <'\tgit checkout left^0 &&\n'> <'\n'> <'\tgit merge -s recursive right^0 &&\n'> <'\n'> <'\ttest 1 -eq $(git ls-files -s | wc -l) &&\n'> <'\ttest 0 -eq $(git ls-files -u | wc -l) &&\n'> <'\ttest 0 -eq $(git ls-files -o | wc -l) &&\n'> <'\n'> <'\techo 0 >expect &&\n'> <'\tgit cat-file -p base:sub/file >>expect &&\n'> <'\techo 7 >>expect &&\n'> <'\ttest_cmp expect sub &&\n'> <'\n'> <'\ttest -f sub\n'> ) } ) (C {(test_expect_success)} {(SQ <'setup rename/rename (2to1) + modify/modify'>)} { (SQ <'\n'> <'\tgit rm -rf . &&\n'> <'\tgit clean -fdqx &&\n'> <'\trm -rf .git &&\n'> <'\tgit init &&\n'> <'\n'> <'\tprintf "1\\n2\\n3\\n4\\n5\\n" >a &&\n'> <'\tprintf "5\\n4\\n3\\n2\\n1\\n" >b &&\n'> <'\tgit add a b &&\n'> <'\tgit commit -m A &&\n'> <'\tgit tag A &&\n'> <'\n'> <'\tgit checkout -b B A &&\n'> <'\tgit mv a c &&\n'> <'\techo 0 >>b &&\n'> <'\tgit add b &&\n'> <'\tgit commit -m B &&\n'> <'\n'> <'\tgit checkout -b C A &&\n'> <'\tgit mv b c &&\n'> <'\techo 6 >>a &&\n'> <'\tgit add a &&\n'> <'\tgit commit -m C\n'> ) } ) (C {(test_expect_success)} {(SQ <'handle rename/rename (2to1) conflict correctly'>)} { (SQ <'\n'> <'\tgit checkout B^0 &&\n'> <'\n'> <'\ttest_must_fail git merge -s recursive C^0 >out &&\n'> <'\ttest_i18ngrep "CONFLICT (rename/rename)" out &&\n'> <'\n'> <'\ttest 2 -eq $(git ls-files -s | wc -l) &&\n'> <'\ttest 2 -eq $(git ls-files -u | wc -l) &&\n'> <'\ttest 2 -eq $(git ls-files -u c | wc -l) &&\n'> <'\ttest 3 -eq $(git ls-files -o | wc -l) &&\n'> <'\n'> <'\ttest ! -f a &&\n'> <'\ttest ! -f b &&\n'> <'\ttest -f c~HEAD &&\n'> <'\ttest -f c~C^0 &&\n'> <'\n'> <'\ttest $(git hash-object c~HEAD) = $(git rev-parse C:a) &&\n'> <'\ttest $(git hash-object c~C^0) = $(git rev-parse B:b)\n'> ) } ) (C {(test_expect_success)} {(SQ <'setup simple rename/rename (1to2) conflict'>)} { (SQ <'\n'> <'\tgit rm -rf . &&\n'> <'\tgit clean -fdqx &&\n'> <'\trm -rf .git &&\n'> <'\tgit init &&\n'> <'\n'> <'\techo stuff >a &&\n'> <'\tgit add a &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m A &&\n'> <'\tgit tag A &&\n'> <'\n'> <'\tgit checkout -b B A &&\n'> <'\tgit mv a b &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m B &&\n'> <'\n'> <'\tgit checkout -b C A &&\n'> <'\tgit mv a c &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m C\n'> ) } ) (C {(test_expect_success)} {(SQ <'merge has correct working tree contents'>)} { (SQ <'\n'> <'\tgit checkout C^0 &&\n'> <'\n'> <'\ttest_must_fail git merge -s recursive B^0 &&\n'> <'\n'> <'\ttest 3 -eq $(git ls-files -s | wc -l) &&\n'> <'\ttest 3 -eq $(git ls-files -u | wc -l) &&\n'> <'\ttest 0 -eq $(git ls-files -o | wc -l) &&\n'> <'\n'> <'\ttest $(git rev-parse :1:a) = $(git rev-parse A:a) &&\n'> <'\ttest $(git rev-parse :3:b) = $(git rev-parse A:a) &&\n'> <'\ttest $(git rev-parse :2:c) = $(git rev-parse A:a) &&\n'> <'\n'> <'\ttest ! -f a &&\n'> <'\ttest $(git hash-object b) = $(git rev-parse A:a) &&\n'> <'\ttest $(git hash-object c) = $(git rev-parse A:a)\n'> ) } ) (C {(test_expect_success)} {(SQ <'setup rename/rename(1to2)/add-source conflict'>)} { (SQ <'\n'> <'\tgit rm -rf . &&\n'> <'\tgit clean -fdqx &&\n'> <'\trm -rf .git &&\n'> <'\tgit init &&\n'> <'\n'> <'\tprintf "1\\n2\\n3\\n4\\n5\\n6\\n7\\n" >a &&\n'> <'\tgit add a &&\n'> <'\tgit commit -m A &&\n'> <'\tgit tag A &&\n'> <'\n'> <'\tgit checkout -b B A &&\n'> <'\tgit mv a b &&\n'> <'\tgit commit -m B &&\n'> <'\n'> <'\tgit checkout -b C A &&\n'> <'\tgit mv a c &&\n'> <'\techo something completely different >a &&\n'> <'\tgit add a &&\n'> <'\tgit commit -m C\n'> ) } ) (C {(test_expect_failure)} {(SQ <'detect conflict with rename/rename(1to2)/add-source merge'>)} { (SQ <'\n'> <'\tgit checkout B^0 &&\n'> <'\n'> <'\ttest_must_fail git merge -s recursive C^0 &&\n'> <'\n'> <'\ttest 4 -eq $(git ls-files -s | wc -l) &&\n'> <'\ttest 0 -eq $(git ls-files -o | wc -l) &&\n'> <'\n'> <'\ttest $(git rev-parse 3:a) = $(git rev-parse C:a) &&\n'> <'\ttest $(git rev-parse 1:a) = $(git rev-parse A:a) &&\n'> <'\ttest $(git rev-parse 2:b) = $(git rev-parse B:b) &&\n'> <'\ttest $(git rev-parse 3:c) = $(git rev-parse C:c) &&\n'> <'\n'> <'\ttest -f a &&\n'> <'\ttest -f b &&\n'> <'\ttest -f c\n'> ) } ) (C {(test_expect_success)} {(SQ <'setup rename/rename(1to2)/add-source resolvable conflict'>)} { (SQ <'\n'> <'\tgit rm -rf . &&\n'> <'\tgit clean -fdqx &&\n'> <'\trm -rf .git &&\n'> <'\tgit init &&\n'> <'\n'> <'\t>a &&\n'> <'\tgit add a &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m base &&\n'> <'\tgit tag A &&\n'> <'\n'> <'\tgit checkout -b B A &&\n'> <'\tgit mv a b &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m one &&\n'> <'\n'> <'\tgit checkout -b C A &&\n'> <'\tgit mv a b &&\n'> <'\techo important-info >a &&\n'> <'\tgit add a &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m two\n'> ) } ) (C {(test_expect_failure)} {(SQ <'rename/rename/add-source still tracks new a file'>)} { (SQ <'\n'> <'\tgit checkout C^0 &&\n'> <'\tgit merge -s recursive B^0 &&\n'> <'\n'> <'\ttest 2 -eq $(git ls-files -s | wc -l) &&\n'> <'\ttest 0 -eq $(git ls-files -o | wc -l) &&\n'> <'\n'> <'\ttest $(git rev-parse HEAD:a) = $(git rev-parse C:a) &&\n'> <'\ttest $(git rev-parse HEAD:b) = $(git rev-parse A:a)\n'> ) } ) (C {(test_expect_success)} {(SQ <'setup rename/rename(1to2)/add-dest conflict'>)} { (SQ <'\n'> <'\tgit rm -rf . &&\n'> <'\tgit clean -fdqx &&\n'> <'\trm -rf .git &&\n'> <'\tgit init &&\n'> <'\n'> <'\techo stuff >a &&\n'> <'\tgit add a &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m base &&\n'> <'\tgit tag A &&\n'> <'\n'> <'\tgit checkout -b B A &&\n'> <'\tgit mv a b &&\n'> <'\techo precious-data >c &&\n'> <'\tgit add c &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m one &&\n'> <'\n'> <'\tgit checkout -b C A &&\n'> <'\tgit mv a c &&\n'> <'\techo important-info >b &&\n'> <'\tgit add b &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m two\n'> ) } ) (C {(test_expect_success)} {(SQ <'rename/rename/add-dest merge still knows about conflicting file versions'>)} { (SQ <'\n'> <'\tgit checkout C^0 &&\n'> <'\ttest_must_fail git merge -s recursive B^0 &&\n'> <'\n'> <'\ttest 5 -eq $(git ls-files -s | wc -l) &&\n'> <'\ttest 2 -eq $(git ls-files -u b | wc -l) &&\n'> <'\ttest 2 -eq $(git ls-files -u c | wc -l) &&\n'> <'\ttest 4 -eq $(git ls-files -o | wc -l) &&\n'> <'\n'> <'\ttest $(git rev-parse :1:a) = $(git rev-parse A:a) &&\n'> <'\ttest $(git rev-parse :2:b) = $(git rev-parse C:b) &&\n'> <'\ttest $(git rev-parse :3:b) = $(git rev-parse B:b) &&\n'> <'\ttest $(git rev-parse :2:c) = $(git rev-parse C:c) &&\n'> <'\ttest $(git rev-parse :3:c) = $(git rev-parse B:c) &&\n'> <'\n'> <'\ttest $(git hash-object c~HEAD) = $(git rev-parse C:c) &&\n'> <'\ttest $(git hash-object c~B\\^0) = $(git rev-parse B:c) &&\n'> <'\ttest $(git hash-object b~HEAD) = $(git rev-parse C:b) &&\n'> <'\ttest $(git hash-object b~B\\^0) = $(git rev-parse B:b) &&\n'> <'\n'> <'\ttest ! -f b &&\n'> <'\ttest ! -f c\n'> ) } ) (C {(test_done)}) ] )