(CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(SQ <'Test cherry-pick -x and -s'>)} spids: [4] ) ] spids: [4] ) (C {(.)} {(./test-lib.sh)}) (FuncDef name: pristine_detach body: (BraceGroup children: [ (AndOr ops: [Op_DAmp Op_DAmp Op_DAmp] children: [ (C {(git)} {(cherry-pick)} {(--quit)}) (C {(git)} {(checkout)} {(-f)} {(DQ ($ VSub_Number '$1') ('^0'))}) (C {(git)} {(read-tree)} {(-u)} {(--reset)} {(HEAD)}) (C {(git)} {(clean)} {(-d)} {(-f)} {(-f)} {(-q)} {(-x)}) ] ) ] spids: [20] ) spids: [15 19] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:mesg_one_line) op: Equal rhs: {(SQ <'base: commit message'>)} spids: [76] ) ] spids: [76] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:mesg_no_footer) op: Equal rhs: {(DQ ($ VSub_Name '$mesg_one_line') ('\n') ('\n') (OneWordBodyThatsNotA-S-o-B))} spids: [82] ) ] spids: [82] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:mesg_with_footer) op: Equal rhs: { (DQ ($ VSub_Name '$mesg_no_footer') ('\n') ('\n') ('Signed-off-by: ') ($ VSub_Name '$GIT_COMMITTER_NAME') (' <') ($ VSub_Name '$GIT_COMMITTER_EMAIL') ('>\n') ('Signed-off-by: A.U. Thor <author@example.com>\n') ('Signed-off-by: B.U. Thor <buthor@example.com>') ) } spids: [91] ) ] spids: [91] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:mesg_broken_footer) op: Equal rhs: { (DQ ($ VSub_Name '$mesg_no_footer') ('\n') ('\n') ('The signed-off-by string should begin with the words Signed-off-by followed\n') ('by a colon and space, and then the signers name and email address. e.g.\n') ('Signed-off-by: ') ($ VSub_Name '$GIT_COMMITTER_NAME') (' <') ($ VSub_Name '$GIT_COMMITTER_EMAIL') ('>') ) } spids: [106] ) ] spids: [106] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:mesg_with_footer_sob) op: Equal rhs: { (DQ ($ VSub_Name '$mesg_with_footer') ('\n') ('Signed-off-by: ') ($ VSub_Name '$GIT_COMMITTER_NAME') (' <') ($ VSub_Name '$GIT_COMMITTER_EMAIL') ('>') ) } spids: [121] ) ] spids: [121] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:mesg_with_cherry_footer) op: Equal rhs: { (DQ ($ VSub_Name '$mesg_with_footer_sob') ('\n') ('(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)\n') ('Tested-by: C.U. Thor <cuthor@example.com>') ) } spids: [133] ) ] spids: [133] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:mesg_unclean) op: Equal rhs: { (DQ ($ VSub_Name '$mesg_one_line') ('\n') ('\n') ('\n') ('leading empty lines\n') ('\n') ('\n') ('consecutive empty lines\n') ('\n') ('# hash tag comment\n') ('\n') ('trailing empty lines\n') ('\n') ('\n') ) } spids: [142] ) ] spids: [142] ) (C {(test_expect_success)} {(setup)} { (SQ <'\n'> <'\tgit config advice.detachedhead false &&\n'> <'\techo unrelated >unrelated &&\n'> <'\tgit add unrelated &&\n'> <'\ttest_commit initial foo a &&\n'> <'\ttest_commit "$mesg_one_line" foo b mesg-one-line &&\n'> <'\tgit reset --hard initial &&\n'> <'\ttest_commit "$mesg_no_footer" foo b mesg-no-footer &&\n'> <'\tgit reset --hard initial &&\n'> <'\ttest_commit "$mesg_broken_footer" foo b mesg-broken-footer &&\n'> <'\tgit reset --hard initial &&\n'> <'\ttest_commit "$mesg_with_footer" foo b mesg-with-footer &&\n'> <'\tgit reset --hard initial &&\n'> <'\ttest_commit "$mesg_with_footer_sob" foo b mesg-with-footer-sob &&\n'> <'\tgit reset --hard initial &&\n'> <'\ttest_commit "$mesg_with_cherry_footer" foo b mesg-with-cherry-footer &&\n'> <'\tgit reset --hard initial &&\n'> <'\ttest_config commit.cleanup verbatim &&\n'> <'\ttest_commit "$mesg_unclean" foo b mesg-unclean &&\n'> <'\ttest_unconfig commit.cleanup &&\n'> <'\tpristine_detach initial &&\n'> <'\ttest_commit conflicting unrelated\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick -x inserts blank line after one line subject'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tsha1=$(git rev-parse mesg-one-line^0) &&\n'> <'\tgit cherry-pick -x mesg-one-line &&\n'> <'\tcat <<-EOF >expect &&\n'> <'\t\t$mesg_one_line\n'> <'\n'> <'\t\t(cherry picked from commit $sha1)\n'> <'\tEOF\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick -s inserts blank line after one line subject'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tgit cherry-pick -s mesg-one-line &&\n'> <'\tcat <<-EOF >expect &&\n'> <'\t\t$mesg_one_line\n'> <'\n'> <'\t\tSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n'> <'\tEOF\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick -s inserts blank line after non-conforming footer'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tgit cherry-pick -s mesg-broken-footer &&\n'> <'\tcat <<-EOF >expect &&\n'> <'\t\t$mesg_broken_footer\n'> <'\n'> <'\t\tSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n'> <'\tEOF\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick -x inserts blank line when conforming footer not found'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tsha1=$(git rev-parse mesg-no-footer^0) &&\n'> <'\tgit cherry-pick -x mesg-no-footer &&\n'> <'\tcat <<-EOF >expect &&\n'> <'\t\t$mesg_no_footer\n'> <'\n'> <'\t\t(cherry picked from commit $sha1)\n'> <'\tEOF\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick -s inserts blank line when conforming footer not found'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tgit cherry-pick -s mesg-no-footer &&\n'> <'\tcat <<-EOF >expect &&\n'> <'\t\t$mesg_no_footer\n'> <'\n'> <'\t\tSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n'> <'\tEOF\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick -x -s inserts blank line when conforming footer not found'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tsha1=$(git rev-parse mesg-no-footer^0) &&\n'> <'\tgit cherry-pick -x -s mesg-no-footer &&\n'> <'\tcat <<-EOF >expect &&\n'> <'\t\t$mesg_no_footer\n'> <'\n'> <'\t\t(cherry picked from commit $sha1)\n'> <'\t\tSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n'> <'\tEOF\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick -s adds sob when last sob doesnt match committer'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tgit cherry-pick -s mesg-with-footer &&\n'> <'\tcat <<-EOF >expect &&\n'> <'\t\t$mesg_with_footer\n'> <'\t\tSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n'> <'\tEOF\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick -x -s adds sob when last sob doesnt match committer'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tsha1=$(git rev-parse mesg-with-footer^0) &&\n'> <'\tgit cherry-pick -x -s mesg-with-footer &&\n'> <'\tcat <<-EOF >expect &&\n'> <'\t\t$mesg_with_footer\n'> <'\t\t(cherry picked from commit $sha1)\n'> <'\t\tSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n'> <'\tEOF\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick -s refrains from adding duplicate trailing sob'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tgit cherry-pick -s mesg-with-footer-sob &&\n'> <'\tcat <<-EOF >expect &&\n'> <'\t\t$mesg_with_footer_sob\n'> <'\tEOF\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick -x -s adds sob even when trailing sob exists for committer'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tsha1=$(git rev-parse mesg-with-footer-sob^0) &&\n'> <'\tgit cherry-pick -x -s mesg-with-footer-sob &&\n'> <'\tcat <<-EOF >expect &&\n'> <'\t\t$mesg_with_footer_sob\n'> <'\t\t(cherry picked from commit $sha1)\n'> <'\t\tSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n'> <'\tEOF\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick -x treats "(cherry picked from..." line as part of footer'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tsha1=$(git rev-parse mesg-with-cherry-footer^0) &&\n'> <'\tgit cherry-pick -x mesg-with-cherry-footer &&\n'> <'\tcat <<-EOF >expect &&\n'> <'\t\t$mesg_with_cherry_footer\n'> <'\t\t(cherry picked from commit $sha1)\n'> <'\tEOF\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick -s treats "(cherry picked from..." line as part of footer'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tgit cherry-pick -s mesg-with-cherry-footer &&\n'> <'\tcat <<-EOF >expect &&\n'> <'\t\t$mesg_with_cherry_footer\n'> <'\t\tSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n'> <'\tEOF\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick -x -s treats "(cherry picked from..." line as part of footer'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tsha1=$(git rev-parse mesg-with-cherry-footer^0) &&\n'> <'\tgit cherry-pick -x -s mesg-with-cherry-footer &&\n'> <'\tcat <<-EOF >expect &&\n'> <'\t\t$mesg_with_cherry_footer\n'> <'\t\t(cherry picked from commit $sha1)\n'> <'\t\tSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n'> <'\tEOF\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'cherry-pick preserves commit message'>)} { (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tprintf "$mesg_unclean" >expect &&\n'> <'\tgit log -1 --pretty=format:%B mesg-unclean >actual &&\n'> <'\ttest_cmp expect actual &&\n'> <'\tgit cherry-pick mesg-unclean &&\n'> <'\tgit log -1 --pretty=format:%B >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_done)}) ] )