#!/bin/sh global test_description := ''CRLF merge conflict across text=auto change * [master] remove .gitattributes ! [side] add line from b -- + [side] add line from b * [master] remove .gitattributes * [master^] add line from a * [master~2] normalize file *+ [side^] Initial '' source ./test-lib.sh test_have_prereq SED_STRIPS_CR && global SED_OPTIONS := '-b' proc compare_files { tr '\015\000' QN <$1 >"$1".expect && tr '\015\000' QN <$2 >"$2".actual && test_cmp "$1".expect "$2".actual && rm "$1".expect "$2".actual } test_expect_success setup ' git config core.autocrlf false && echo first line | append_cr >file && echo first line >control_file && echo only line >inert_file && git add file control_file inert_file && test_tick && git commit -m "Initial" && git tag initial && git branch side && echo "* text=auto" >.gitattributes && echo first line >file && git add .gitattributes file && test_tick && git commit -m "normalize file" && echo same line | append_cr >>file && echo same line >>control_file && git add file control_file && test_tick && git commit -m "add line from a" && git tag a && git rm .gitattributes && rm file && git checkout file && test_tick && git commit -m "remove .gitattributes" && git tag c && git checkout side && echo same line | append_cr >>file && echo same line >>control_file && git add file control_file && test_tick && git commit -m "add line from b" && git tag b && git checkout master ' test_expect_success 'set up fuzz_conflict() helper' ' fuzz_conflict() { sed $SED_OPTIONS -e "s/^\([<>=]......\) .*/\1/" "$@" } ' test_expect_success 'Merge after setting text=auto' ' cat <<-\EOF >expected && first line same line EOF if test_have_prereq NATIVE_CRLF; then append_cr expected.temp && mv expected.temp expected fi && git config merge.renormalize true && git rm -fr . && rm -f .gitattributes && git reset --hard a && git merge b && compare_files expected file ' test_expect_success 'Merge addition of text=auto eol=LF' ' git config core.eol lf && cat <<-\EOF >expected && first line same line EOF git config merge.renormalize true && git rm -fr . && rm -f .gitattributes && git reset --hard b && git merge a && compare_files expected file ' test_expect_success 'Merge addition of text=auto eol=CRLF' ' git config core.eol crlf && cat <<-\EOF >expected && first line same line EOF append_cr expected.temp && mv expected.temp expected && git config merge.renormalize true && git rm -fr . && rm -f .gitattributes && git reset --hard b && echo >&2 "After git reset --hard b" && git ls-files -s --eol >&2 && git merge a && compare_files expected file ' test_expect_success 'Detect CRLF/LF conflict after setting text=auto' ' git config core.eol native && echo "<<<<<<<" >expected && echo first line >>expected && echo same line >>expected && echo ======= >>expected && echo first line | append_cr >>expected && echo same line | append_cr >>expected && echo ">>>>>>>" >>expected && git config merge.renormalize false && rm -f .gitattributes && git reset --hard a && test_must_fail git merge b && fuzz_conflict file >file.fuzzy && compare_files expected file.fuzzy ' test_expect_success 'Detect LF/CRLF conflict from addition of text=auto' ' echo "<<<<<<<" >expected && echo first line | append_cr >>expected && echo same line | append_cr >>expected && echo ======= >>expected && echo first line >>expected && echo same line >>expected && echo ">>>>>>>" >>expected && git config merge.renormalize false && rm -f .gitattributes && git reset --hard b && test_must_fail git merge a && fuzz_conflict file >file.fuzzy && compare_files expected file.fuzzy ' test_expect_failure 'checkout -m after setting text=auto' ' cat <<-\EOF >expected && first line same line EOF git config merge.renormalize true && git rm -fr . && rm -f .gitattributes && git reset --hard initial && git checkout a -- . && git checkout -m b && compare_files expected file ' test_expect_failure 'checkout -m addition of text=auto' ' cat <<-\EOF >expected && first line same line EOF git config merge.renormalize true && git rm -fr . && rm -f .gitattributes file && git reset --hard initial && git checkout b -- . && git checkout -m a && compare_files expected file ' test_expect_failure 'cherry-pick patch from after text=auto was added' ' append_cr <<-\EOF >expected && first line same line EOF git config merge.renormalize true && git rm -fr . && git reset --hard b && test_must_fail git cherry-pick a >err 2>&1 && grep "[Nn]othing added" err && compare_files expected file ' test_expect_success 'Test delete/normalize conflict' ' git checkout -f side && git rm -fr . && rm -f .gitattributes && git reset --hard initial && git rm file && git commit -m "remove file" && git checkout master && git reset --hard a^ && git merge side ' test_done (CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: { (SQ <"CRLF merge conflict across text=auto change\n"> <"\n"> <"* [master] remove .gitattributes\n"> <" ! [side] add line from b\n"> <"--\n"> <" + [side] add line from b\n"> <"* [master] remove .gitattributes\n"> <"* [master^] add line from a\n"> <"* [master~2] normalize file\n"> <"*+ [side^] Initial\n"> ) } spids: [4] ) ] spids: [4] ) (C {(.)} {(./test-lib.sh)}) (AndOr children: [ (C {(test_have_prereq)} {(SED_STRIPS_CR)}) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:SED_OPTIONS) op:Equal rhs:{(-b)} spids:[30])] spids: [30] ) ] op_id: Op_DAmp ) (FuncDef name: compare_files body: (BraceGroup children: [ (AndOr children: [ (SimpleCommand words: [{(tr)} {(SQ <"\\015\\000">)} {(QN)}] redirects: [ (Redir op_id: Redir_Less fd: -1 arg_word: {(DQ ($ VSub_Number "$1"))} spids: [50] ) (Redir op_id: Redir_Great fd: -1 arg_word: {(DQ ($ VSub_Number "$1")) (.expect)} spids: [55] ) ] ) (AndOr children: [ (SimpleCommand words: [{(tr)} {(SQ <"\\015\\000">)} {(QN)}] redirects: [ (Redir op_id: Redir_Less fd: -1 arg_word: {(DQ ($ VSub_Number "$2"))} spids: [72] ) (Redir op_id: Redir_Great fd: -1 arg_word: {(DQ ($ VSub_Number "$2")) (.actual)} spids: [77] ) ] ) (AndOr children: [ (C {(test_cmp)} {(DQ ($ VSub_Number "$1")) (.expect)} {(DQ ($ VSub_Number "$2")) (.actual)} ) (C {(rm)} {(DQ ($ VSub_Number "$1")) (.expect)} {(DQ ($ VSub_Number "$2")) (.actual)} ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] spids: [39] ) spids: [34 38] ) (C {(test_expect_success)} {(setup)} { (SQ <"\n"> <"\tgit config core.autocrlf false &&\n"> <"\n"> <"\techo first line | append_cr >file &&\n"> <"\techo first line >control_file &&\n"> <"\techo only line >inert_file &&\n"> <"\n"> <"\tgit add file control_file inert_file &&\n"> <"\ttest_tick &&\n"> <"\tgit commit -m \"Initial\" &&\n"> <"\tgit tag initial &&\n"> <"\tgit branch side &&\n"> <"\n"> <"\techo \"* text=auto\" >.gitattributes &&\n"> <"\techo first line >file &&\n"> <"\tgit add .gitattributes file &&\n"> <"\ttest_tick &&\n"> <"\tgit commit -m \"normalize file\" &&\n"> <"\n"> <"\techo same line | append_cr >>file &&\n"> <"\techo same line >>control_file &&\n"> <"\tgit add file control_file &&\n"> <"\ttest_tick &&\n"> <"\tgit commit -m \"add line from a\" &&\n"> <"\tgit tag a &&\n"> <"\n"> <"\tgit rm .gitattributes &&\n"> <"\trm file &&\n"> <"\tgit checkout file &&\n"> <"\ttest_tick &&\n"> <"\tgit commit -m \"remove .gitattributes\" &&\n"> <"\tgit tag c &&\n"> <"\n"> <"\tgit checkout side &&\n"> <"\techo same line | append_cr >>file &&\n"> <"\techo same line >>control_file &&\n"> <"\tgit add file control_file &&\n"> <"\ttest_tick &&\n"> <"\tgit commit -m \"add line from b\" &&\n"> <"\tgit tag b &&\n"> <"\n"> <"\tgit checkout master\n"> ) } ) (C {(test_expect_success)} {(SQ <"set up fuzz_conflict() helper">)} { (SQ <"\n"> <"\tfuzz_conflict() {\n"> <"\t\tsed $SED_OPTIONS -e \"s/^\\([<>=]......\\) .*/\\1/\" \"$@\"\n"> <"\t}\n"> ) } ) (C {(test_expect_success)} {(SQ <"Merge after setting text=auto">)} { (SQ <"\n"> <"\tcat <<-\\EOF >expected &&\n"> <"\tfirst line\n"> <"\tsame line\n"> <"\tEOF\n"> <"\n"> <"\tif test_have_prereq NATIVE_CRLF; then\n"> <"\t\tappend_cr expected.temp &&\n"> <"\t\tmv expected.temp expected\n"> <"\tfi &&\n"> <"\tgit config merge.renormalize true &&\n"> <"\tgit rm -fr . &&\n"> <"\trm -f .gitattributes &&\n"> <"\tgit reset --hard a &&\n"> <"\tgit merge b &&\n"> <"\tcompare_files expected file\n"> ) } ) (C {(test_expect_success)} {(SQ <"Merge addition of text=auto eol=LF">)} { (SQ <"\n"> <"\tgit config core.eol lf &&\n"> <"\tcat <<-\\EOF >expected &&\n"> <"\tfirst line\n"> <"\tsame line\n"> <"\tEOF\n"> <"\n"> <"\tgit config merge.renormalize true &&\n"> <"\tgit rm -fr . &&\n"> <"\trm -f .gitattributes &&\n"> <"\tgit reset --hard b &&\n"> <"\tgit merge a &&\n"> <"\tcompare_files expected file\n"> ) } ) (C {(test_expect_success)} {(SQ <"Merge addition of text=auto eol=CRLF">)} { (SQ <"\n"> <"\tgit config core.eol crlf &&\n"> <"\tcat <<-\\EOF >expected &&\n"> <"\tfirst line\n"> <"\tsame line\n"> <"\tEOF\n"> <"\n"> <"\tappend_cr expected.temp &&\n"> <"\tmv expected.temp expected &&\n"> <"\tgit config merge.renormalize true &&\n"> <"\tgit rm -fr . &&\n"> <"\trm -f .gitattributes &&\n"> <"\tgit reset --hard b &&\n"> <"\techo >&2 \"After git reset --hard b\" &&\n"> <"\tgit ls-files -s --eol >&2 &&\n"> <"\tgit merge a &&\n"> <"\tcompare_files expected file\n"> ) } ) (C {(test_expect_success)} {(SQ <"Detect CRLF/LF conflict after setting text=auto">)} { (SQ <"\n"> <"\tgit config core.eol native &&\n"> <"\techo \"<<<<<<<\" >expected &&\n"> <"\techo first line >>expected &&\n"> <"\techo same line >>expected &&\n"> <"\techo ======= >>expected &&\n"> <"\techo first line | append_cr >>expected &&\n"> <"\techo same line | append_cr >>expected &&\n"> <"\techo \">>>>>>>\" >>expected &&\n"> <"\tgit config merge.renormalize false &&\n"> <"\trm -f .gitattributes &&\n"> <"\tgit reset --hard a &&\n"> <"\ttest_must_fail git merge b &&\n"> <"\tfuzz_conflict file >file.fuzzy &&\n"> <"\tcompare_files expected file.fuzzy\n"> ) } ) (C {(test_expect_success)} {(SQ <"Detect LF/CRLF conflict from addition of text=auto">)} { (SQ <"\n"> <"\techo \"<<<<<<<\" >expected &&\n"> <"\techo first line | append_cr >>expected &&\n"> <"\techo same line | append_cr >>expected &&\n"> <"\techo ======= >>expected &&\n"> <"\techo first line >>expected &&\n"> <"\techo same line >>expected &&\n"> <"\techo \">>>>>>>\" >>expected &&\n"> <"\tgit config merge.renormalize false &&\n"> <"\trm -f .gitattributes &&\n"> <"\tgit reset --hard b &&\n"> <"\ttest_must_fail git merge a &&\n"> <"\tfuzz_conflict file >file.fuzzy &&\n"> <"\tcompare_files expected file.fuzzy\n"> ) } ) (C {(test_expect_failure)} {(SQ <"checkout -m after setting text=auto">)} { (SQ <"\n"> <"\tcat <<-\\EOF >expected &&\n"> <"\tfirst line\n"> <"\tsame line\n"> <"\tEOF\n"> <"\n"> <"\tgit config merge.renormalize true &&\n"> <"\tgit rm -fr . &&\n"> <"\trm -f .gitattributes &&\n"> <"\tgit reset --hard initial &&\n"> <"\tgit checkout a -- . &&\n"> <"\tgit checkout -m b &&\n"> <"\tcompare_files expected file\n"> ) } ) (C {(test_expect_failure)} {(SQ <"checkout -m addition of text=auto">)} { (SQ <"\n"> <"\tcat <<-\\EOF >expected &&\n"> <"\tfirst line\n"> <"\tsame line\n"> <"\tEOF\n"> <"\n"> <"\tgit config merge.renormalize true &&\n"> <"\tgit rm -fr . &&\n"> <"\trm -f .gitattributes file &&\n"> <"\tgit reset --hard initial &&\n"> <"\tgit checkout b -- . &&\n"> <"\tgit checkout -m a &&\n"> <"\tcompare_files expected file\n"> ) } ) (C {(test_expect_failure)} {(SQ <"cherry-pick patch from after text=auto was added">)} { (SQ <"\n"> <"\tappend_cr <<-\\EOF >expected &&\n"> <"\tfirst line\n"> <"\tsame line\n"> <"\tEOF\n"> <"\n"> <"\tgit config merge.renormalize true &&\n"> <"\tgit rm -fr . &&\n"> <"\tgit reset --hard b &&\n"> <"\ttest_must_fail git cherry-pick a >err 2>&1 &&\n"> <"\tgrep \"[Nn]othing added\" err &&\n"> <"\tcompare_files expected file\n"> ) } ) (C {(test_expect_success)} {(SQ <"Test delete/normalize conflict">)} { (SQ <"\n"> <"\tgit checkout -f side &&\n"> <"\tgit rm -fr . &&\n"> <"\trm -f .gitattributes &&\n"> <"\tgit reset --hard initial &&\n"> <"\tgit rm file &&\n"> <"\tgit commit -m \"remove file\" &&\n"> <"\tgit checkout master &&\n"> <"\tgit reset --hard a^ &&\n"> <"\tgit merge side\n"> ) } ) (C {(test_done)}) ] )