(command.CommandList children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:test_description) op: assign_op.Equal rhs: {(SQ <'git p4 preserve users'>)} spids: [4] ) ] ) (C {<.>} {<'./lib-git-p4.sh'>}) (C {<test_expect_success>} {(SQ <'start p4d'>)} {(SQ <'\n'> <'\tstart_p4d\n'>)}) (C {<test_expect_success>} {(SQ <'create files'>)} { (SQ <'\n'> <'\t(\n'> <'\t\tcd "$cli" &&\n'> <'\t\tp4 client -o | sed "/LineEnd/s/:.*/:unix/" | p4 client -i &&\n'> <'\t\techo file1 >file1 &&\n'> <'\t\techo file2 >file2 &&\n'> <'\t\tp4 add file1 file2 &&\n'> <'\t\tp4 submit -d "add files"\n'> <'\t)\n'> ) } ) (command.ShFunction name: p4_grant_admin body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp] children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:name) op: assign_op.Equal rhs: {($ Id.VSub_Number '$1')} spids: [53] ) ] ) (command.Pipeline children: [ (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<p4>} {<protect>} {<-o>}) (C {<echo>} { (DQ <' admin user '> ($ Id.VSub_DollarName '$name') <' * //depot/...'> ) } ) ] ) ] ) (C {<p4>} {<protect>} {<-i>}) ] negated: F ) ] ) ] ) ) (command.ShFunction name: p4_check_commit_author body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp] children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:file) op: assign_op.Equal rhs: {($ Id.VSub_Number '$1')} spids: [100] ) (assign_pair lhs: (sh_lhs_expr.Name name:user) op: assign_op.Equal rhs: {($ Id.VSub_Number '$2')} spids: [103] ) ] ) (command.Pipeline children: [ (C {<p4>} {<changes>} {<-m>} {<1>} {<'//depot/'> ($ Id.VSub_DollarName '$file')}) (C {<grep>} {<-q>} {($ Id.VSub_DollarName '$user')}) ] negated: F ) ] ) ] ) ) (command.ShFunction name: make_change_by_user body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp] children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:file) op: assign_op.Equal rhs: {($ Id.VSub_Number '$1')} spids: [138] ) (assign_pair lhs: (sh_lhs_expr.Name name:name) op: assign_op.Equal rhs: {($ Id.VSub_Number '$2')} spids: [141] ) (assign_pair lhs: (sh_lhs_expr.Name name:email) op: assign_op.Equal rhs: {($ Id.VSub_Number '$3')} spids: [144] ) ] ) (command.Simple words: [{<echo>} {(DQ <'username: a change by '> ($ Id.VSub_DollarName '$name'))}] redirects: [ (redir op: <Id.Redir_DGreat '>>'> loc: (redir_loc.Fd fd:1) arg: {(DQ ($ Id.VSub_DollarName '$file'))} ) ] do_fork: T ) (C {<git>} {<add>} {(DQ ($ Id.VSub_DollarName '$file'))}) (C {<git>} {<commit>} {<--author>} {(DQ ($ Id.VSub_DollarName '$name') <' <'> ($ Id.VSub_DollarName '$email') <'>'>)} {<-m>} {(DQ <'a change by '> ($ Id.VSub_DollarName '$name'))} ) ] ) ] ) ) (C {<test_expect_success>} {(SQ <'preserve users'>)} { (SQ <'\n'> <'\tp4_add_user alice &&\n'> <'\tp4_add_user bob &&\n'> <'\tp4_grant_admin alice &&\n'> <'\tgit p4 clone --dest="$git" //depot &&\n'> <'\ttest_when_finished cleanup_git &&\n'> <'\t(\n'> <'\t\tcd "$git" &&\n'> <'\t\techo "username: a change by alice" >>file1 &&\n'> <'\t\techo "username: a change by bob" >>file2 &&\n'> <'\t\tgit commit --author "Alice <alice@example.com>" -m "a change by alice" file1 &&\n'> <'\t\tgit commit --author "Bob <bob@example.com>" -m "a change by bob" file2 &&\n'> <'\t\tgit config git-p4.skipSubmitEditCheck true &&\n'> <'\t\tP4EDITOR="test-chmtime +5" P4USER=alice P4PASSWD=secret &&\n'> <'\t\texport P4EDITOR P4USER P4PASSWD &&\n'> <'\t\tgit p4 commit --preserve-user &&\n'> <'\t\tp4_check_commit_author file1 alice &&\n'> <'\t\tp4_check_commit_author file2 bob\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'refuse to preserve users without perms'>)} { (SQ <'\n'> <'\tgit p4 clone --dest="$git" //depot &&\n'> <'\ttest_when_finished cleanup_git &&\n'> <'\t(\n'> <'\t\tcd "$git" &&\n'> <'\t\tgit config git-p4.skipSubmitEditCheck true &&\n'> <'\t\techo "username-noperms: a change by alice" >>file1 &&\n'> <'\t\tgit commit --author "Alice <alice@example.com>" -m "perms: a change by alice" file1 &&\n'> <'\t\tP4EDITOR="test-chmtime +5" P4USER=bob P4PASSWD=secret &&\n'> <'\t\texport P4EDITOR P4USER P4PASSWD &&\n'> <'\t\ttest_must_fail git p4 commit --preserve-user &&\n'> <'\t\t! git diff --exit-code HEAD..p4/master\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'preserve user where author is unknown to p4'>)} { (SQ <'\n'> <'\tgit p4 clone --dest="$git" //depot &&\n'> <'\ttest_when_finished cleanup_git &&\n'> <'\t(\n'> <'\t\tcd "$git" &&\n'> <'\t\tgit config git-p4.skipSubmitEditCheck true &&\n'> <'\t\techo "username-bob: a change by bob" >>file1 &&\n'> <'\t\tgit commit --author "Bob <bob@example.com>" -m "preserve: a change by bob" file1 &&\n'> <'\t\techo "username-unknown: a change by charlie" >>file1 &&\n'> < '\t\tgit commit --author "Charlie <charlie@example.com>" -m "preserve: a change by charlie" file1 &&\n' > <'\t\tP4EDITOR="test-chmtime +5" P4USER=alice P4PASSWD=secret &&\n'> <'\t\texport P4EDITOR P4USER P4PASSWD &&\n'> <'\t\ttest_must_fail git p4 commit --preserve-user &&\n'> <'\t\t! git diff --exit-code HEAD..p4/master &&\n'> <'\n'> <'\t\techo "$0: repeat with allowMissingP4Users enabled" &&\n'> <'\t\tgit config git-p4.allowMissingP4Users true &&\n'> <'\t\tgit config git-p4.preserveUser true &&\n'> <'\t\tgit p4 commit &&\n'> <'\t\tgit diff --exit-code HEAD..p4/master &&\n'> <'\t\tp4_check_commit_author file1 alice\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'not preserving user with mixed authorship'>)} { (SQ <'\n'> <'\tgit p4 clone --dest="$git" //depot &&\n'> <'\ttest_when_finished cleanup_git &&\n'> <'\t(\n'> <'\t\tcd "$git" &&\n'> <'\t\tgit config git-p4.skipSubmitEditCheck true &&\n'> <'\t\tp4_add_user derek &&\n'> <'\n'> <'\t\tmake_change_by_user usernamefile3 Derek derek@example.com &&\n'> <'\t\tP4EDITOR=cat P4USER=alice P4PASSWD=secret &&\n'> <'\t\texport P4EDITOR P4USER P4PASSWD &&\n'> <'\t\tgit p4 commit |\\\n'> <'\t\tgrep "git author derek@example.com does not match" &&\n'> <'\n'> <'\t\tmake_change_by_user usernamefile3 Charlie charlie@example.com &&\n'> <'\t\tgit p4 commit |\\\n'> <'\t\tgrep "git author charlie@example.com does not match" &&\n'> <'\n'> <'\t\tmake_change_by_user usernamefile3 alice alice@example.com &&\n'> <'\t\tgit p4 commit |\\\n'> <'\t\ttest_must_fail grep "git author.*does not match" &&\n'> <'\n'> <'\t\tgit config git-p4.skipUserNameCheck true &&\n'> <'\t\tmake_change_by_user usernamefile3 Charlie charlie@example.com &&\n'> <'\t\tgit p4 commit |\\\n'> <'\t\ttest_must_fail grep "git author.*does not match" &&\n'> <'\n'> <'\t\tp4_check_commit_author usernamefile3 alice\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'kill p4d'>)} {(SQ <'\n'> <'\tkill_p4d\n'>)}) (C {<test_done>}) ] )