#!/bin/sh global test_description := ''git apply --3way'' source ./test-lib.sh proc create_filefor i in @Argv { echo $i } } proc sanitize_conflicted_diff { sed -e ' /^index /d s/^\(+[<>][<>][<>][<>]*\) .*/\1/ ' } test_expect_success setup ' test_tick && create_file >one 1 2 3 4 5 6 7 && cat one >two && git add one two && git commit -m initial && git branch side && test_tick && create_file >one 1 two 3 4 5 six 7 && create_file >two 1 two 3 4 5 6 7 && git commit -a -m master && git checkout side && create_file >one 1 2 3 4 five 6 7 && create_file >two 1 2 3 4 five 6 7 && git commit -a -m side && git checkout master ' test_expect_success 'apply without --3way' ' git diff side^ side >P.diff && # should fail to apply git reset --hard && git checkout master^0 && test_must_fail git apply --index P.diff && # should leave things intact git diff-files --exit-code && git diff-index --exit-code --cached HEAD ' test_expect_success 'apply with --3way' ' # Merging side should be similar to applying this patch git diff ...side >P.diff && # The corresponding conflicted merge git reset --hard && git checkout master^0 && test_must_fail git merge --no-commit side && git ls-files -s >expect.ls && git diff HEAD | sanitize_conflicted_diff >expect.diff && # should fail to apply git reset --hard && git checkout master^0 && test_must_fail git apply --index --3way P.diff && git ls-files -s >actual.ls && git diff HEAD | sanitize_conflicted_diff >actual.diff && # The result should resemble the corresponding merge test_cmp expect.ls actual.ls && test_cmp expect.diff actual.diff ' test_expect_success 'apply with --3way with rerere enabled' ' git config rerere.enabled true && # Merging side should be similar to applying this patch git diff ...side >P.diff && # The corresponding conflicted merge git reset --hard && git checkout master^0 && test_must_fail git merge --no-commit side && # Manually resolve and record the resolution create_file 1 two 3 4 five six 7 >one && git rerere && cat one >expect && # should fail to apply git reset --hard && git checkout master^0 && test_must_fail git apply --index --3way P.diff && # but rerere should have replayed the recorded resolution test_cmp expect one ' test_expect_success 'apply -3 with add/add conflict setup' ' git reset --hard && git checkout -b adder && create_file 1 2 3 4 5 6 7 >three && create_file 1 2 3 4 5 6 7 >four && git add three four && git commit -m "add three and four" && git checkout -b another adder^ && create_file 1 2 3 4 5 6 7 >three && create_file 1 2 3 four 5 6 7 >four && git add three four && git commit -m "add three and four" && # Merging another should be similar to applying this patch git diff adder...another >P.diff && git checkout adder^0 && test_must_fail git merge --no-commit another && git ls-files -s >expect.ls && git diff HEAD | sanitize_conflicted_diff >expect.diff ' test_expect_success 'apply -3 with add/add conflict' ' # should fail to apply ... git reset --hard && git checkout adder^0 && test_must_fail git apply --index --3way P.diff && # ... and leave conflicts in the index and in the working tree git ls-files -s >actual.ls && git diff HEAD | sanitize_conflicted_diff >actual.diff && # The result should resemble the corresponding merge test_cmp expect.ls actual.ls && test_cmp expect.diff actual.diff ' test_expect_success 'apply -3 with add/add conflict (dirty working tree)' ' # should fail to apply ... git reset --hard && git checkout adder^0 && echo >>four && cat four >four.save && cat three >three.save && git ls-files -s >expect.ls && test_must_fail git apply --index --3way P.diff && # ... and should not touch anything git ls-files -s >actual.ls && test_cmp expect.ls actual.ls && test_cmp four.save four && test_cmp three.save three ' test_done (CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(SQ <"git apply --3way">)} spids: [4] ) ] spids: [4] ) (C {(.)} {(./test-lib.sh)}) (FuncDef name: create_file body: (BraceGroup children: [ (ForEach iter_name: i do_arg_iter: True body: (DoGroup children:[(C {(echo)} {(DQ ($ VSub_Name "$i"))})] spids:[2838]) spids: [-1 -1] ) ] spids: [20] ) spids: [15 19] ) (FuncDef name: sanitize_conflicted_diff body: (BraceGroup children: [ (C {(sed)} {(-e)} {(SQ <"\n"> <"\t\t/^index /d\n"> <"\t\ts/^\\(+[<>][<>][<>][<>]*\\) .*/\\1/\n"> <"\t">)} ) ] spids: [48] ) spids: [43 47] ) (C {(test_expect_success)} {(setup)} { (SQ <"\n"> <"\ttest_tick &&\n"> <"\tcreate_file >one 1 2 3 4 5 6 7 &&\n"> <"\tcat one >two &&\n"> <"\tgit add one two &&\n"> <"\tgit commit -m initial &&\n"> <"\n"> <"\tgit branch side &&\n"> <"\n"> <"\ttest_tick &&\n"> <"\tcreate_file >one 1 two 3 4 5 six 7 &&\n"> <"\tcreate_file >two 1 two 3 4 5 6 7 &&\n"> <"\tgit commit -a -m master &&\n"> <"\n"> <"\tgit checkout side &&\n"> <"\tcreate_file >one 1 2 3 4 five 6 7 &&\n"> <"\tcreate_file >two 1 2 3 4 five 6 7 &&\n"> <"\tgit commit -a -m side &&\n"> <"\n"> <"\tgit checkout master\n"> ) } ) (C {(test_expect_success)} {(SQ <"apply without --3way">)} { (SQ <"\n"> <"\tgit diff side^ side >P.diff &&\n"> <"\n"> <"\t# should fail to apply\n"> <"\tgit reset --hard &&\n"> <"\tgit checkout master^0 &&\n"> <"\ttest_must_fail git apply --index P.diff &&\n"> <"\t# should leave things intact\n"> <"\tgit diff-files --exit-code &&\n"> <"\tgit diff-index --exit-code --cached HEAD\n"> ) } ) (C {(test_expect_success)} {(SQ <"apply with --3way">)} { (SQ <"\n"> <"\t# Merging side should be similar to applying this patch\n"> <"\tgit diff ...side >P.diff &&\n"> <"\n"> <"\t# The corresponding conflicted merge\n"> <"\tgit reset --hard &&\n"> <"\tgit checkout master^0 &&\n"> <"\ttest_must_fail git merge --no-commit side &&\n"> <"\tgit ls-files -s >expect.ls &&\n"> <"\tgit diff HEAD | sanitize_conflicted_diff >expect.diff &&\n"> <"\n"> <"\t# should fail to apply\n"> <"\tgit reset --hard &&\n"> <"\tgit checkout master^0 &&\n"> <"\ttest_must_fail git apply --index --3way P.diff &&\n"> <"\tgit ls-files -s >actual.ls &&\n"> <"\tgit diff HEAD | sanitize_conflicted_diff >actual.diff &&\n"> <"\n"> <"\t# The result should resemble the corresponding merge\n"> <"\ttest_cmp expect.ls actual.ls &&\n"> <"\ttest_cmp expect.diff actual.diff\n"> ) } ) (C {(test_expect_success)} {(SQ <"apply with --3way with rerere enabled">)} { (SQ <"\n"> <"\tgit config rerere.enabled true &&\n"> <"\n"> <"\t# Merging side should be similar to applying this patch\n"> <"\tgit diff ...side >P.diff &&\n"> <"\n"> <"\t# The corresponding conflicted merge\n"> <"\tgit reset --hard &&\n"> <"\tgit checkout master^0 &&\n"> <"\ttest_must_fail git merge --no-commit side &&\n"> <"\n"> <"\t# Manually resolve and record the resolution\n"> <"\tcreate_file 1 two 3 4 five six 7 >one &&\n"> <"\tgit rerere &&\n"> <"\tcat one >expect &&\n"> <"\n"> <"\t# should fail to apply\n"> <"\tgit reset --hard &&\n"> <"\tgit checkout master^0 &&\n"> <"\ttest_must_fail git apply --index --3way P.diff &&\n"> <"\n"> <"\t# but rerere should have replayed the recorded resolution\n"> <"\ttest_cmp expect one\n"> ) } ) (C {(test_expect_success)} {(SQ <"apply -3 with add/add conflict setup">)} { (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\n"> <"\tgit checkout -b adder &&\n"> <"\tcreate_file 1 2 3 4 5 6 7 >three &&\n"> <"\tcreate_file 1 2 3 4 5 6 7 >four &&\n"> <"\tgit add three four &&\n"> <"\tgit commit -m \"add three and four\" &&\n"> <"\n"> <"\tgit checkout -b another adder^ &&\n"> <"\tcreate_file 1 2 3 4 5 6 7 >three &&\n"> <"\tcreate_file 1 2 3 four 5 6 7 >four &&\n"> <"\tgit add three four &&\n"> <"\tgit commit -m \"add three and four\" &&\n"> <"\n"> <"\t# Merging another should be similar to applying this patch\n"> <"\tgit diff adder...another >P.diff &&\n"> <"\n"> <"\tgit checkout adder^0 &&\n"> <"\ttest_must_fail git merge --no-commit another &&\n"> <"\tgit ls-files -s >expect.ls &&\n"> <"\tgit diff HEAD | sanitize_conflicted_diff >expect.diff\n"> ) } ) (C {(test_expect_success)} {(SQ <"apply -3 with add/add conflict">)} { (SQ <"\n"> <"\t# should fail to apply ...\n"> <"\tgit reset --hard &&\n"> <"\tgit checkout adder^0 &&\n"> <"\ttest_must_fail git apply --index --3way P.diff &&\n"> <"\t# ... and leave conflicts in the index and in the working tree\n"> <"\tgit ls-files -s >actual.ls &&\n"> <"\tgit diff HEAD | sanitize_conflicted_diff >actual.diff &&\n"> <"\n"> <"\t# The result should resemble the corresponding merge\n"> <"\ttest_cmp expect.ls actual.ls &&\n"> <"\ttest_cmp expect.diff actual.diff\n"> ) } ) (C {(test_expect_success)} {(SQ <"apply -3 with add/add conflict (dirty working tree)">)} { (SQ <"\n"> <"\t# should fail to apply ...\n"> <"\tgit reset --hard &&\n"> <"\tgit checkout adder^0 &&\n"> <"\techo >>four &&\n"> <"\tcat four >four.save &&\n"> <"\tcat three >three.save &&\n"> <"\tgit ls-files -s >expect.ls &&\n"> <"\ttest_must_fail git apply --index --3way P.diff &&\n"> <"\t# ... and should not touch anything\n"> <"\tgit ls-files -s >actual.ls &&\n"> <"\ttest_cmp expect.ls actual.ls &&\n"> <"\ttest_cmp four.save four &&\n"> <"\ttest_cmp three.save three\n"> ) } ) (C {(test_done)}) ] )