#!/bin/sh global test_description := ''merge: handle file mode'' source ./test-lib.sh test_expect_success 'set up mode change in one branch' ' : >file1 && git add file1 && git commit -m initial && git checkout -b a1 master && : >dummy && git add dummy && git commit -m a && git checkout -b b1 master && test_chmod +x file1 && git add file1 && git commit -m b1 ' proc do_one_mode { global strategy := $1 global us := $2 global them := $3 test_expect_success "resolve single mode change ($strategy, $us)" ' git checkout -f $us && git merge -s $strategy $them && git ls-files -s file1 | grep ^100755 ' test_expect_success FILEMODE "verify executable bit on file ($strategy, $us)" ' test -x file1 ' } do_one_mode recursive a1 b1 do_one_mode recursive b1 a1 do_one_mode resolve a1 b1 do_one_mode resolve b1 a1 test_expect_success 'set up mode change in both branches' ' git reset --hard HEAD && git checkout -b a2 master && : >file2 && H=$(git hash-object file2) && test_chmod +x file2 && git commit -m a2 && git checkout -b b2 master && : >file2 && git add file2 && git commit -m b2 && { echo "100755 $H 2 file2" echo "100644 $H 3 file2" } >expect ' proc do_both_modes { global strategy := $1 test_expect_success "detect conflict on double mode change ($strategy)" ' git reset --hard && git checkout -f a2 && test_must_fail git merge -s $strategy b2 && git ls-files -u >actual && test_cmp actual expect && git ls-files -s file2 | grep ^100755 ' test_expect_success FILEMODE "verify executable bit on file ($strategy)" ' test -x file2 ' } # both sides are equivalent, so no need to run both ways do_both_modes recursive do_both_modes resolve test_expect_success 'set up delete/modechange scenario' ' git reset --hard && git checkout -b deletion master && git rm file1 && git commit -m deletion ' proc do_delete_modechange { global strategy := $1 global us := $2 global them := $3 test_expect_success "detect delete/modechange conflict ($strategy, $us)" ' git reset --hard && git checkout $us && test_must_fail git merge -s $strategy $them ' } do_delete_modechange recursive b1 deletion do_delete_modechange recursive deletion b1 do_delete_modechange resolve b1 deletion do_delete_modechange resolve deletion b1 test_done (CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(SQ <"merge: handle file mode">)} spids: [4] ) ] spids: [4] ) (C {(.)} {(./test-lib.sh)}) (C {(test_expect_success)} {(SQ <"set up mode change in one branch">)} { (SQ <"\n"> <"\t: >file1 &&\n"> <"\tgit add file1 &&\n"> <"\tgit commit -m initial &&\n"> <"\tgit checkout -b a1 master &&\n"> <"\t: >dummy &&\n"> <"\tgit add dummy &&\n"> <"\tgit commit -m a &&\n"> <"\tgit checkout -b b1 master &&\n"> <"\ttest_chmod +x file1 &&\n"> <"\tgit add file1 &&\n"> <"\tgit commit -m b1\n"> ) } ) (FuncDef name: do_one_mode body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:strategy) op: Equal rhs: {($ VSub_Number "$1")} spids: [44] ) ] spids: [44] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:us) op: Equal rhs: {($ VSub_Number "$2")} spids: [48] ) ] spids: [48] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:them) op: Equal rhs: {($ VSub_Number "$3")} spids: [52] ) ] spids: [52] ) (C {(test_expect_success)} { (DQ ("resolve single mode change (") ($ VSub_Name "$strategy") (", ") ($ VSub_Name "$us") (")") ) } { (SQ <"\n"> <"\t\tgit checkout -f $us &&\n"> <"\t\tgit merge -s $strategy $them &&\n"> <"\t\tgit ls-files -s file1 | grep ^100755\n"> <"\t"> ) } ) (C {(test_expect_success)} {(FILEMODE)} { (DQ ("verify executable bit on file (") ($ VSub_Name "$strategy") (", ") ($ VSub_Name "$us") (")") ) } {(SQ <"\n"> <"\t\ttest -x file1\n"> <"\t">)} ) ] spids: [41] ) spids: [36 40] ) (C {(do_one_mode)} {(recursive)} {(a1)} {(b1)}) (C {(do_one_mode)} {(recursive)} {(b1)} {(a1)}) (C {(do_one_mode)} {(resolve)} {(a1)} {(b1)}) (C {(do_one_mode)} {(resolve)} {(b1)} {(a1)}) (C {(test_expect_success)} {(SQ <"set up mode change in both branches">)} { (SQ <"\n"> <"\tgit reset --hard HEAD &&\n"> <"\tgit checkout -b a2 master &&\n"> <"\t: >file2 &&\n"> <"\tH=$(git hash-object file2) &&\n"> <"\ttest_chmod +x file2 &&\n"> <"\tgit commit -m a2 &&\n"> <"\tgit checkout -b b2 master &&\n"> <"\t: >file2 &&\n"> <"\tgit add file2 &&\n"> <"\tgit commit -m b2 &&\n"> <"\t{\n"> <"\t\techo \"100755 $H 2\tfile2\"\n"> <"\t\techo \"100644 $H 3\tfile2\"\n"> <"\t} >expect\n"> ) } ) (FuncDef name: do_both_modes body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:strategy) op: Equal rhs: {($ VSub_Number "$1")} spids: [163] ) ] spids: [163] ) (C {(test_expect_success)} {(DQ ("detect conflict on double mode change (") ($ VSub_Name "$strategy") (")"))} { (SQ <"\n"> <"\t\tgit reset --hard &&\n"> <"\t\tgit checkout -f a2 &&\n"> <"\t\ttest_must_fail git merge -s $strategy b2 &&\n"> <"\t\tgit ls-files -u >actual &&\n"> <"\t\ttest_cmp actual expect &&\n"> <"\t\tgit ls-files -s file2 | grep ^100755\n"> <"\t"> ) } ) (C {(test_expect_success)} {(FILEMODE)} {(DQ ("verify executable bit on file (") ($ VSub_Name "$strategy") (")"))} {(SQ <"\n"> <"\t\ttest -x file2\n"> <"\t">)} ) ] spids: [160] ) spids: [155 159] ) (C {(do_both_modes)} {(recursive)}) (C {(do_both_modes)} {(resolve)}) (C {(test_expect_success)} {(SQ <"set up delete/modechange scenario">)} { (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\tgit checkout -b deletion master &&\n"> <"\tgit rm file1 &&\n"> <"\tgit commit -m deletion\n"> ) } ) (FuncDef name: do_delete_modechange body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:strategy) op: Equal rhs: {($ VSub_Number "$1")} spids: [242] ) ] spids: [242] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:us) op: Equal rhs: {($ VSub_Number "$2")} spids: [246] ) ] spids: [246] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:them) op: Equal rhs: {($ VSub_Number "$3")} spids: [250] ) ] spids: [250] ) (C {(test_expect_success)} { (DQ ("detect delete/modechange conflict (") ($ VSub_Name "$strategy") (", ") ($ VSub_Name "$us") (")") ) } { (SQ <"\n"> <"\t\tgit reset --hard &&\n"> <"\t\tgit checkout $us &&\n"> <"\t\ttest_must_fail git merge -s $strategy $them\n"> <"\t"> ) } ) ] spids: [239] ) spids: [234 238] ) (C {(do_delete_modechange)} {(recursive)} {(b1)} {(deletion)}) (C {(do_delete_modechange)} {(recursive)} {(deletion)} {(b1)}) (C {(do_delete_modechange)} {(resolve)} {(b1)} {(deletion)}) (C {(do_delete_modechange)} {(resolve)} {(deletion)} {(b1)}) (C {(test_done)}) ] )