Now maintainers or developers can also use commit --trailer="Signed-off-by:commiter<email>" from the command line to provide trailers to commit messages. This solution may be more generalized than v1. ZheNing Hu (3): [GSOC] commit: add --trailer option interpret-trailers: add own-identity option commit: add own-identity option Documentation/git-commit.txt | 25 +- Documentation/git-interpret-trailers.txt | 14 + builtin/commit.c | 31 ++ builtin/interpret-trailers.c | 6 +- t/t7501-commit-basic-functionality.sh | 91 ++++++ t/t7502-commit-porcelain.sh | 356 +++++++++++++++++++++++ t/t7513-interpret-trailers.sh | 12 + trailer.c | 18 +- trailer.h | 3 +- 9 files changed, 550 insertions(+), 6 deletions(-) base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945 Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v10 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v10 Pull-Request: https://github.com/gitgitgadget/git/pull/901 Range-diff vs v9: 1: e524c4ba5dc1 ! 1: 949faf9ee56a [GSOC] commit: add --trailer option @@ Documentation/git-commit.txt: The `-m` option is mutually exclusive with `-c`, ` + <committer@xxxxxxxxxxx>" --trailer "Helped-by:C O Mitter \ + <committer@xxxxxxxxxxx>"` will add the "Signed-off-by" trailer + and the "Helped-by" trailer in the commit message.) -+ See linkgit:git-interpret-trailers[1] for details. ++ Use `git -c trailer.* commit --trailer` to make the appropriate ++ configuration. See linkgit:git-interpret-trailers[1] for details. -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks. @@ builtin/commit.c: static int prepare_to_commit(const char *index_file, const cha + "--in-place", git_path_commit_editmsg(), NULL); + strvec_pushv(&run_trailer.args, trailer_args.v); + run_trailer.git_cmd = 1; -+ if (run_command(&run_trailer)) -+ strvec_clear(&run_trailer.args); ++ if (run_command(&run_trailer)) { ++ die(_("unable to pass tailers to --trailers")); ++ } + strvec_clear(&trailer_args); + } + @@ builtin/commit.c: int cmd_commit(int argc, const char **argv, const char *prefix OPT_STRING(0, "fixup", &fixup_message, N_("commit"), N_("use autosquash formatted message to fixup specified commit")), OPT_STRING(0, "squash", &squash_message, N_("commit"), N_("use autosquash formatted message to squash specified commit")), OPT_BOOL(0, "reset-author", &renew_authorship, N_("the commit is authored by me now (used with -C/-c/--amend)")), -+ OPT_CALLBACK_F(0, "trailer", NULL, N_("trailer"), N_("trailer(s) to add"), PARSE_OPT_NONEG, opt_pass_trailer), ++ OPT_CALLBACK_F(0, "trailer", NULL, N_("trailer"), N_("add custom trailer(s)"), PARSE_OPT_NONEG, opt_pass_trailer), OPT_BOOL('s', "signoff", &signoff, N_("add a Signed-off-by trailer")), OPT_FILENAME('t', "template", &template_file, N_("use specified template file")), OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")), @@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' ' ' -+test_expect_success 'trailer' ' -+ >file1 && -+ git add file1 && -+ git commit -s --trailer "Signed-off-by:C O Mitter1 <committer1@xxxxxxxxxxx>" \ -+ --trailer "Helped-by:C O Mitter2 <committer2@xxxxxxxxxxx>" \ -+ --trailer "Reported-by:C O Mitter3 <committer3@xxxxxxxxxxx>" \ -+ --trailer "Mentored-by:C O Mitter4 <committer4@xxxxxxxxxxx>" \ ++test_expect_success 'commit --trailer without -c' ' ++ echo "fun" >>file && ++ git add file && ++ cat >expected <<-\EOF && ++ ++ Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> ++ Signed-off-by: C1 E1 ++ Helped-by: C2 E2 ++ Reported-by: C3 E3 ++ Mentored-by: C4 E4 ++ EOF ++ git commit -s --trailer "Signed-off-by:C1 E1 " \ ++ --trailer "Helped-by:C2 E2 " \ ++ --trailer "Reported-by:C3 E3" \ ++ --trailer "Mentored-by:C4 E4" \ + -m "hello" && + git cat-file commit HEAD >commit.msg && -+ sed -e "1,7d" commit.msg >actual && ++ sed -e "1,6d" commit.msg >actual && ++ test_cmp expected actual ++' ++ ++test_expect_success 'commit --trailer with -c and "replace" as ifexists' ' ++ echo "fun" >>file1 && ++ git add file1 && ++ cat >expected <<-\EOF && ++ ++ Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> ++ Signed-off-by: C1 E1 ++ Reported-by: C3 E3 ++ Mentored-by: C4 E4 ++ Helped-by: C3 E3 ++ EOF ++ git -c trailer.ifexists="replace" \ ++ commit --trailer "Mentored-by: C4 E4" \ ++ --trailer "Helped-by: C3 E3" \ ++ --amend && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,6d" commit.msg >actual && ++ test_cmp expected actual ++' ++ ++test_expect_success 'commit --trailer with -c and "add" as ifexists' ' ++ echo "fun" >>file1 && ++ git add file1 && ++ cat >expected <<-\EOF && ++ ++ Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> ++ Signed-off-by: C1 E1 ++ Reported-by: C3 E3 ++ Mentored-by: C4 E4 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ EOF ++ git -c trailer.ifexists="add" \ ++ commit --trailer "Helped-by: C3 E3" \ ++ --trailer "Helped-by: C3 E3" \ ++ --amend && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,6d" commit.msg >actual && ++ test_cmp expected actual ++' ++ ++test_expect_success 'commit --trailer with -c and "donothing" as ifexists' ' ++ echo "fun" >>file1 && ++ git add file1 && + cat >expected <<-\EOF && ++ + Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> -+ Signed-off-by: C O Mitter1 <committer1@xxxxxxxxxxx> -+ Helped-by: C O Mitter2 <committer2@xxxxxxxxxxx> -+ Reported-by: C O Mitter3 <committer3@xxxxxxxxxxx> -+ Mentored-by: C O Mitter4 <committer4@xxxxxxxxxxx> ++ Signed-off-by: C1 E1 ++ Reported-by: C3 E3 ++ Mentored-by: C4 E4 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Reviewed-by: C6 E6 + EOF ++ git -c trailer.ifexists="donothing" \ ++ commit --trailer "Mentored-by: C5 E5" \ ++ --trailer "Reviewed-by: C6 E6" \ ++ --amend && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,6d" commit.msg >actual && ++ test_cmp expected actual ++' ++ ++test_expect_success 'commit --trailer with -c and "addIfDifferent" as ifexists' ' ++ echo "fun" >>file1 && ++ git add file1 && ++ cat >expected <<-\EOF && ++ ++ Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> ++ Signed-off-by: C1 E1 ++ Reported-by: C3 E3 ++ Mentored-by: C4 E4 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Reviewed-by: C6 E6 ++ Reported-by: C5 E5 ++ EOF ++ git -c trailer.ifexists="addIfDifferent" \ ++ commit --trailer "Reviewed-by: C6 E6" \ ++ --trailer "Reported-by: C5 E5" \ ++ --amend && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,6d" commit.msg >actual && ++ test_cmp expected actual ++' ++ ++test_expect_success 'commit --trailer with -c and "addIfDifferentNeighbor" as ifexists' ' ++ echo "fun" >>file1 && ++ git add file1 && ++ cat >expected <<-\EOF && ++ ++ Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> ++ Signed-off-by: C1 E1 ++ Reported-by: C3 E3 ++ Mentored-by: C4 E4 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Reviewed-by: C6 E6 ++ Reported-by: C5 E5 ++ EOF ++ git -c trailer.ifexists="addIfDifferent" \ ++ commit --trailer "Reported-by: C5 E5" \ ++ --trailer "Reviewed-by: C6 E6" \ ++ --amend && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,6d" commit.msg >actual && ++ test_cmp expected actual ++' ++ ++test_expect_success 'commit --trailer with -c and "end" as where' ' ++ echo "fun" >>file1 && ++ git add file1 && ++ cat >expected <<-\EOF && ++ ++ Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> ++ Signed-off-by: C1 E1 ++ Reported-by: C3 E3 ++ Mentored-by: C4 E4 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Reviewed-by: C6 E6 ++ Reported-by: C5 E5 ++ Reported-by: C7 E7 ++ EOF ++ git -c trailer.where="end" \ ++ commit --trailer "Reported-by: C5 E5" \ ++ --trailer "Reported-by: C7 E7" \ ++ --amend && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,6d" commit.msg >actual && ++ test_cmp expected actual ++' ++ ++test_expect_success 'commit --trailer with -c and "start" as where' ' ++ echo "fun" >>file1 && ++ git add file1 && ++ cat >expected <<-\EOF && ++ ++ Signed-off-by: C8 E8 ++ Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> ++ Signed-off-by: C1 E1 ++ Reported-by: C3 E3 ++ Mentored-by: C4 E4 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Reviewed-by: C6 E6 ++ Reported-by: C5 E5 ++ Reported-by: C7 E7 ++ EOF ++ git -c trailer.where="start" \ ++ commit --trailer "Signed-off-by: C8 E8" \ ++ --trailer "Signed-off-by: C8 E8" \ ++ --amend && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,6d" commit.msg >actual && ++ test_cmp expected actual ++' ++ ++test_expect_success 'commit --trailer with -c and "after" as where' ' ++ echo "fun" >>file1 && ++ git add file1 && ++ cat >expected <<-\EOF && ++ ++ Signed-off-by: C8 E8 ++ Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> ++ Signed-off-by: C1 E1 ++ Reported-by: C3 E3 ++ Mentored-by: C4 E4 ++ Mentored-by: C9 E9 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Reviewed-by: C6 E6 ++ Reported-by: C5 E5 ++ Reported-by: C7 E7 ++ Reported-by: C10 E10 ++ EOF ++ git -c trailer.where="after" \ ++ commit --trailer "Mentored-by: C9 E9" \ ++ --trailer "Reported-by: C10 E10" \ ++ --amend && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,6d" commit.msg >actual && ++ test_cmp expected actual ++' ++ ++test_expect_success 'commit --trailer with -c and "before" as where' ' ++ echo "fun" >>file1 && ++ git add file1 && ++ cat >expected <<-\EOF && ++ ++ Signed-off-by: C8 E8 ++ Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> ++ Signed-off-by: C1 E1 ++ Reported-by: C11 E11 ++ Reported-by: C3 E3 ++ Mentored-by: C4 E4 ++ Mentored-by: C9 E9 ++ Helped-by: C12 E12 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Reviewed-by: C6 E6 ++ Reported-by: C5 E5 ++ Reported-by: C7 E7 ++ Reported-by: C10 E10 ++ EOF ++ git -c trailer.where="before" \ ++ commit --trailer "Helped-by: C12 E12" \ ++ --trailer "Reported-by: C11 E11" \ ++ --amend && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,6d" commit.msg >actual && ++ test_cmp expected actual ++' ++ ++test_expect_success 'commit --trailer with -c and "donothing" as ifmissing' ' ++ echo "fun" >>file1 && ++ git add file1 && ++ cat >expected <<-\EOF && ++ ++ Signed-off-by: C8 E8 ++ Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> ++ Signed-off-by: C1 E1 ++ Reported-by: C11 E11 ++ Reported-by: C3 E3 ++ Mentored-by: C4 E4 ++ Mentored-by: C9 E9 ++ Helped-by: C12 E12 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Reviewed-by: C6 E6 ++ Reported-by: C5 E5 ++ Reported-by: C7 E7 ++ Reported-by: C10 E10 ++ Helped-by: C12 E12 ++ EOF ++ git -c trailer.ifmissing="donothing" \ ++ commit --trailer "Helped-by: C12 E12" \ ++ --trailer "Based-by: C13 E13" \ ++ --amend && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,6d" commit.msg >actual && ++ test_cmp expected actual ++' ++ ++test_expect_success 'commit --trailer with -c and "add" as ifmissing' ' ++ echo "fun" >>file1 && ++ git add file1 && ++ cat >expected <<-\EOF && ++ ++ Signed-off-by: C8 E8 ++ Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> ++ Signed-off-by: C1 E1 ++ Reported-by: C11 E11 ++ Reported-by: C3 E3 ++ Mentored-by: C4 E4 ++ Mentored-by: C9 E9 ++ Helped-by: C12 E12 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Helped-by: C3 E3 ++ Reviewed-by: C6 E6 ++ Reported-by: C5 E5 ++ Reported-by: C7 E7 ++ Reported-by: C10 E10 ++ Helped-by: C12 E12 ++ Based-by: C13 E13 ++ EOF ++ git -c trailer.ifmissing="add" \ ++ commit --trailer "Helped-by: C12 E12" \ ++ --trailer "Based-by: C13 E13" \ ++ --amend && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,6d" commit.msg >actual && ++ test_cmp expected actual ++' ++ ++test_expect_success 'commit --trailer with -c and "=" as separators' ' ++ echo "fun" >>file1 && ++ git add file1 && ++ cat >expected <<-\EOF && ++ ++ Acked-by= Peff ++ EOF ++ git -c trailer.separators="=" \ ++ -c trailer.ack.key="Acked-by= " \ ++ commit --trailer "ack = Peff" -m "hello" && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,6d" commit.msg >actual && ++ test_cmp expected actual ++' ++ ++test_expect_success 'commit --trailer with -c and ":=#" as separators' ' ++ echo "fun" >>file1 && ++ git add file1 && ++ cat >expected <<-\EOF && ++ ++ Bug #42 ++ EOF ++ git -c trailer.separators=":=#" \ ++ -c trailer.bug.key="Bug #" \ ++ commit --trailer "bug = 42" -m "I hate bug" && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,6d" commit.msg >actual && + test_cmp expected actual +' + -: ------------ > 2: 42590e95deee interpret-trailers: add own-identity option -: ------------ > 3: 2dfcc20f0e9f commit: add own-identity option -- gitgitgadget