commit: provides multiple common signatures
PATCH 1/1 commit: provides multiple common signatures
From: ZheNing Hu <[email protected]>
Similar to "Helped-by", "Reported-by", "Reviewed-by", "Mentored-by" these signatures are often seen in git commit messages. After referring to the simple implementation of commit --signoff and send-email -cc=" commiter <email>", I am considering whether to provide multiple signature parameters from the command line. I think this might help maintainers and developers directly uses the shell to provide these signatures instead of multiple times repetitive writing those trailers each time.
To achieve this goal, i refactored the append_signoff design and provided append_message and append_message_string_list interfaces, providing new ways to generate those various signatures.
Users now can use commit -H "helper <eamil>" to generate "Helped-by" trailer, commit -R "reviewer <eamil>" to generate "Reviewed-by" trailer, commit -r "reporter <eamil> "to generate "Reported-by" trailer, commit -M "mentor <eamil>" to generate "Mentored-by" trailer.
---
[GSOC] commit: provides multiple signatures from command line
I don’t know if my idea will satisfy everyone, I'm also thinking about whether we can provide a more generalized version (I think this idea can be extended: because users and developers have other signature methods that they want, such as "Based-on-patch-by") I hope someone can give me pointers (on the correctness of ideas or codes)
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Documentation/git-commit.txt | 24 +++++++- builtin/commit.c | 63 +++++++++++++++++++++ sequencer.c | 40 +++++++++---- sequencer.h | 4 ++ t/t7502-commit-porcelain.sh | 106 +++++++++++++++++++++++++++++++++++ 5 files changed, 226 insertions(+), 11 deletions(-)
Documentation/git-commit.txt +23 -1
@@ -14,7 +14,9 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(-H|--helped-by)=<address>...] + [(-R|--reviewed-by)=<address>...] [(-r|--reported-by)=<address>...] + [(-M|--mentored)=<address>...] DESCRIPTION -----------
@@ -166,6 +168,26 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +-H=<address>...:: +--helped-by=<address>...:: + Add one or more `Helped-by` trailer by the committer at the end of the commit + log message. + +-R=<address>...:: +--reviewed-by=<address>...:: + Add one or more `Reviewed-by` trailer by the committer at the end of the commit + log message. + +-r=<address>...:: +--reported-by=<address>...:: + Add one or more `Reported-by` trailer by the committer at the end of the commit + log message. + +-M=<address>...:: +--mentored-by=<address>...:: + Add one or more `Mentored-by` trailer by the committer at the end of the commit + log message. + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.
builtin/commit.c +63 -0
93 lines not on this page · raw message
sequencer.c +30 -10
@@ -4668,16 +4668,12 @@ int sequencer_pick_revisions(struct repository *r,return res; } -void append_signoff (struct strbuf *msgbuf,size_t ignore_footer,unsigned flag) +void append_message (struct strbuf *msgbuf,struct strbuf *sob, +size_t ignore_footer,unsigned flag) {unsigned no_dup_sob = flag &APPEND_SIGNOFF_DEDUP ; -struct strbuf sob =STRBUF_INIT ;int has_footer; -strbuf_addstr (&sob, sign_off_header); -strbuf_addstr (&sob,fmt_name (WANT_COMMITTER_IDENT )); -strbuf_addch (&sob,'\n' ); -if (!ignore_footer)strbuf_complete_line (msgbuf);
@@ -4685,11 +4681,11 @@ void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)* If the whole message buffer is equal to the sob, pretend that we * found a conforming footer with a matching sob */ -if (msgbuf->len - ignore_footer == sob.len && - !strncmp (msgbuf->buf, sob.buf, sob.len)) +if (msgbuf->len - ignore_footer == sob->len && + !strncmp (msgbuf->buf, sob->buf, sob->len)) has_footer =3 ;else - has_footer =has_conforming_footer (msgbuf, &sob, ignore_footer); + has_footer =has_conforming_footer (msgbuf, sob, ignore_footer);if (!has_footer) {const char *append_newlines =NULL ;
@@ -4723,8 +4719,32 @@ void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)if (has_footer !=3 && (!no_dup_sob || has_footer !=2 ))strbuf_splice (msgbuf, msgbuf->len - ignore_footer,0 , - sob.buf, sob.len); + sob->buf, sob->len); +} + +void append_signoff (struct strbuf *msgbuf,size_t ignore_footer,unsigned flag) +{ +struct strbuf sob =STRBUF_INIT ; +strbuf_addstr (&sob, sign_off_header); +strbuf_addstr (&sob,fmt_name (WANT_COMMITTER_IDENT )); +strbuf_addch (&sob,'\n' ); +append_message (msgbuf, &sob, ignore_footer, flag); +strbuf_release (&sob); +} +void append_message_string_list (struct strbuf *msgbuf,const char *header, +struct string_list *sobs,size_t ignore_footer,unsigned flag) { +int i; +struct strbuf sob =STRBUF_INIT ; + +for ( i =0 ; i < sobs->nr; i++) + { +strbuf_addstr (&sob, header); +strbuf_addstr (&sob, sobs->items[i].string); +strbuf_addch (&sob,'\n' ); +append_message (msgbuf, &sob, ignore_footer, flag); +strbuf_reset (&sob); + }strbuf_release (&sob); }
sequencer.h +4 -0
@@ -174,6 +174,10 @@ int todo_list_rearrange_squash(struct todo_list *todo_list);* and the new signoff will be spliced into the buffer before those bytes. */ void append_signoff (struct strbuf *msgbuf,size_t ignore_footer,unsigned flag); +void append_message (struct strbuf *msgbuf,struct strbuf *sob, +size_t ignore_footer,unsigned flag); +void append_message_string_list (struct strbuf *msgbuf,const char *header, +struct string_list *sobs,size_t ignore_footer,unsigned flag);void append_conflicts_hint (struct index_state *istate,struct strbuf *msgbuf,enum commit_msg_cleanup_mode cleanup_mode);
t/t7502-commit-porcelain.sh +106 -0
112 lines not on this page · raw message
base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945
Signature · 1 line
gitgitgadget
Hey!
The idea seems very useful to me though I am not sure what others feel about this and whether Git is ready for such a thing or not. Keeping this concern aside, I will still review the patch due to my own interest in it as well.
Quoted 4 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Similar to "Helped-by", "Reported-by", "Reviewed-by", "Mentored-by" these signatures are often seen in git commit messages. After
I think it will be better to rephrase the line so that it is easier to understand. It took me a couple of reads to figure out what you meant.
Something like:
Similar to "Signed-off-by", trailers such as "Reported-by", "Helped-by" and "Mentored-by" are also seen in Git commits.
Quoted 7 lines
referring to the simple implementation of
commit --signoffandsend-email -cc=" commiter <email>", I am considering whether to provide multiple signature parameters from the command line. I think this might help maintainers and developers directly uses the shell to provide these signatures instead of multiple times repetitive writing those trailers each time.
The above para is more appropriate for a cover letter than a commit message. Your thought process for the patch you sent is equally valuable but this does not belong in the commit message. Commit messages are more about what you did and any nuances that follow. You get me?
Use 'git format-patch --cover-letter <...>' to create a cover letter for your patch.
Quoted 3 lines
To achieve this goal, i refactored the
append_signoffdesign and providedappend_messageandappend_message_string_listinterfaces, providing new ways to generate those various signatures.
s/i/I
Also, commit messages are generally written in the imperative tense when desciribing what you have done in the commit.
Quoted 4 lines
Users now can use
commit -H "helper <eamil>"to generate "Helped-by" trailer,commit -R "reviewer <eamil>"to generate "Reviewed-by" trailer,commit -r "reporter <eamil> "to generate "Reported-by" trailer,commit -M "mentor <eamil>"to generate "Mentored-by" trailer.
Multiple typos.
Quoted 1 line
Signed-off-by ZheNing Hu <[email protected]>
So, an improved commit message could be:
-----8<-----
commit: support multiple trailers from the command line
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. Extend this list to include other commonly used trailers viz., "Helped-by", "Reviewed-by", "Reported-by" and "Mentored-by". Introduce options '-H', '-R', '-r' and '-M' corresponding to the aforementioned trailers.
While at it, add tests in the script 't7502-commit-porcelain.sh' and add information regarding these options in the Documentation of 'git commit'.
----->8-----
Quoted 7 lines
[GSOC] commit: provides multiple signatures from command line
I don’t know if my idea will satisfy everyone, I'm also thinking about whether we can provide a more generalized version (I think this idea can be extended: because users and developers have other signature methods that they want, such as "Based-on-patch-by") I hope someone can give me pointers (on the correctness of ideas or codes)
It will be great if we let the user add customised options for the respective trailers but I think that trying to cater to such a large audience will only complicate the whole process and decrease the support avialable for the options/command. Apart from this, I think that the trailer "Reviewed-by" may not be that widely used and it would be better if we remove it from this patch.
Quoted 35 lines
Documentation/git-commit.txt | 24 +++++++- builtin/commit.c | 63 +++++++++++++++++++++ sequencer.c | 40 +++++++++---- sequencer.h | 4 ++ t/t7502-commit-porcelain.sh | 106 +++++++++++++++++++++++++++++++++++ 5 files changed, 226 insertions(+), 11 deletions(-)Documentation/git-commit.txt +12
-1@@ -14,7 +14,9 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(-H|--helped-by)=<address>...] + [(-R|--reviewed-by)=<address>...] [(-r|--reported-by)=<address>...] + [(-M|--mentored)=<address>...] DESCRIPTION -----------@@ -166,6 +168,26 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +-H=<address>...:: +--helped-by=<address>...:: + Add one or more `Helped-by` trailer by the committer at the end of the commit + log message. + +-R=<address>...:: +--reviewed-by=<address>...:: + Add one or more `Reviewed-by` trailer by the committer at the end of the commit + log message.
Documentation/git-commit.txt The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. · line 189
Quoted 10 lines
Documentation/git-commit.txt +10
-0+ +-r=<address>...:: +--reported-by=<address>...:: + Add one or more `Reported-by` trailer by the committer at the end of the commit + log message. + +-M=<address>...:: +--mentored-by=<address>...:: + Add one or more `Mentored-by` trailer by the committer at the end of the commit + log message.
Oh! I did not think you had added long forms of these options and was about to comment on that. Good that you added. Do talk about them as well in the commit message.
Quoted 8 lines
Documentation/git-commit.txt +0
-0-n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.builtin/commit.c +0
-0
builtin/commit.c static int config_commit_verbose = -1; /* unspecified */ · line 119
Quoted 7 lines
builtin/commit.c +4
-0@@ -113,6 +113,10 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct string_list helped_by =STRING_LIST_INIT_NODUP ; +static struct string_list mentored_by =STRING_LIST_INIT_NODUP ; +static struct string_list reviewed_by =STRING_LIST_INIT_NODUP ; +static struct string_list reported_by =STRING_LIST_INIT_NODUP ;
Good that you kept the variables as 'string_list's instead of a usual 'char*'.
Quoted 4 lines
builtin/commit.c +0
-0/* * The default commit message cleanup mode will remove the lines @@ -829,6 +833,20 @@ static int prepare_to_commit(const char *index_file, const char *prefix,if (signoff)
builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 843
Quoted 10 lines
builtin/commit.c +8
-0append_signoff (&sb,ignore_non_trailer (sb.buf, sb.len),0 ); +if (helped_by.items) +append_message_string_list (&sb,"Helped-by: " , &helped_by,ignore_non_trailer (sb.buf, sb.len),0 ); +if (reviewed_by.items) +append_message_string_list (&sb,"Reviewed-by: " , &reviewed_by,ignore_non_trailer (sb.buf, sb.len),0 ); +if (reported_by.items) +append_message_string_list (&sb,"Reported-by: " , &reported_by,ignore_non_trailer (sb.buf, sb.len),0 ); +if (mentored_by.items) +append_message_string_list (&sb,"Mentored-by: " , &mentored_by,ignore_non_trailer (sb.buf, sb.len),0 );
I think this part will look prettier if you wrap around the text. For code segments, the wrap around limit is 80 chars. For commit messages its 72 chars. Wrap around means that as soon as you hit N number of characters, you proceed to the next(new) line.
Quoted 51 lines
builtin/commit.c +40
-0+string_list_clear (&helped_by,0 ); +string_list_clear (&reviewed_by,0 ); +string_list_clear (&reported_by,0 ); +string_list_clear (&mentored_by,0 ); +if (fwrite (sb.buf,1 , sb.len, s->fp) < sb.len)die_errno (_ ("could not write commit template" ));@@ -1490,6 +1508,42 @@ static int git_commit_config(const char *k, const char *v, void *cb)return git_status_config (k, v, s); } +static int help_callback (const struct option *opt,const char *arg,int unset) +{ +if (unset) +string_list_clear (&helped_by,0 ); +else +string_list_append (&helped_by, arg); +return 0 ; +} + +static int review_callback (const struct option *opt,const char *arg,int unset) +{ +if (unset) +string_list_clear (&reviewed_by,0 ); +else +string_list_append (&reviewed_by, arg); +return 0 ; +} + +static int report_callback (const struct option *opt,const char *arg,int unset) +{ +if (unset) +string_list_clear (&reported_by,0 ); +else +string_list_append (&reported_by, arg); +return 0 ; +} + +static int mentor_callback (const struct option *opt,const char *arg,int unset) +{ +if (unset) +string_list_clear (&mentored_by,0 ); +else +string_list_append (&mentored_by, arg); +return 0 ; +}int cmd_commit (int argc,const char **argv,const char *prefix) {static struct wt_status s;
builtin/commit.c int cmd_commit(int argc, const char **argv, const char *prefix) · line 1567
Quoted 7 lines
builtin/commit.c +4
-0@@ -1507,6 +1561,10 @@ 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 ('H' ,"helped-by" ,NULL ,N_ ("email" ),N_ ("add a Helped-by trailer" ), help_callback), +OPT_CALLBACK ('r' ,"reported-by" ,NULL ,N_ ("email" ),N_ ("add a Reported-by trailer" ), report_callback), +OPT_CALLBACK ('R' ,"reviewed-by" ,NULL ,N_ ("email" ),N_ ("add a Reviewed-by trailer" ), review_callback), + OPT_CALLBACK('M', "mentored-by", NULL, N_("email"), N_("add a Mentored-by trailer"), mentor_callback),
It would be lovely if you could line wrap these above additions too!
Quoted 20 lines
builtin/commit.c +5
-0OPT_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")),@@ -1561,6 +1619,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix)struct commit_extra_header *extra =NULL ;struct strbuf err =STRBUF_INIT ; + helped_by.strdup_strings =1 ; + reviewed_by.strdup_strings =1 ; + reported_by.strdup_strings =1 ; + mentored_by.strdup_strings =1 ; +if (argc ==2 && !strcmp (argv[1 ],"-h" ))usage_with_options (builtin_commit_usage, builtin_commit_options);sequencer.c +0
-0
sequencer.c int sequencer_pick_revisions(struct repository *r, · line 4672
Quoted 6 lines
sequencer.c +2
-1@@ -4668,16 +4668,12 @@ int sequencer_pick_revisions(struct repository *r,return res; } -void append_signoff (struct strbuf *msgbuf,size_t ignore_footer,unsigned flag) +void append_message (struct strbuf *msgbuf,struct strbuf *sob, +size_t ignore_footer,unsigned flag)
Its nice to see that you generalised the pre-exisiting function instead of creating a new one(s) for the new trailers. Good.
It will be better to name 'struct strbuf *sob' to something more generic, maybe 'struct strbuf *trailer' since 'sob' stands for 'Signed-off-by' and since the function is becoming more generic, its contents should too.
Quoted 14 lines
sequencer.c +0
-5{unsigned no_dup_sob = flag &APPEND_SIGNOFF_DEDUP ; -struct strbuf sob =STRBUF_INIT ;int has_footer; -strbuf_addstr (&sob, sign_off_header); -strbuf_addstr (&sob,fmt_name (WANT_COMMITTER_IDENT )); -strbuf_addch (&sob,'\n' ); -if (!ignore_footer)strbuf_complete_line (msgbuf);@@ -4685,11 +4681,11 @@ void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)* If the whole message buffer is equal to the sob, pretend that we
sequencer.c void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag) · line 4688
Quoted 10 lines
sequencer.c +3
-3* found a conforming footer with a matching sob */ -if (msgbuf->len - ignore_footer == sob.len && - !strncmp (msgbuf->buf, sob.buf, sob.len)) +if (msgbuf->len - ignore_footer == sob->len && + !strncmp (msgbuf->buf, sob->buf, sob->len)) has_footer =3 ;else - has_footer =has_conforming_footer (msgbuf, &sob, ignore_footer); + has_footer =has_conforming_footer (msgbuf, sob, ignore_footer);
Again, rename the variables.
Quoted 8 lines
sequencer.c +1
-1if (!has_footer) {const char *append_newlines =NULL ;@@ -4723,8 +4719,32 @@ void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)if (has_footer !=3 && (!no_dup_sob || has_footer !=2 ))strbuf_splice (msgbuf, msgbuf->len - ignore_footer,0 , - sob.buf, sob.len); + sob->buf, sob->len);
sequencer.c void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag) · line 4732
Quoted 10 lines
sequencer.c +10
-0+} +void append_signoff (struct strbuf *msgbuf,size_t ignore_footer,unsigned flag) +{ +struct strbuf sob =STRBUF_INIT ; +strbuf_addstr (&sob, sign_off_header); +strbuf_addstr (&sob,fmt_name (WANT_COMMITTER_IDENT )); +strbuf_addch (&sob,'\n' ); +append_message (msgbuf, &sob, ignore_footer, flag); +strbuf_release (&sob); +}
I think it will be nice if you could use a flag to denote whether the entity to be appended is a 'sign-off' or not. This way when say the variable 'int signoff' is 1, then use the above part in the 'append_message()' function otherwise go with the flow that exists.
Quoted 5 lines
sequencer.c +5
-0+void append_message_string_list (struct strbuf *msgbuf,const char *header, +struct string_list *sobs,size_t ignore_footer,unsigned flag) { +int i; +struct strbuf sob =STRBUF_INIT ; +
sequencer.c void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag) · line 4749
Quoted 10 lines
sequencer.c +8
-0+for ( i =0 ; i < sobs->nr; i++) + { +strbuf_addstr (&sob, header); +strbuf_addstr (&sob, sobs->items[i].string); +strbuf_addch (&sob,'\n' ); +append_message (msgbuf, &sob, ignore_footer, flag); +strbuf_reset (&sob); + }strbuf_release (&sob); }
Similarly, here, if 'signoff = 0' then the above part goes on. Or another alternative can be to create a 'append_message_helper()' and shift the current contents of 'append_message()' into that and use the above function to work as per the value of signoff.
So a possible flow can be:
void append_message_string_list(...params...) {
if (signoff) {
..excecute the necessary segments and call the
'append_message_helper()' function...
} else {
..similarly here..
}
}This way we save ourselves some extra functions.
Quoted 5 lines
sequencer.h +0
-0
sequencer.h int todo_list_rearrange_squash(struct todo_list *todo_list); · line 183
Quoted 10 lines
sequencer.h +4
-0@@ -174,6 +174,10 @@ int todo_list_rearrange_squash(struct todo_list *todo_list);* and the new signoff will be spliced into the buffer before those bytes. */ void append_signoff (struct strbuf *msgbuf,size_t ignore_footer,unsigned flag); +void append_message (struct strbuf *msgbuf,struct strbuf *sob, +size_t ignore_footer,unsigned flag); +void append_message_string_list (struct strbuf *msgbuf,const char *header, +struct string_list *sobs,size_t ignore_footer,unsigned flag);void append_conflicts_hint (struct index_state *istate,struct strbuf *msgbuf,enum commit_msg_cleanup_mode cleanup_mode);
Then, these would have to be corrected too.
t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 155
Quoted 7 lines
t/t7502-commit-porcelain.sh +0
-0@@ -154,6 +154,112 @@ test_expect_success 'sign off' ' '
I feel that the tests deserve a commit of their own. A follow-up commit in this patch.
Quoted 4 lines
t/t7502-commit-porcelain.sh +4
-0+test_expect_success 'helped-by' ' + + >file1 && + git add file1 &&
t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 170
Quoted 10 lines
t/t7502-commit-porcelain.sh +10
-0+ git commit --helped-by="foo <bar@frotz>" \ + --helped-by="foo2 <bar2@frotz>" -m "thank you" && + git cat-file commit HEAD >commit.msg && + sed -ne "s/Helped-by: //p" commit.msg >actual && + cat >expected <<-\EOF && + foo <bar@frotz> + foo2 <bar2@frotz> + EOF + test_cmp expected actual +
Was this extra line feed intentional? It looks odd here and other test (scripts) don't have this. Though, this test script seems to have many tests which have an extra line feed. My suggestion would be to eliminate it. Maybe this script is old and hasn't been reviewed for a cleanup in a long time.
Quoted 6 lines
t/t7502-commit-porcelain.sh +6
-0+' + +test_expect_success 'reported-by' ' + + >file2 && + git add file2 &&
t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 186
Quoted 10 lines
t/t7502-commit-porcelain.sh +10
-0+ git commit --reported-by="foo <bar@frotz>" \ + --reported-by="foo2 <bar2@frotz>" -m "thank you" && + git cat-file commit HEAD >commit.msg && + sed -ne "s/Reported-by: //p" commit.msg >actual && + cat >expected <<-\EOF && + foo <bar@frotz> + foo2 <bar2@frotz> + EOF + test_cmp expected actual +
Similarly here and in the parts that follow.
<...>
This seems like a good patch to me but more experienced members will be able to comment better I think. Good job anyways.
Regards,
Shourya Shukla
Quoted 3 lines · Shourya Shukla <[email protected]> 于2021年3月11日周四 下午11:05写道:
Hey!
Hi!
Quoted 5 lines
The idea seems very useful to me though I am not sure what others feel about this and whether Git is ready for such a thing or not. Keeping this concern aside, I will still review the patch due to my own interest in it as well.
haha, thank you! I'm glad that my whims can be recognized by you and help git itself.
Quoted 6 lines · ZheNing Hu via GitGitGadget
Quoted 4 lines
From: ZheNing Hu <[email protected]>
Similar to "Helped-by", "Reported-by", "Reviewed-by", "Mentored-by" these signatures are often seen in git commit messages. After
Quoted 8 lines
I think it will be better to rephrase the line so that it is easier to understand. It took me a couple of reads to figure out what you meant.
Something like:
Similar to "Signed-off-by", trailers such as "Reported-by", "Helped-by" and "Mentored-by" are also seen in Git commits.
It's exactly what you said.
My lack of English sometimes limits my expression.
Quoted 8 lines
Quoted 7 lines
referring to the simple implementation of
commit --signoffandsend-email -cc=" commiter <email>", I am considering whether to provide multiple signature parameters from the command line. I think this might help maintainers and developers directly uses the shell to provide these signatures instead of multiple times repetitive writing those trailers each time.
Quoted 8 lines
The above para is more appropriate for a cover letter than a commit message. Your thought process for the patch you sent is equally valuable but this does not belong in the commit message. Commit messages are more about what you did and any nuances that follow. You get me?
Use 'git format-patch --cover-letter <...>' to create a cover letter for your patch.
I understand it now, because I use GGG, I will put this content into the GGG conversation.
Quoted 9 lines
Quoted 3 lines
To achieve this goal, i refactored the
append_signoffdesign and providedappend_messageandappend_message_string_listinterfaces, providing new ways to generate those various signatures.s/i/I
Also, commit messages are generally written in the imperative tense when desciribing what you have done in the commit.
You're right.
Quoted 20 lines
Quoted 4 lines
Users now can use
commit -H "helper <eamil>"to generate "Helped-by" trailer,commit -R "reviewer <eamil>"to generate "Reviewed-by" trailer,commit -r "reporter <eamil> "to generate "Reported-by" trailer,commit -M "mentor <eamil>"to generate "Mentored-by" trailer.Multiple typos.
Quoted 1 line
Signed-off-by ZheNing Hu <[email protected]>So, an improved commit message could be:
-----8<-----
commit: support multiple trailers from the command lineHistorically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. Extend this list to include other commonly used trailers viz., "Helped-by", "Reviewed-by", "Reported-by" and "Mentored-by". Introduce options '-H', '-R', '-r' and '-M' corresponding to the aforementioned trailers.
Quoted 3 lines
While at it, add tests in the script '
t7502-commit-porcelain.sh' and add information regarding these options in the Documentation of 'git commit'.
I think this paragraph may not be needed. Junio said in reply to one of my previous patches that we may not need to add instructions about test files and documents, because git log -p --stat can clearly see that what we have done in testing and documentation.
Quoted 10 lines
----->8-----
Quoted 7 lines
[GSOC] commit: provides multiple signatures from command line
I don’t know if my idea will satisfy everyone, I'm also thinking about whether we can provide a more generalized version (I think this idea can be extended: because users and developers have other signature methods that they want, such as "Based-on-patch-by") I hope someone can give me pointers (on the correctness of ideas or codes)
Quoted 6 lines
It will be great if we let the user add customised options for the respective trailers but I think that trying to cater to such a large audience will only complicate the whole process and decrease the support avialable for the options/command. Apart from this, I think that the trailer "Reviewed-by" may not be that widely used and it would be better if we remove it from this patch.
Okay, I will delete it.
Quoted 42 lines
Quoted 42 lines
Documentation/git-commit.txt | 24 +++++++- builtin/commit.c | 63 +++++++++++++++++++++ sequencer.c | 40 +++++++++---- sequencer.h | 4 ++ t/t7502-commit-porcelain.sh | 106 +++++++++++++++++++++++++++++++++++ 5 files changed, 226 insertions(+), 11 deletions(-)Documentation/git-commit.txt +18
-1@@ -14,7 +14,9 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(-H|--helped-by)=<address>...] + [(-R|--reviewed-by)=<address>...] [(-r|--reported-by)=<address>...] + [(-M|--mentored)=<address>...] DESCRIPTION -----------@@ -166,6 +168,26 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +-H=<address>...:: +--helped-by=<address>...:: + Add one or more `Helped-by` trailer by the committer at the end of the commit + log message. + +-R=<address>...:: +--reviewed-by=<address>...:: + Add one or more `Reviewed-by` trailer by the committer at the end of the commit + log message. + +-r=<address>...:: +--reported-by=<address>...:: + Add one or more `Reported-by` trailer by the committer at the end of the commit + log message. +
Quoted 9 lines
Documentation/git-commit.txt The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. · line 189
Quoted 4 lines
Documentation/git-commit.txt +4
-0+-M=<address>...:: +--mentored-by=<address>...:: + Add one or more `Mentored-by` trailer by the committer at the end of the commit + log message.Oh! I did not think you had added long forms of these options and was about to comment on that. Good that you added. Do talk about them as well in the commit message.
Yes, I forgot to mention these long formats in the commit message.
Quoted 25 lines
Quoted 8 lines
Documentation/git-commit.txt +0
-0-n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.builtin/commit.c +0
-0builtin/commit.c static int config_commit_verbose = -1; /* unspecified */ · line 119
Quoted 7 lines
builtin/commit.c +4
-0@@ -113,6 +113,10 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct string_list helped_by =STRING_LIST_INIT_NODUP ; +static struct string_list mentored_by =STRING_LIST_INIT_NODUP ; +static struct string_list reviewed_by =STRING_LIST_INIT_NODUP ; +static struct string_list reported_by =STRING_LIST_INIT_NODUP ;Good that you kept the variables as 'string_list's instead of a usual 'char*'.
Quoted 6 lines
builtin/commit.c +0
-0/* * The default commit message cleanup mode will remove the lines @@ -829,6 +833,20 @@ static int prepare_to_commit(const char *index_file, const char *prefix,if (signoff)append_signoff (&sb,ignore_non_trailer (sb.buf, sb.len),0 );
Quoted 14 lines
builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 843
Quoted 8 lines
builtin/commit.c +8
-0+if (helped_by.items) +append_message_string_list (&sb,"Helped-by: " , &helped_by,ignore_non_trailer (sb.buf, sb.len),0 ); +if (reviewed_by.items) +append_message_string_list (&sb,"Reviewed-by: " , &reviewed_by,ignore_non_trailer (sb.buf, sb.len),0 ); +if (reported_by.items) +append_message_string_list (&sb,"Reported-by: " , &reported_by,ignore_non_trailer (sb.buf, sb.len),0 ); +if (mentored_by.items) +append_message_string_list (&sb,"Mentored-by: " , &mentored_by,ignore_non_trailer (sb.buf, sb.len),0 );I think this part will look prettier if you wrap around the text. For code segments, the wrap around limit is 80 chars. For commit messages its 72 chars. Wrap around means that as soon as you hit N number of characters, you proceed to the next(new) line.
Fine.
Quoted 91 lines
Quoted 51 lines
builtin/commit.c +40
-0+string_list_clear (&helped_by,0 ); +string_list_clear (&reviewed_by,0 ); +string_list_clear (&reported_by,0 ); +string_list_clear (&mentored_by,0 ); +if (fwrite (sb.buf,1 , sb.len, s->fp) < sb.len)die_errno (_ ("could not write commit template" ));@@ -1490,6 +1508,42 @@ static int git_commit_config(const char *k, const char *v, void *cb)return git_status_config (k, v, s); } +static int help_callback (const struct option *opt,const char *arg,int unset) +{ +if (unset) +string_list_clear (&helped_by,0 ); +else +string_list_append (&helped_by, arg); +return 0 ; +} + +static int review_callback (const struct option *opt,const char *arg,int unset) +{ +if (unset) +string_list_clear (&reviewed_by,0 ); +else +string_list_append (&reviewed_by, arg); +return 0 ; +} + +static int report_callback (const struct option *opt,const char *arg,int unset) +{ +if (unset) +string_list_clear (&reported_by,0 ); +else +string_list_append (&reported_by, arg); +return 0 ; +} + +static int mentor_callback (const struct option *opt,const char *arg,int unset) +{ +if (unset) +string_list_clear (&mentored_by,0 ); +else +string_list_append (&mentored_by, arg); +return 0 ; +}int cmd_commit (int argc,const char **argv,const char *prefix) {static struct wt_status s;builtin/commit.c int cmd_commit(int argc, const char **argv, const char *prefix) · line 1567
Quoted 7 lines
builtin/commit.c +4
-0@@ -1507,6 +1561,10 @@ 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 ('H' ,"helped-by" ,NULL ,N_ ("email" ),N_ ("add a Helped-by trailer" ), help_callback), +OPT_CALLBACK ('r' ,"reported-by" ,NULL ,N_ ("email" ),N_ ("add a Reported-by trailer" ), report_callback), +OPT_CALLBACK ('R' ,"reviewed-by" ,NULL ,N_ ("email" ),N_ ("add a Reviewed-by trailer" ), review_callback), + OPT_CALLBACK('M', "mentored-by", NULL, N_("email"), N_("add a Mentored-by trailer"), mentor_callback),It would be lovely if you could line wrap these above additions too!
Quoted 20 lines
builtin/commit.c +5
-0OPT_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")),@@ -1561,6 +1619,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix)struct commit_extra_header *extra =NULL ;struct strbuf err =STRBUF_INIT ; + helped_by.strdup_strings =1 ; + reviewed_by.strdup_strings =1 ; + reported_by.strdup_strings =1 ; + mentored_by.strdup_strings =1 ; +if (argc ==2 && !strcmp (argv[1 ],"-h" ))usage_with_options (builtin_commit_usage, builtin_commit_options);sequencer.c +0
-0sequencer.c int sequencer_pick_revisions(struct repository *r, · line 4672
Quoted 6 lines
sequencer.c +2
-1@@ -4668,16 +4668,12 @@ int sequencer_pick_revisions(struct repository *r,return res; } -void append_signoff (struct strbuf *msgbuf,size_t ignore_footer,unsigned flag) +void append_message (struct strbuf *msgbuf,struct strbuf *sob, +size_t ignore_footer,unsigned flag)Its nice to see that you generalised the pre-exisiting function instead of creating a new one(s) for the new trailers. Good.
Quoted 5 lines
It will be better to name 'struct strbuf *sob' to something more generic, maybe 'struct strbuf *trailer' since 'sob' stands for 'Signed-off-by' and since the function is becoming more generic, its contents should too.
When I wrote it, I didn’t realize that sob refers to the abbreviation of 'Signed-off-by', I will change it.
Quoted 84 lines
Quoted 14 lines
sequencer.c +0
-5{unsigned no_dup_sob = flag &APPEND_SIGNOFF_DEDUP ; -struct strbuf sob =STRBUF_INIT ;int has_footer; -strbuf_addstr (&sob, sign_off_header); -strbuf_addstr (&sob,fmt_name (WANT_COMMITTER_IDENT )); -strbuf_addch (&sob,'\n' ); -if (!ignore_footer)strbuf_complete_line (msgbuf);@@ -4685,11 +4681,11 @@ void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)* If the whole message buffer is equal to the sob, pretend that we sequencer.c void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag) · line 4688
Quoted 10 lines
sequencer.c +3
-3* found a conforming footer with a matching sob */ -if (msgbuf->len - ignore_footer == sob.len && - !strncmp (msgbuf->buf, sob.buf, sob.len)) +if (msgbuf->len - ignore_footer == sob->len && + !strncmp (msgbuf->buf, sob->buf, sob->len)) has_footer =3 ;else - has_footer =has_conforming_footer (msgbuf, &sob, ignore_footer); + has_footer =has_conforming_footer (msgbuf, sob, ignore_footer);Again, rename the variables.
Quoted 8 lines
sequencer.c +1
-1if (!has_footer) {const char *append_newlines =NULL ;@@ -4723,8 +4719,32 @@ void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)if (has_footer !=3 && (!no_dup_sob || has_footer !=2 ))strbuf_splice (msgbuf, msgbuf->len - ignore_footer,0 , - sob.buf, sob.len); + sob->buf, sob->len);sequencer.c void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag) · line 4732
Quoted 10 lines
sequencer.c +10
-0+} +void append_signoff (struct strbuf *msgbuf,size_t ignore_footer,unsigned flag) +{ +struct strbuf sob =STRBUF_INIT ; +strbuf_addstr (&sob, sign_off_header); +strbuf_addstr (&sob,fmt_name (WANT_COMMITTER_IDENT )); +strbuf_addch (&sob,'\n' ); +append_message (msgbuf, &sob, ignore_footer, flag); +strbuf_release (&sob); +}I think it will be nice if you could use a flag to denote whether the entity to be appended is a 'sign-off' or not. This way when say the variable 'int signoff' is 1, then use the above part in the '
append_message()' function otherwise go with the flow that exists.Quoted 5 lines
sequencer.c +5
-0+void append_message_string_list (struct strbuf *msgbuf,const char *header, +struct string_list *sobs,size_t ignore_footer,unsigned flag) { +int i; +struct strbuf sob =STRBUF_INIT ; +sequencer.c void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag) · line 4749
Quoted 10 lines
sequencer.c +8
-0+for ( i =0 ; i < sobs->nr; i++) + { +strbuf_addstr (&sob, header); +strbuf_addstr (&sob, sobs->items[i].string); +strbuf_addch (&sob,'\n' ); +append_message (msgbuf, &sob, ignore_footer, flag); +strbuf_reset (&sob); + }strbuf_release (&sob); }Similarly, here, if 'signoff = 0' then the above part goes on. Or another alternative can be to create a '
append_message_helper()' and shift the current contents of 'append_message()' into that and use the above function to work as per the value of signoff.So a possible flow can be:
void
append_message_string_list(...params...){if (signoff) { ..excecute the necessary segments and call the 'append_message_helper()' function... } else { ..similarly here.. } }
Quoted 1 line
This way we save ourselves some extra functions.
May some thing like this:
if (signoff)
append_message_string_list(&sb, "Signed-off-by: ", NULL,
ignore_non_trailer(sb.buf, sb.len), 0);
And then we could judge in append_message_string_list if the arguement string_list *trailers set to NULL. If so, we do something similar to append_signoff, otherwise, we carry out other situations.
So that we can delete the append_signoff and user can only need to call append_message_string_list in any where, I don't
know if it is better.
Quoted 42 lines
Quoted 6 lines
sequencer.h +0
-0sequencer.h int todo_list_rearrange_squash(struct todo_list *todo_list); · line 183
Quoted 10 lines
sequencer.h +4
-0@@ -174,6 +174,10 @@ int todo_list_rearrange_squash(struct todo_list *todo_list);* and the new signoff will be spliced into the buffer before those bytes. */ void append_signoff (struct strbuf *msgbuf,size_t ignore_footer,unsigned flag); +void append_message (struct strbuf *msgbuf,struct strbuf *sob, +size_t ignore_footer,unsigned flag); +void append_message_string_list (struct strbuf *msgbuf,const char *header, +struct string_list *sobs,size_t ignore_footer,unsigned flag);void append_conflicts_hint (struct index_state *istate,struct strbuf *msgbuf,enum commit_msg_cleanup_mode cleanup_mode);Then, these would have to be corrected too.
t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 155
Quoted 7 lines
t/t7502-commit-porcelain.sh +0
-0@@ -154,6 +154,112 @@ test_expect_success 'sign off' ' 'I feel that the tests deserve a commit of their own. A follow-up commit in this patch.
Quoted 12 lines
t/t7502-commit-porcelain.sh +12
-0+test_expect_success 'helped-by' ' + + >file1 && + git add file1 && + git commit --helped-by="foo <bar@frotz>" \ + --helped-by="foo2 <bar2@frotz>" -m "thank you" && + git cat-file commit HEAD >commit.msg && + sed -ne "s/Helped-by: //p" commit.msg >actual && + cat >expected <<-\EOF && + foo <bar@frotz> + foo2 <bar2@frotz> + EOF
Quoted 9 lines
t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 169
Quoted 2 lines
t/t7502-commit-porcelain.sh +2
-0+ test_cmp expected actual +Was this extra line feed intentional? It looks odd here and other test (scripts) don't have this. Though, this test script seems to have many tests which have an extra line feed. My suggestion would be to eliminate it. Maybe this script is old and hasn't been reviewed for a cleanup in a long time.
I might want to keep the same format with the last "sign off" test. Now it seems that this is not necessary.
Quoted 19 lines
Quoted 6 lines
t/t7502-commit-porcelain.sh +6
-0+' + +test_expect_success 'reported-by' ' + + >file2 && + git add file2 &&t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 186
Quoted 10 lines
t/t7502-commit-porcelain.sh +10
-0+ git commit --reported-by="foo <bar@frotz>" \ + --reported-by="foo2 <bar2@frotz>" -m "thank you" && + git cat-file commit HEAD >commit.msg && + sed -ne "s/Reported-by: //p" commit.msg >actual && + cat >expected <<-\EOF && + foo <bar@frotz> + foo2 <bar2@frotz> + EOF + test_cmp expected actual +Similarly here and in the parts that follow.
Quoted 5 lines
<...>
This seems like a good patch to me but more experienced members will be able to comment better I think. Good job anyways.
Your comments and encouragement are of great help to me :)
Quoted 3 lines
Regards,
Shourya Shukla
Regards,
ZheNing Hu
Quoted 9 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Similar to "Helped-by", "Reported-by", "Reviewed-by", "Mentored-by" these signatures are often seen in git commit messages. After referring to the simple implementation of
commit --signoffandsend-email -cc=" commiter <email>", I am considering whether to provide multiple signature parameters from the command line.
+ ...
t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 249
Quoted 6 lines
t/t7502-commit-porcelain.sh +6
-0+ >file6 && + git add file6 && + git commit -H "foo <bar@frotz>" \ + -R "foo2 <bar2@frotz>" \ + -M "foo3 <bar3@frotz>" \ + -r "foo4 <bar4@frotz>" -s -m "thank you" &&
Firm NAK.
Especially, not in this form that squats on short-and-sweet single letter option names only to support the convention of this single project (namely, Git).
cf. https://lore.kernel.org/git/[email protected]/
Thanks.
Quoted 9 lines · Junio C Hamano <[email protected]> 于2021年3月12日周五 上午1:29写道:
Firm NAK.
Especially, not in this form that squats on short-and-sweet single letter option names only to support the convention of this single project (namely, Git).
cf. https://lore.kernel.org/git/[email protected]/
Thanks.
Well, Junio, you point is It's also worth thinking about, This "trailer =<trailer>:<argtrailer>" is probably the more general version of the tailer I want to provide to commit, Then I may need to know how Christian Couder trailer.c work first,or can you give a little directionality guidance?
Thanks.
Quoted 9 lines · Junio C Hamano <[email protected]> 于2021年3月12日周五 上午1:29写道:
Firm NAK.
Especially, not in this form that squats on short-and-sweet single letter option names only to support the convention of this single project (namely, Git).
cf. https://lore.kernel.org/git/[email protected]/
Thanks.
Now I understand that We have a git command now:
`git interpret-trailers --in-place --where=end \
./a.txt --trailer "Signed-off-by:adl <[email protected]> " can add the trailers to specified file, so now maybe I only need to provide --trailer` for commit, right?
PATCH v2 1/1 commit: add trailer command
In reply to ZheNing Hu via GitGitGadgetFrom: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide richer trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now use --trailer <token>[(=|:)<value>] pass the trailers to interpret-trailers and generate trailers in commit messages.
---
[GSOC] commit: provides multiple signatures from command line
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.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Range-diff vs v1:
1: e9389e72ac65 ! 1: 4c507d17db4f [GSOC] commit: provides multiple common signatures
@@ Metadata
Author: ZheNing Hu <[email protected]>
## Commit message ##
- [GSOC] commit: provides multiple common signatures
+ [GSOC] commit: add trailer command
- Similar to "Helped-by", "Reported-by", "Reviewed-by", "Mentored-by"
- these signatures are often seen in git commit messages. After
- referring to the simple implementation of `commit --signoff`
- and `send-email -cc=" commiter <email>"`, I am considering
- whether to provide multiple signature parameters from the
- command line. I think this might help maintainers and
- developers directly uses the shell to provide these signatures
- instead of multiple times repetitive writing those trailers
- each time.
+ Historically, Git has supported the 'Signed-off-by' commit trailer
+ using the '--signoff' and the '-s' option from the command line.
+ But users may need to provide richer trailer information from the
+ command line such as "Helped-by", "Reported-by", "Mentored-by",
- To achieve this goal, i refactored the `append_signoff` design and
- provided `append_message` and `append_message_string_list` interfaces,
- providing new ways to generate those various signatures.
-
- Users now can use `commit -H "helper <eamil>"` to generate "Helped-by" trailer,
- `commit -R "reviewer <eamil>"` to generate "Reviewed-by" trailer,
- `commit -r "reporter <eamil> "`to generate "Reported-by" trailer,
- `commit -M "mentor <eamil>"` to generate "Mentored-by" trailer.
+ Now use `--trailer <token>[(=|:)<value>]` pass the trailers to
+ `interpret-trailers` and generate trailers in commit messages.
Signed-off-by: ZheNing Hu <[email protected]>
@@ Documentation/git-commit.txt: SYNOPSIS
[--date=<date>] [--cleanup=<mode>] [--[no-]status]
[-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]]
- [-S[<keyid>]] [--] [<pathspec>...]
-+ [-S[<keyid>]] [--] [<pathspec>...] [(-H|--helped-by)=<address>...]
-+ [(-R|--reviewed-by)=<address>...] [(-r|--reported-by)=<address>...]
-+ [(-M|--mentored)=<address>...]
++ [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...]
DESCRIPTION
-----------
@@ Documentation/git-commit.txt: The `-m` option is mutually exclusive with `-c`, `
include::signoff-option.txt[]
-+-H=<address>...::
-+--helped-by=<address>...::
-+ Add one or more `Helped-by` trailer by the committer at the end of the commit
-+ log message.
-+
-+-R=<address>...::
-+--reviewed-by=<address>...::
-+ Add one or more `Reviewed-by` trailer by the committer at the end of the commit
-+ log message.
-+
-+-r=<address>...::
-+--reported-by=<address>...::
-+ Add one or more `Reported-by` trailer by the committer at the end of the commit
-+ log message.
-+
-+-M=<address>...::
-+--mentored-by=<address>...::
-+ Add one or more `Mentored-by` trailer by the committer at the end of the commit
-+ log message.
++--trailer <token>[(=|:)<value>]::
++ Specify a (<token>, <value>) pair that should be applied as a
++ trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter <[email protected]>" \
++ --trailer "Helped-by:C O Mitter <[email protected]>"`will add the "Signed-off" trailer
++ and the "Helped-by" trailer in the commit message.)
+
-n::
--no-verify::
@@ builtin/commit.c: static int config_commit_verbose = -1; /* unspecified */
static int no_post_rewrite, allow_empty_message, pathspec_file_nul;
static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;
static char *sign_commit, *pathspec_from_file;
-+static struct string_list helped_by = STRING_LIST_INIT_NODUP;
-+static struct string_list mentored_by = STRING_LIST_INIT_NODUP;
-+static struct string_list reviewed_by = STRING_LIST_INIT_NODUP;
-+static struct string_list reported_by = STRING_LIST_INIT_NODUP;
++struct child_process run_trailer = CHILD_PROCESS_INIT;
++static const char *trailer;
/*
* The default commit message cleanup mode will remove the lines
-@@ builtin/commit.c: static int prepare_to_commit(const char *index_file, const char *prefix,
- if (signoff)
- append_signoff(&sb, ignore_non_trailer(sb.buf, sb.len), 0);
-
-+ if(helped_by.items)
-+ append_message_string_list(&sb, "Helped-by: ", &helped_by, ignore_non_trailer(sb.buf, sb.len), 0);
-+ if(reviewed_by.items)
-+ append_message_string_list(&sb, "Reviewed-by: ", &reviewed_by, ignore_non_trailer(sb.buf, sb.len), 0);
-+ if(reported_by.items)
-+ append_message_string_list(&sb, "Reported-by: ", &reported_by, ignore_non_trailer(sb.buf, sb.len), 0);
-+ if(mentored_by.items)
-+ append_message_string_list(&sb, "Mentored-by: ", &mentored_by, ignore_non_trailer(sb.buf, sb.len), 0);
-+
-+ string_list_clear(&helped_by, 0);
-+ string_list_clear(&reviewed_by, 0);
-+ string_list_clear(&reported_by, 0);
-+ string_list_clear(&mentored_by, 0);
-+
- if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len)
- die_errno(_("could not write commit template"));
+@@ builtin/commit.c: static struct strbuf message = STRBUF_INIT;
-@@ builtin/commit.c: static int git_commit_config(const char *k, const char *v, void *cb)
- return git_status_config(k, v, s);
- }
+ static enum wt_status_format status_format = STATUS_FORMAT_UNSPECIFIED;
-+static int help_callback(const struct option *opt, const char *arg, int unset)
-+{
-+ if (unset)
-+ string_list_clear(&helped_by, 0);
-+ else
-+ string_list_append(&helped_by, arg);
-+ return 0;
-+}
-+
-+static int review_callback(const struct option *opt, const char *arg, int unset)
++static int opt_pass_trailer(const struct option *opt, const char *arg, int unset)
+{
-+ if (unset)
-+ string_list_clear(&reviewed_by, 0);
-+ else
-+ string_list_append(&reviewed_by, arg);
-+ return 0;
-+}
-+
-+static int report_callback(const struct option *opt, const char *arg, int unset)
-+{
-+ if (unset)
-+ string_list_clear(&reported_by, 0);
-+ else
-+ string_list_append(&reported_by, arg);
-+ return 0;
-+}
-+
-+static int mentor_callback(const struct option *opt, const char *arg, int unset)
-+{
-+ if (unset)
-+ string_list_clear(&mentored_by, 0);
-+ else
-+ string_list_append(&mentored_by, arg);
++ if (unset) {
++ strvec_clear(&run_trailer.args);
++ return -1;
++ }
++ run_trailer.git_cmd = 1;
++ strvec_pushl(&run_trailer.args, "--trailer", arg, NULL);
+ return 0;
+}
+
- int cmd_commit(int argc, const char **argv, const char *prefix)
+ static int opt_parse_porcelain(const struct option *opt, const char *arg, int unset)
{
- static struct wt_status s;
+ enum wt_status_format *value = (enum wt_status_format *)opt->value;
+@@ builtin/commit.c: static int prepare_to_commit(const char *index_file, const char *prefix,
+
+ fclose(s->fp);
+
++ run_command(&run_trailer);
++
+ /*
+ * Reject an attempt to record a non-merge empty commit without
+ * explicit --allow-empty. In the cherry-pick case, it may be
@@ 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('H', "helped-by", NULL, N_("email"), N_("add a Helped-by trailer"), help_callback),
-+ OPT_CALLBACK('r', "reported-by", NULL, N_("email"), N_("add a Reported-by trailer"), report_callback),
-+ OPT_CALLBACK('R', "reviewed-by", NULL, N_("email"), N_("add a Reviewed-by trailer"), review_callback),
-+ OPT_CALLBACK('M', "mentored-by", NULL, N_("email"), N_("add a Mentored-by trailer"), mentor_callback),
++ OPT_CALLBACK(0, "trailer", &trailer, N_("trailer"), N_("trailer(s) to add"), 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")),
@@ builtin/commit.c: int cmd_commit(int argc, const char **argv, const char *prefix)
- struct commit_extra_header *extra = NULL;
- struct strbuf err = STRBUF_INIT;
-
-+ helped_by.strdup_strings = 1;
-+ reviewed_by.strdup_strings = 1;
-+ reported_by.strdup_strings = 1;
-+ mentored_by.strdup_strings = 1;
-+
- if (argc == 2 && !strcmp(argv[1], "-h"))
- usage_with_options(builtin_commit_usage, builtin_commit_options);
-
-
- ## sequencer.c ##
-@@ sequencer.c: int sequencer_pick_revisions(struct repository *r,
- return res;
- }
-
--void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)
-+void append_message(struct strbuf *msgbuf, struct strbuf *sob,
-+ size_t ignore_footer, unsigned flag)
- {
- unsigned no_dup_sob = flag & APPEND_SIGNOFF_DEDUP;
-- struct strbuf sob = STRBUF_INIT;
- int has_footer;
-
-- strbuf_addstr(&sob, sign_off_header);
-- strbuf_addstr(&sob, fmt_name(WANT_COMMITTER_IDENT));
-- strbuf_addch(&sob, '\n');
--
- if (!ignore_footer)
- strbuf_complete_line(msgbuf);
-
-@@ sequencer.c: void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)
- * If the whole message buffer is equal to the sob, pretend that we
- * found a conforming footer with a matching sob
- */
-- if (msgbuf->len - ignore_footer == sob.len &&
-- !strncmp(msgbuf->buf, sob.buf, sob.len))
-+ if (msgbuf->len - ignore_footer == sob->len &&
-+ !strncmp(msgbuf->buf, sob->buf, sob->len))
- has_footer = 3;
- else
-- has_footer = has_conforming_footer(msgbuf, &sob, ignore_footer);
-+ has_footer = has_conforming_footer(msgbuf, sob, ignore_footer);
-
- if (!has_footer) {
- const char *append_newlines = NULL;
-@@ sequencer.c: void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)
-
- if (has_footer != 3 && (!no_dup_sob || has_footer != 2))
- strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,
-- sob.buf, sob.len);
-+ sob->buf, sob->len);
-+}
-+
-+void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)
-+{
-+ struct strbuf sob = STRBUF_INIT;
-+ strbuf_addstr(&sob, sign_off_header);
-+ strbuf_addstr(&sob, fmt_name(WANT_COMMITTER_IDENT));
-+ strbuf_addch(&sob, '\n');
-+ append_message(msgbuf, &sob, ignore_footer, flag);
-+ strbuf_release(&sob);
-+}
-
-+void append_message_string_list(struct strbuf *msgbuf, const char *header,
-+ struct string_list *sobs, size_t ignore_footer, unsigned flag) {
-+ int i;
-+ struct strbuf sob = STRBUF_INIT;
-+
-+ for ( i = 0; i < sobs->nr; i++)
-+ {
-+ strbuf_addstr(&sob, header);
-+ strbuf_addstr(&sob, sobs->items[i].string);
-+ strbuf_addch(&sob, '\n');
-+ append_message(msgbuf, &sob, ignore_footer, flag);
-+ strbuf_reset(&sob);
-+ }
- strbuf_release(&sob);
- }
-
-
- ## sequencer.h ##
-@@ sequencer.h: int todo_list_rearrange_squash(struct todo_list *todo_list);
- * and the new signoff will be spliced into the buffer before those bytes.
- */
- void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag);
-+void append_message(struct strbuf *msgbuf, struct strbuf *sob,
-+ size_t ignore_footer, unsigned flag);
-+void append_message_string_list(struct strbuf *msgbuf, const char*header,
-+ struct string_list *sobs, size_t ignore_footer, unsigned flag);
-
- void append_conflicts_hint(struct index_state *istate,
- struct strbuf *msgbuf, enum commit_msg_cleanup_mode cleanup_mode);
+ die(_("could not parse HEAD commit"));
+ }
+ verbose = -1; /* unspecified */
++ strvec_pushl(&run_trailer.args, "interpret-trailers",
++ "--in-place", "--where=end", git_path_commit_editmsg(), NULL);
+ argc = parse_and_validate_options(argc, argv, builtin_commit_options,
+ builtin_commit_usage,
+ prefix, current_head, &s);
## t/t7502-commit-porcelain.sh ##
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' '
'
-+test_expect_success 'helped-by' '
-+
++test_expect_success 'trailer' '
+ >file1 &&
+ git add file1 &&
-+ git commit --helped-by="foo <bar@frotz>" \
-+ --helped-by="foo2 <bar2@frotz>" -m "thank you" &&
-+ git cat-file commit HEAD >commit.msg &&
-+ sed -ne "s/Helped-by: //p" commit.msg >actual &&
-+ cat >expected <<-\EOF &&
-+ foo <bar@frotz>
-+ foo2 <bar2@frotz>
-+ EOF
-+ test_cmp expected actual
-+
-+'
-+
-+test_expect_success 'reported-by' '
-+
-+ >file2 &&
-+ git add file2 &&
-+ git commit --reported-by="foo <bar@frotz>" \
-+ --reported-by="foo2 <bar2@frotz>" -m "thank you" &&
-+ git cat-file commit HEAD >commit.msg &&
-+ sed -ne "s/Reported-by: //p" commit.msg >actual &&
-+ cat >expected <<-\EOF &&
-+ foo <bar@frotz>
-+ foo2 <bar2@frotz>
-+ EOF
-+ test_cmp expected actual
-+
-+'
-+
-+test_expect_success 'reviewed-by' '
-+
-+ >file3 &&
-+ git add file3 &&
-+ git commit --reviewed-by="foo <bar@frotz>" \
-+ --reviewed-by="foo2 <bar2@frotz>" -m "thank you" &&
-+ git cat-file commit HEAD >commit.msg &&
-+ sed -ne "s/Reviewed-by: //p" commit.msg >actual &&
-+ cat >expected <<-\EOF &&
-+ foo <bar@frotz>
-+ foo2 <bar2@frotz>
-+ EOF
-+ test_cmp expected actual
-+
-+'
-+
-+test_expect_success 'mentored-by' '
-+
-+ >file4 &&
-+ git add file4 &&
-+ git commit --mentored-by="foo <bar@frotz>" \
-+ --mentored-by="foo2 <bar2@frotz>" -m "thank you" &&
-+ git cat-file commit HEAD >commit.msg &&
-+ sed -ne "s/Mentored-by: //p" commit.msg >actual &&
-+ cat >expected <<-\EOF &&
-+ foo <bar@frotz>
-+ foo2 <bar2@frotz>
-+ EOF
-+ test_cmp expected actual
-+
-+'
-+
-+test_expect_success 'multiple signatures' '
-+
-+ >file5 &&
-+ git add file5 &&
-+ git commit --helped-by="foo <bar@frotz>" \
-+ --reviewed-by="foo2 <bar2@frotz>" \
-+ --mentored-by="foo3 <bar3@frotz>" \
-+ --reported-by="foo4 <bar4@frotz>" -s -m "thank you" &&
++ git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \
++ --trailer "Helped-by:C O Mitter2 <[email protected]>" \
++ --trailer "Reported-by:C O Mitter3 <[email protected]>" \
++ --trailer "Mentored-by:C O Mitter4 <[email protected]>" \
++ -m "hello" &&
+ git cat-file commit HEAD >commit.msg &&
+ sed -e "1,7d" commit.msg >actual &&
+ cat >expected <<-\EOF &&
+ Signed-off-by: C O Mitter <[email protected]>
-+ Helped-by: foo <bar@frotz>
-+ Reviewed-by: foo2 <bar2@frotz>
-+ Reported-by: foo4 <bar4@frotz>
-+ Mentored-by: foo3 <bar3@frotz>
++ Signed-off-by: C O Mitter1 <[email protected]>
++ Helped-by: C O Mitter2 <[email protected]>
++ Reported-by: C O Mitter3 <[email protected]>
++ Mentored-by: C O Mitter4 <[email protected]>
+ EOF
+ test_cmp expected actual
-+
-+'
-+
-+test_expect_success 'multiple signatures (use abbreviations)' '
-+
-+ >file6 &&
-+ git add file6 &&
-+ git commit -H "foo <bar@frotz>" \
-+ -R "foo2 <bar2@frotz>" \
-+ -M "foo3 <bar3@frotz>" \
-+ -r "foo4 <bar4@frotz>" -s -m "thank you" &&
-+ git cat-file commit HEAD >commit.msg &&
-+ sed -e "1,7d" commit.msg >actual &&
-+ cat >expected <<-\EOF &&
-+ Signed-off-by: C O Mitter <[email protected]>
-+ Helped-by: foo <bar@frotz>
-+ Reviewed-by: foo2 <bar2@frotz>
-+ Reported-by: foo4 <bar4@frotz>
-+ Mentored-by: foo3 <bar3@frotz>
-+ EOF
-+ test_cmp expected actual
-+
+'
+
test_expect_success 'multiple -m' 'Documentation/git-commit.txt | 8 +++++++- builtin/commit.c | 18 ++++++++++++++++++ t/t7502-commit-porcelain.sh | 20 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-)
Documentation/git-commit.txt +7 -1
@@ -14,7 +14,7 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...] DESCRIPTION -----------
@@ -166,6 +166,12 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter <[email protected]>" \ + --trailer "Helped-by:C O Mitter <[email protected]>"`will add the "Signed-off" trailer + and the "Helped-by" trailer in the commit message.) + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.
builtin/commit.c +18 -0
@@ -113,6 +113,8 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +struct child_process run_trailer =CHILD_PROCESS_INIT ; +static const char *trailer;/* * The default commit message cleanup mode will remove the lines
@@ -131,6 +133,17 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +if (unset) { +strvec_clear (&run_trailer.args); +return -1 ; + } + run_trailer.git_cmd =1 ; +strvec_pushl (&run_trailer.args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
@@ -958,6 +971,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +run_command (&run_trailer); +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be
@@ -1507,6 +1522,7 @@ 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 (0 ,"trailer" , &trailer,N_ ("trailer" ),N_ ("trailer(s) to add" ), 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")),
@@ -1577,6 +1593,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)die (_ ("could not parse HEAD commit" )); } verbose =-1 ;/* unspecified */ +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--in-place" ,"--where=end" ,git_path_commit_editmsg (),NULL ); argc =parse_and_validate_options (argc, argv, builtin_commit_options, builtin_commit_usage, prefix, current_head, &s);
t/t7502-commit-porcelain.sh +20 -0
@@ -154,6 +154,26 @@ test_expect_success 'sign off' ' ' +test_expect_success 'trailer' ' + >file1 && + git add file1 && + git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ + --trailer "Helped-by:C O Mitter2 <[email protected]>" \ + --trailer "Reported-by:C O Mitter3 <[email protected]>" \ + --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ + -m "hello" && + git cat-file commit HEAD >commit.msg && + sed -e "1,7d" commit.msg >actual && + cat >expected <<-\EOF && + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter1 <[email protected]> + Helped-by: C O Mitter2 <[email protected]> + Reported-by: C O Mitter3 <[email protected]> + Mentored-by: C O Mitter4 <[email protected]> + EOF + test_cmp expected actual +' + test_expect_success 'multiple -m' ' >negative &&
base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945
Signature · 1 line
gitgitgadget
Re: [PATCH v2] [GSOC] commit: add trailer command
Quoted 7 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide richer trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Nit: not sure that "richer" is the proper word here. I would just use "other" instead.
Quoted 2 lines
Now use
--trailer <token>[(=|:)<value>]pass the trailers tointerpret-trailersand generate trailers in commit messages.
The subject says "add trailer command" while here you say "use". So which one is it? Does "--trailer" already exist, and we are just going to use it? Or will this patch series actually "add" it?
Looking at the existing options and the code of this patch series, the patch series actually adds the "--trailer" (not "trailer") option, so "add" or "implement" would be clearer than "use".
So maybe something like the following might be better:
"Now implement a new --trailer <token>[(=|:)<value>] option to pass other trailers to interpret-trailers and insert them into commit messages."
Also something like "--trailer" is usually called an option (or sometimes a flag), not a command (especially not when the word is not a verb, and when the new feature isn't a new exclusive mode of operation). So something like "commit: add --trailer option" might be a better subject.
Quoted 3 lines
Signed-off-by ZheNing Hu <[email protected]>---
[GSOC] commit: provides multiple signatures from command line
It looks like this is using the subject of a patch that previously attempted to add features with a similar purpose. I don't think you need to put it there, or if you want to refer to it, I think it might be better to be a bit more explicit, for example like:
"This patch replaces my previous attempt to provide similar features in a patch called: [GSOC] commit: provides multiple signatures from command line."
Quoted 4 lines
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.
Ok, I agree that it's a good idea to have a good generic solution first, before having specialized options for specific trailers.
Quoted 5 lines
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/901Range-diff vs v1:
If this patch series has very few code and commit messages in common with a previous attempt at implementing similar features, it might be better to make it a new patch series rather than a v2. This could avoid sending range-diffs that are mostly useless.
Re: [PATCH v2] [GSOC] commit: add trailer command
Quoted 6 lines · Christian Couder <[email protected]> 于2021年3月14日周日 下午12:19写道:
Quoted 3 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Quoted 8 lines
Quoted 4 lines
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide richer trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Nit: not sure that "richer" is the proper word here. I would just use "other" instead.
OK.
Quoted 11 lines
Quoted 2 lines
Now use
--trailer <token>[(=|:)<value>]pass the trailers tointerpret-trailersand generate trailers in commit messages.The subject says "add trailer command" while here you say "use". So which one is it? Does "--trailer" already exist, and we are just going to use it? Or will this patch series actually "add" it?
Looking at the existing options and the code of this patch series, the patch series actually adds the "--trailer" (not "trailer") option, so "add" or "implement" would be clearer than "use".
You're right. "add" will be more accurate in this situation.
Quoted 16 lines
So maybe something like the following might be better:
"Now implement a new
--trailer <token>[(=|:)<value>]option to pass other trailers tointerpret-trailersand insert them into commit messages."Also something like "--trailer" is usually called an option (or sometimes a flag), not a command (especially not when the word is not a verb, and when the new feature isn't a new exclusive mode of operation). So something like "commit: add --trailer option" might be a better subject.
Quoted 3 lines
Signed-off-by ZheNing Hu <[email protected]>---
[GSOC] commit: provides multiple signatures from command line
Quoted 9 lines
It looks like this is using the subject of a patch that previously attempted to add features with a similar purpose. I don't think you need to put it there, or if you want to refer to it, I think it might be better to be a bit more explicit, for example like:
"This patch replaces my previous attempt to provide similar features in a patch called: [GSOC] commit: provides multiple signatures from command line."
I may have thought that the effect of the two patch was closer so did not change it.
Quoted 8 lines
Quoted 4 lines
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.
Ok, I agree that it's a good idea to have a good generic solution first, before having specialized options for specific trailers.
Thanks. :)
Quoted 10 lines
Quoted 5 lines
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/901Range-diff vs v1:
If this patch series has very few code and commit messages in common with a previous attempt at implementing similar features, it might be better to make it a new patch series rather than a v2. This could avoid sending range-diffs that are mostly useless.
Thank you for these pertinent suggestions. I will pay more attention.
Re: [PATCH v2] [GSOC] commit: add trailer command
In reply to Christian CouderQuoted 7 lines · Christian Couder
Ok, I agree that it's a good idea to have a good generic solution first, before having specialized options for specific trailers.
Quoted 4 lines
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Quoted 6 lines
Quoted 1 line
Range-diff vs v1:
If this patch series has very few code and commit messages in common with a previous attempt at implementing similar features, it might be better to make it a new patch series rather than a v2. This could avoid sending range-diffs that are mostly useless.
Thanks for all the good suggestions.
PATCH v3 1/1 commit: add --trailer option
In reply to ZheNing Hu via GitGitGadgetFrom: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new --trailer <token>[(=|:)<value>] option to pass other trailers to interpret-trailers and insert them into commit messages.
---
[GSOC] commit: add --trailer option
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.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Range-diff vs v2:
1: 4c507d17db4f ! 1: b4e161a98f8b [GSOC] commit: add trailer command
@@ Metadata
Author: ZheNing Hu <[email protected]>
## Commit message ##
- [GSOC] commit: add trailer command
+ [GSOC] commit: add --trailer option
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line.
- But users may need to provide richer trailer information from the
+ But users may need to provide other trailer information from the
command line such as "Helped-by", "Reported-by", "Mentored-by",
- Now use --trailer <token>[(=|:)<value>] pass the trailers to
- interpret-trailers and generate trailers in commit messages.
+ Now implement a new --trailer <token>[(=|:)<value>] option to pass
+ other trailers to interpret-trailers and insert them into commit
+ messages.
Documentation/git-commit.txt | 8 +++++++- builtin/commit.c | 18 ++++++++++++++++++ t/t7502-commit-porcelain.sh | 20 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-)
Documentation/git-commit.txt +7 -1
@@ -14,7 +14,7 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...] DESCRIPTION -----------
@@ -166,6 +166,12 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter <[email protected]>" \ + --trailer "Helped-by:C O Mitter <[email protected]>"`will add the "Signed-off" trailer + and the "Helped-by" trailer in the commit message.) + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.
builtin/commit.c +18 -0
@@ -113,6 +113,8 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +struct child_process run_trailer =CHILD_PROCESS_INIT ; +static const char *trailer;/* * The default commit message cleanup mode will remove the lines
@@ -131,6 +133,17 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +if (unset) { +strvec_clear (&run_trailer.args); +return -1 ; + } + run_trailer.git_cmd =1 ; +strvec_pushl (&run_trailer.args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
@@ -958,6 +971,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +run_command (&run_trailer); +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be
@@ -1507,6 +1522,7 @@ 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 (0 ,"trailer" , &trailer,N_ ("trailer" ),N_ ("trailer(s) to add" ), 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")),
@@ -1577,6 +1593,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)die (_ ("could not parse HEAD commit" )); } verbose =-1 ;/* unspecified */ +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--in-place" ,"--where=end" ,git_path_commit_editmsg (),NULL ); argc =parse_and_validate_options (argc, argv, builtin_commit_options, builtin_commit_usage, prefix, current_head, &s);
t/t7502-commit-porcelain.sh +20 -0
@@ -154,6 +154,26 @@ test_expect_success 'sign off' ' ' +test_expect_success 'trailer' ' + >file1 && + git add file1 && + git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ + --trailer "Helped-by:C O Mitter2 <[email protected]>" \ + --trailer "Reported-by:C O Mitter3 <[email protected]>" \ + --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ + -m "hello" && + git cat-file commit HEAD >commit.msg && + sed -e "1,7d" commit.msg >actual && + cat >expected <<-\EOF && + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter1 <[email protected]> + Helped-by: C O Mitter2 <[email protected]> + Reported-by: C O Mitter3 <[email protected]> + Mentored-by: C O Mitter4 <[email protected]> + EOF + test_cmp expected actual +' + test_expect_success 'multiple -m' ' >negative &&
base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945
Signature · 1 line
gitgitgadget
Re: [PATCH v3] [GSOC] commit: add --trailer option
Quoted 32 lines · ZheNing Hu via GitGitGadget
builtin/commit.c +13
-0@@ -113,6 +113,8 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +struct child_process run_trailer =CHILD_PROCESS_INIT ; +static const char *trailer;/* * The default commit message cleanup mode will remove the lines @@ -131,6 +133,17 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +if (unset) { +strvec_clear (&run_trailer.args); +return -1 ; + } + run_trailer.git_cmd =1 ; +strvec_pushl (&run_trailer.args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 975
Quoted 5 lines
builtin/commit.c +2
-0@@ -958,6 +971,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +run_command (&run_trailer); +
There is slight problem with running the command unconditionally. If no --trailer is passed, then the opt_pass_trailer() backend is never called, which consequently will not set the trailer command ".git_cmd" option to 1.
This will lead the run_command() API to not interpret the command as git internal, and attempt to launch as an usual command "interpret-trailers" that will likely not exist or launch an unwanted command that is not part of the GIT suite.
This can be seen by running git commit without any options:
$ ./bin-wrappers/git -C /tmp/test commit
error: cannot run interpret-trailers: No such file or directory
...The .git_cmd should be set to true before running the command.
(the above output is from a built version with v2.31.0-rc2 + this patch
for confirmation).
Furthermore, in my opinion, we shouldn't even bother to run the command if no --trailer is passed, otherwise, we always be paying the cost of launching an OS process regardless if the user doesn't want to add trailers in theirs projects.
With that said and based on this current implementation, maybe an improved version will look like:
if (run_trailer.args.nr) {
run_trailer.git_cmd = 1;
run_command(&run_trailer);
}Naturally the git_cmd = 1 will be removed from opt_pass_trailer() function as it won't be necessary. As minor bonus, we don't end up setting the value for every new --trailer :).
Quoted 12 lines
builtin/commit.c +1
-0/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be @@ -1507,6 +1522,7 @@ 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 (0 ,"trailer" , &trailer,N_ ("trailer" ),N_ ("trailer(s) to add" ), 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")),
builtin/commit.c int cmd_commit(int argc, const char **argv, const char *prefix) · line 1597
Quoted 5 lines
builtin/commit.c +2
-0@@ -1577,6 +1593,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)die (_ ("could not parse HEAD commit" )); } verbose =-1 ;/* unspecified */ +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--in-place" ,"--where=end" ,git_path_commit_editmsg (),NULL );
Style: The "--in-place" part should be aligned with the parentheses much the like the following line with the "argc = parse_and_validate_options....".
For example:
strvec_pushl(&run_trailer.args, "interpret-trailers", "--in-place", "--where=end", .....
Quoted 9 lines
builtin/commit.c +0
-0argc =parse_and_validate_options (argc, argv, builtin_commit_options, builtin_commit_usage, prefix, current_head, &s);t/t7502-commit-porcelain.sh +0
-0@@ -154,6 +154,26 @@ test_expect_success 'sign off' '
t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 164
Quoted 10 lines
t/t7502-commit-porcelain.sh +8
-0' +test_expect_success 'trailer' ' + >file1 && + git add file1 && + git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ + --trailer "Helped-by:C O Mitter2 <[email protected]>" \ + --trailer "Reported-by:C O Mitter3 <[email protected]>" \ + --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ + -m "hello" &&
Perhaps here, the --trailer lines and "-m hello" option should be indent in order to make it clear that these option are part of the "git commit" from the above line, something like this:
git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ --trailer "Helped-by:C O Mitter2 <[email protected]>" \ --trailer "Reported-by:C O Mitter3 <[email protected]>" \ --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ -m "hello" &&
t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 177
Quoted 13 lines
t/t7502-commit-porcelain.sh +12
-0+ git cat-file commit HEAD >commit.msg && + sed -e "1,7d" commit.msg >actual && + cat >expected <<-\EOF && + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter1 <[email protected]> + Helped-by: C O Mitter2 <[email protected]> + Reported-by: C O Mitter3 <[email protected]> + Mentored-by: C O Mitter4 <[email protected]> + EOF + test_cmp expected actual +' + test_expect_success 'multiple -m' '
Hope these comments are useful.
Signature · 2 lines
Thanks Rafael
Re: [PATCH v3] [GSOC] commit: add --trailer option
Quoted 72 lines · Rafael Silva <[email protected]> 于2021年3月14日周日 下午9:46写道:
Quoted 32 lines · ZheNing Hu via GitGitGadget
builtin/commit.c +13
-0@@ -113,6 +113,8 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +struct child_process run_trailer =CHILD_PROCESS_INIT ; +static const char *trailer;/* * The default commit message cleanup mode will remove the lines @@ -131,6 +133,17 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +if (unset) { +strvec_clear (&run_trailer.args); +return -1 ; + } + run_trailer.git_cmd =1 ; +strvec_pushl (&run_trailer.args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 975
Quoted 5 lines
builtin/commit.c +2
-0@@ -958,6 +971,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +run_command (&run_trailer); +There is slight problem with running the command unconditionally. If no --trailer is passed, then the
opt_pass_trailer()backend is never called, which consequently will not set the trailer command ".git_cmd" option to 1.This will lead the
run_command()API to not interpret the command as git internal, and attempt to launch as an usual command "interpret-trailers" that will likely not exist or launch an unwanted command that is not part of the GIT suite.This can be seen by running
git commitwithout any options:$ ./bin-wrappers/git -C /tmp/test commit error: cannot run interpret-trailers: No such file or directory ...The
.git_cmdshould be set to true before running the command.(the above output is from a built version with v2.31.0-rc2 + this patch
for confirmation).Furthermore, in my opinion, we shouldn't even bother to run the command if no --trailer is passed, otherwise, we always be paying the cost of launching an OS process regardless if the user doesn't want to add trailers in theirs projects.
With that said and based on this current implementation, maybe an improved version will look like:
Quoted 8 lines
if (run_trailer.args.nr) { run_trailer.git_cmd = 1; run_command(&run_trailer); }Naturally the
git_cmd = 1will be removed fromopt_pass_trailer()function as it won't be necessary. As minor bonus, we don't end up setting the value for every new --trailer :).
Thank you, I didn't notice the problem before :).
Quoted 13 lines
Quoted 13 lines
builtin/commit.c +1
-0/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be @@ -1507,6 +1522,7 @@ 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 (0 ,"trailer" , &trailer,N_ ("trailer" ),N_ ("trailer(s) to add" ), 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")),@@ -1577,6 +1593,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
Quoted 9 lines
builtin/commit.c int cmd_commit(int argc, const char **argv, const char *prefix) · line 1597
Quoted 5 lines
builtin/commit.c +2
-0die (_ ("could not parse HEAD commit" )); } verbose =-1 ;/* unspecified */ +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--in-place" ,"--where=end" ,git_path_commit_editmsg (),NULL );Style: The "--in-place" part should be aligned with the parentheses much the like the following line with the "argc =
parse_and_validate_options....".
Well, the CodingGuidelines say it's both vaild. But you are right, try to keep the same format as nearby code will be better.
Quoted 50 lines
For example:
strvec_pushl(&run_trailer.args, "interpret-trailers", "--in-place", "--where=end", .....Quoted 9 lines
builtin/commit.c +0
-0argc =parse_and_validate_options (argc, argv, builtin_commit_options, builtin_commit_usage, prefix, current_head, &s);t/t7502-commit-porcelain.sh +0
-0@@ -154,6 +154,26 @@ test_expect_success 'sign off' 't/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 164
Quoted 10 lines
t/t7502-commit-porcelain.sh +8
-0' +test_expect_success 'trailer' ' + >file1 && + git add file1 && + git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ + --trailer "Helped-by:C O Mitter2 <[email protected]>" \ + --trailer "Reported-by:C O Mitter3 <[email protected]>" \ + --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ + -m "hello" &&Perhaps here, the --trailer lines and "-m hello" option should be indent in order to make it clear that these option are part of the "git commit" from the above line, something like this:
git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ --trailer "Helped-by:C O Mitter2 <[email protected]>" \ --trailer "Reported-by:C O Mitter3 <[email protected]>" \ --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ -m "hello" &&t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 177
Quoted 13 lines
t/t7502-commit-porcelain.sh +12
-0+ git cat-file commit HEAD >commit.msg && + sed -e "1,7d" commit.msg >actual && + cat >expected <<-\EOF && + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter1 <[email protected]> + Helped-by: C O Mitter2 <[email protected]> + Reported-by: C O Mitter3 <[email protected]> + Mentored-by: C O Mitter4 <[email protected]> + EOF + test_cmp expected actual +' + test_expect_success 'multiple -m' '
Quoted 4 lines
Hope these comments are useful.
--
Thanks
Rafael
I am gratitude to you for helping me.
--
Thanks
ZheNing Hu
PATCH v4 1/1 commit: add --trailer option
In reply to ZheNing Hu via GitGitGadgetFrom: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new --trailer <token>[(=|:)<value>] option to pass other trailers to interpret-trailers and insert them into commit messages.
---
[GSOC] commit: add --trailer option
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.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v4
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Range-diff vs v3:
1: b4e161a98f8b ! 1: dc507553ef4f [GSOC] commit: add --trailer option
@@ Documentation/git-commit.txt: The `-m` option is mutually exclusive with `-c`, `
+--trailer <token>[(=|:)<value>]::
+ Specify a (<token>, <value>) pair that should be applied as a
-+ trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter <[email protected]>" \
-+ --trailer "Helped-by:C O Mitter <[email protected]>"`will add the "Signed-off" trailer
++ trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \
++ <[email protected]>" --trailer "Helped-by:C O Mitter \
++ <[email protected]>"` will add the "Signed-off" trailer
+ and the "Helped-by" trailer in the commit message.)
+
-n::
@@ builtin/commit.c: static struct strbuf message = STRBUF_INIT;
+ strvec_clear(&run_trailer.args);
+ return -1;
+ }
-+ run_trailer.git_cmd = 1;
+ strvec_pushl(&run_trailer.args, "--trailer", arg, NULL);
+ return 0;
+}
@@ builtin/commit.c: static int prepare_to_commit(const char *index_file, const cha
fclose(s->fp);
-+ run_command(&run_trailer);
++ if (run_trailer.args.nr != 4) {
++ run_trailer.git_cmd = 1;
++ run_command(&run_trailer);
++ } else
++ strvec_clear(&run_trailer.args);
+
/*
* Reject an attempt to record a non-merge empty commit without
@@ builtin/commit.c: int cmd_commit(int argc, const char **argv, const char *prefix
}
verbose = -1; /* unspecified */
+ strvec_pushl(&run_trailer.args, "interpret-trailers",
-+ "--in-place", "--where=end", git_path_commit_editmsg(), NULL);
++ "--in-place", "--where=end", git_path_commit_editmsg(), NULL);
argc = parse_and_validate_options(argc, argv, builtin_commit_options,
builtin_commit_usage,
prefix, current_head, &s);
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' '
+ >file1 &&
+ git add file1 &&
+ git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \
-+ --trailer "Helped-by:C O Mitter2 <[email protected]>" \
-+ --trailer "Reported-by:C O Mitter3 <[email protected]>" \
-+ --trailer "Mentored-by:C O Mitter4 <[email protected]>" \
-+ -m "hello" &&
++ --trailer "Helped-by:C O Mitter2 <[email protected]>" \
++ --trailer "Reported-by:C O Mitter3 <[email protected]>" \
++ --trailer "Mentored-by:C O Mitter4 <[email protected]>" \
++ -m "hello" &&
+ git cat-file commit HEAD >commit.msg &&
+ sed -e "1,7d" commit.msg >actual &&
+ cat >expected <<-\EOF &&Documentation/git-commit.txt | 9 ++++++++- builtin/commit.c | 21 +++++++++++++++++++++ t/t7502-commit-porcelain.sh | 20 ++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-)
Documentation/git-commit.txt +8 -1
@@ -14,7 +14,7 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...] DESCRIPTION -----------
@@ -166,6 +166,13 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off" trailer + and the "Helped-by" trailer in the commit message.) + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.
builtin/commit.c +21 -0
@@ -113,6 +113,8 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +struct child_process run_trailer =CHILD_PROCESS_INIT ; +static const char *trailer;/* * The default commit message cleanup mode will remove the lines
@@ -131,6 +133,16 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +if (unset) { +strvec_clear (&run_trailer.args); +return -1 ; + } +strvec_pushl (&run_trailer.args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
@@ -958,6 +970,12 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +if (run_trailer.args.nr !=4 ) { + run_trailer.git_cmd =1 ; +run_command (&run_trailer); + }else +strvec_clear (&run_trailer.args); +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be
@@ -1507,6 +1525,7 @@ 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 (0 ,"trailer" , &trailer,N_ ("trailer" ),N_ ("trailer(s) to add" ), 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")),
@@ -1577,6 +1596,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)die (_ ("could not parse HEAD commit" )); } verbose =-1 ;/* unspecified */ +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--in-place" ,"--where=end" ,git_path_commit_editmsg (),NULL ); argc =parse_and_validate_options (argc, argv, builtin_commit_options, builtin_commit_usage, prefix, current_head, &s);
t/t7502-commit-porcelain.sh +20 -0
@@ -154,6 +154,26 @@ test_expect_success 'sign off' ' ' +test_expect_success 'trailer' ' + >file1 && + git add file1 && + git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ + --trailer "Helped-by:C O Mitter2 <[email protected]>" \ + --trailer "Reported-by:C O Mitter3 <[email protected]>" \ + --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ + -m "hello" && + git cat-file commit HEAD >commit.msg && + sed -e "1,7d" commit.msg >actual && + cat >expected <<-\EOF && + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter1 <[email protected]> + Helped-by: C O Mitter2 <[email protected]> + Reported-by: C O Mitter3 <[email protected]> + Mentored-by: C O Mitter4 <[email protected]> + EOF + test_cmp expected actual +' + test_expect_success 'multiple -m' ' >negative &&
base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945
Signature · 1 line
gitgitgadget
Re: [PATCH v4] [GSOC] commit: add --trailer option
builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 975
Quoted 7 lines · ZheNing Hu via GitGitGadget
builtin/commit.c +3
-0@@ -958,6 +970,12 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +if (run_trailer.args.nr !=4 ) { + run_trailer.git_cmd =1 ; +run_command (&run_trailer);
This hardcoded magic 4 is very brittle. It probably makes sense to have another string vector, that is used only to accumulate --trailer arguments and nothing else, and check if that string vector is empty here.
IOW this part would become ...
if (trailer_args.nr) {
strvec_pushl(&run_trailer.args, "interpret-trailers",
"--in-place", ...);
strvec_pushv(&run_trailer.args, trailer_args.v);
run_trailer.git_cmd = 1;
run_command(&run_trailer);
}builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 977
Quoted 2 lines
builtin/commit.c +2
-0+ }else +strvec_clear (&run_trailer.args);
... and there is no need to have "else" that won't need to do anything.
Quoted 12 lines
builtin/commit.c +1
-0/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be @@ -1507,6 +1525,7 @@ 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 (0 ,"trailer" , &trailer,N_ ("trailer" ),N_ ("trailer(s) to add" ), 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")),
builtin/commit.c int cmd_commit(int argc, const char **argv, const char *prefix) · line 1600
Quoted 5 lines
builtin/commit.c +2
-0@@ -1577,6 +1596,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)die (_ ("could not parse HEAD commit" )); } verbose =-1 ;/* unspecified */ +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--in-place" ,"--where=end" ,git_path_commit_editmsg (),NULL );
And this line will be gone.
Quoted 3 lines
builtin/commit.c +0
-0argc =parse_and_validate_options (argc, argv, builtin_commit_options, builtin_commit_usage, prefix, current_head, &s);
Re: [PATCH v4] [GSOC] commit: add --trailer option
Quoted 10 lines · Junio C Hamano <[email protected]> 于2021年3月15日周一 上午7:52写道:
IOW this part would become ...
if (trailer_args.nr) { strvec_pushl(&run_trailer.args, "interpret-trailers", "--in-place", ...); strvec_pushv(&run_trailer.args, trailer_args.v); run_trailer.git_cmd = 1; run_command(&run_trailer); }
Quoted 5 lines
builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 977
Quoted 2 lines
builtin/commit.c +2
-0+ }else +strvec_clear (&run_trailer.args);... and there is no need to have "else" that won't need to do anything.
Yes, but we also should clear "trailer_args" in "else" here, and check the return value of the "run_command()" for clear "run_trailer.args".
Quoted 7 lines
builtin/commit.c int cmd_commit(int argc, const char **argv, const char *prefix) · line 1600
Quoted 4 lines
verbose = -1; /* unspecified */builtin/commit.c +2
-0+strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--in-place" ,"--where=end" ,git_path_commit_editmsg (),NULL );And this line will be gone.
Indeed so.
Thanks.
Re: [PATCH v4] [GSOC] commit: add --trailer option
Quoted 11 lines · ZheNing Hu
Quoted 10 lines · Junio C Hamano <[email protected]> 于2021年3月15日周一 上午7:52写道:
IOW this part would become ...
if (trailer_args.nr) { strvec_pushl(&run_trailer.args, "interpret-trailers", "--in-place", ...); strvec_pushv(&run_trailer.args, trailer_args.v); run_trailer.git_cmd = 1; run_command(&run_trailer); }
Quoted 8 lines
Quoted 5 lines
builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 977
Quoted 2 lines
builtin/commit.c +2
-0+ }else +strvec_clear (&run_trailer.args);... and there is no need to have "else" that won't need to do anything.
Yes, but we also should clear "
trailer_args" in "else" here, and check the return value of the "run_command()" for clear "run_trailer.args".
No. If you introduce the separate strvec, the "else" clause runs only when trailer_args haven't got anything, so there is nothing to clear.
Re: [PATCH v4] [GSOC] commit: add --trailer option
Quoted 20 lines · Junio C Hamano <[email protected]> 于2021年3月15日周一 下午12:42写道:
Quoted 17 lines · ZheNing Hu
Quoted 15 lines · Junio C Hamano <[email protected]> 于2021年3月15日周一 上午7:52写道:
IOW this part would become ...
if (trailer_args.nr) { strvec_pushl(&run_trailer.args, "interpret-trailers", "--in-place", ...); strvec_pushv(&run_trailer.args, trailer_args.v); run_trailer.git_cmd = 1; run_command(&run_trailer); }builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 977
Quoted 2 lines
builtin/commit.c +2
-0+ }else +strvec_clear (&run_trailer.args);... and there is no need to have "else" that won't need to do anything.
Quoted 7 lines
Quoted 2 lines
Yes, but we also should clear "
trailer_args" in "else" here, and check the return value of the "run_command()" for clear "run_trailer.args".No. If you introduce the separate strvec, the "else" clause runs only when
trailer_argshaven't got anything, so there is nothing to clear.
I admit I was wrong before. But this may be the right thing to do.
+ if (trailer_args.nr) {
+ strvec_pushl(&run_trailer.args, "interpret-trailers",
+ "--in-place", "--where=end",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);
+ strvec_clear(&trailer_args);
+ }
PATCH v5 1/1 commit: add --trailer option
In reply to ZheNing Hu via GitGitGadgetFrom: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new --trailer <token>[(=|:)<value>] option to pass other trailers to interpret-trailers and insert them into commit messages.
---
[GSOC] commit: add --trailer option
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.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v5
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v5
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Range-diff vs v4:
1: dc507553ef4f ! 1: ca91accb2852 [GSOC] commit: add --trailer option
@@ builtin/commit.c: static int config_commit_verbose = -1; /* unspecified */
static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;
static char *sign_commit, *pathspec_from_file;
+struct child_process run_trailer = CHILD_PROCESS_INIT;
++struct strvec trailer_args = STRVEC_INIT;
+static const char *trailer;
/*
@@ builtin/commit.c: static struct strbuf message = STRBUF_INIT;
+static int opt_pass_trailer(const struct option *opt, const char *arg, int unset)
+{
+ if (unset) {
-+ strvec_clear(&run_trailer.args);
++ strvec_clear(&trailer_args);
+ return -1;
+ }
-+ strvec_pushl(&run_trailer.args, "--trailer", arg, NULL);
++ strvec_pushl(&trailer_args, "--trailer", arg, NULL);
+ return 0;
+}
+
@@ builtin/commit.c: static int prepare_to_commit(const char *index_file, const cha
fclose(s->fp);
-+ if (run_trailer.args.nr != 4) {
++ if (trailer_args.nr) {
++ strvec_pushl(&run_trailer.args, "interpret-trailers",
++ "--in-place", "--where=end", git_path_commit_editmsg(), NULL);
++ strvec_pushv(&run_trailer.args, trailer_args.v);
+ run_trailer.git_cmd = 1;
-+ run_command(&run_trailer);
-+ } else
-+ strvec_clear(&run_trailer.args);
++ if (run_command(&run_trailer))
++ strvec_clear(&run_trailer.args);
++ strvec_clear(&trailer_args);
++ }
+
/*
* Reject an attempt to record a non-merge empty commit without
@@ builtin/commit.c: int cmd_commit(int argc, const char **argv, const char *prefix
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")),
-@@ builtin/commit.c: int cmd_commit(int argc, const char **argv, const char *prefix)
- die(_("could not parse HEAD commit"));
- }
- verbose = -1; /* unspecified */
-+ strvec_pushl(&run_trailer.args, "interpret-trailers",
-+ "--in-place", "--where=end", git_path_commit_editmsg(), NULL);
- argc = parse_and_validate_options(argc, argv, builtin_commit_options,
- builtin_commit_usage,
- prefix, current_head, &s);
## t/t7502-commit-porcelain.sh ##
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' 'Documentation/git-commit.txt | 9 ++++++++- builtin/commit.c | 24 ++++++++++++++++++++++++ t/t7502-commit-porcelain.sh | 20 ++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-)
Documentation/git-commit.txt +8 -1
@@ -14,7 +14,7 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...] DESCRIPTION -----------
@@ -166,6 +166,13 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off" trailer + and the "Helped-by" trailer in the commit message.) + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.
builtin/commit.c +24 -0
@@ -113,6 +113,9 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +struct child_process run_trailer =CHILD_PROCESS_INIT ; +struct strvec trailer_args =STRVEC_INIT ; +static const char *trailer;/* * The default commit message cleanup mode will remove the lines
@@ -131,6 +134,16 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +if (unset) { +strvec_clear (&trailer_args); +return -1 ; + } +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
@@ -958,6 +971,16 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +if (trailer_args.nr) { +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--in-place" ,"--where=end" ,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); +strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be
@@ -1507,6 +1530,7 @@ 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 (0 ,"trailer" , &trailer,N_ ("trailer" ),N_ ("trailer(s) to add" ), 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 +20 -0
@@ -154,6 +154,26 @@ test_expect_success 'sign off' ' ' +test_expect_success 'trailer' ' + >file1 && + git add file1 && + git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ + --trailer "Helped-by:C O Mitter2 <[email protected]>" \ + --trailer "Reported-by:C O Mitter3 <[email protected]>" \ + --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ + -m "hello" && + git cat-file commit HEAD >commit.msg && + sed -e "1,7d" commit.msg >actual && + cat >expected <<-\EOF && + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter1 <[email protected]> + Helped-by: C O Mitter2 <[email protected]> + Reported-by: C O Mitter3 <[email protected]> + Mentored-by: C O Mitter4 <[email protected]> + EOF + test_cmp expected actual +' + test_expect_success 'multiple -m' ' >negative &&
base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945
Signature · 1 line
gitgitgadget
Re: [PATCH v5] [GSOC] commit: add --trailer option
builtin/commit.c static int config_commit_verbose = -1; /* unspecified */ · line 116
Quoted 9 lines · ZheNing Hu via GitGitGadget
builtin/commit.c +1
-0@@ -113,6 +113,9 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +struct child_process run_trailer =CHILD_PROCESS_INIT ;
It seems to me that run_trailer is used only in the if (trailer_args.nr) {...} block, so it could be declared there instead of as a global variable.
builtin/commit.c static int config_commit_verbose = -1; /* unspecified */ · line 118
Quoted 2 lines
builtin/commit.c +2
-0+struct strvec trailer_args =STRVEC_INIT ; +static const char *trailer;
I am not sure that this trailervariable is really needed. It seems to be used only as the third argument to OPT_CALLBACK(), but there are other places in the code base where we pass NULL as the third argument.
Re: [PATCH v5] [GSOC] commit: add --trailer option
Quoted 4 lines · Christian Couder
On Mon, Mar 15, 2021 at 4:24 AM ZheNing Hu via GitGitGadget <[email protected]> wrote:
Quoted 15 lines
builtin/commit.c static int config_commit_verbose = -1; /* unspecified */ · line 116
Quoted 9 lines
builtin/commit.c +1
-0@@ -113,6 +113,9 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +struct child_process run_trailer =CHILD_PROCESS_INIT ;It seems to me that
run_traileris used only in theif (trailer_args.nr) {...}block, so it could be declared there instead of as a global variable.Quoted 1 line
builtin/commit.c +1
-0+struct strvec trailer_args =STRVEC_INIT ;
Also you might want to add "static" in front of "struct strvec" in the above line.
Re: [PATCH v5] [GSOC] commit: add --trailer option
In reply to Christian CouderQuoted 18 lines · Christian Couder <[email protected]> 于2021年3月15日周一 下午1:33写道:
builtin/commit.c static int config_commit_verbose = -1; /* unspecified */ · line 116
Quoted 9 lines · ZheNing Hu via GitGitGadget
builtin/commit.c +1
-0@@ -113,6 +113,9 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +struct child_process run_trailer =CHILD_PROCESS_INIT ;It seems to me that
run_traileris used only in theif (trailer_args.nr) {...}block, so it could be declared there instead of as a global variable.
Quoted 7 lines
builtin/commit.c static int config_commit_verbose = -1; /* unspecified */ · line 118
Quoted 2 lines
builtin/commit.c +2
-0+struct strvec trailer_args =STRVEC_INIT ; +static const char *trailer;I am not sure that this
trailervariable is really needed. It seems to be used only as the third argument toOPT_CALLBACK(), but there are other places in the code base where we pass NULL as the third argument.
Good advice.
PATCH v6 1/1 commit: add --trailer option
In reply to ZheNing Hu via GitGitGadgetFrom: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new --trailer <token>[(=|:)<value>] option to pass other trailers to interpret-trailers and insert them into commit messages.
---
[GSOC] commit: add --trailer option
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.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v6
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v6
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Range-diff vs v5:
1: ca91accb2852 ! 1: c99ce75da792 [GSOC] commit: add --trailer option
@@ builtin/commit.c: static int config_commit_verbose = -1; /* unspecified */
static int no_post_rewrite, allow_empty_message, pathspec_file_nul;
static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;
static char *sign_commit, *pathspec_from_file;
-+struct child_process run_trailer = CHILD_PROCESS_INIT;
+struct strvec trailer_args = STRVEC_INIT;
-+static const char *trailer;
/*
* The default commit message cleanup mode will remove the lines
@@ builtin/commit.c: static struct strbuf message = STRBUF_INIT;
+static int opt_pass_trailer(const struct option *opt, const char *arg, int unset)
+{
-+ if (unset) {
-+ strvec_clear(&trailer_args);
-+ return -1;
-+ }
++ BUG_ON_OPT_NEG(unset);
++
+ strvec_pushl(&trailer_args, "--trailer", arg, NULL);
+ return 0;
+}
@@ builtin/commit.c: static int prepare_to_commit(const char *index_file, const cha
fclose(s->fp);
+ if (trailer_args.nr) {
++ static struct child_process run_trailer = CHILD_PROCESS_INIT;
++
+ strvec_pushl(&run_trailer.args, "interpret-trailers",
+ "--in-place", "--where=end", git_path_commit_editmsg(), NULL);
+ strvec_pushv(&run_trailer.args, trailer_args.v);
@@ 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(0, "trailer", &trailer, N_("trailer"), N_("trailer(s) to add"), opt_pass_trailer),
++ OPT_CALLBACK_F(0, "trailer", NULL, N_("trailer"), N_("trailer(s) to add"), 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")),Documentation/git-commit.txt | 9 ++++++++- builtin/commit.c | 22 ++++++++++++++++++++++ t/t7502-commit-porcelain.sh | 20 ++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-)
Documentation/git-commit.txt +8 -1
@@ -14,7 +14,7 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...] DESCRIPTION -----------
@@ -166,6 +166,13 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off" trailer + and the "Helped-by" trailer in the commit message.) + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.
builtin/commit.c +22 -0
@@ -113,6 +113,7 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +struct strvec trailer_args =STRVEC_INIT ;/* * The default commit message cleanup mode will remove the lines
@@ -131,6 +132,14 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +BUG_ON_OPT_NEG (unset); + +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
@@ -958,6 +967,18 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +if (trailer_args.nr) { +static struct child_process run_trailer =CHILD_PROCESS_INIT ; + +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--in-place" ,"--where=end" ,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); +strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be
@@ -1507,6 +1528,7 @@ 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_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 +20 -0
@@ -154,6 +154,26 @@ test_expect_success 'sign off' ' ' +test_expect_success 'trailer' ' + >file1 && + git add file1 && + git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ + --trailer "Helped-by:C O Mitter2 <[email protected]>" \ + --trailer "Reported-by:C O Mitter3 <[email protected]>" \ + --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ + -m "hello" && + git cat-file commit HEAD >commit.msg && + sed -e "1,7d" commit.msg >actual && + cat >expected <<-\EOF && + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter1 <[email protected]> + Helped-by: C O Mitter2 <[email protected]> + Reported-by: C O Mitter3 <[email protected]> + Mentored-by: C O Mitter4 <[email protected]> + EOF + test_cmp expected actual +' + test_expect_success 'multiple -m' ' >negative &&
base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945
Signature · 1 line
gitgitgadget
Re: [PATCH v6] [GSOC] commit: add --trailer option
Quoted 27 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new
--trailer <token>[(=|:)<value>]option to pass other trailers tointerpret-trailersand insert them into commit messages.Signed-off-by ZheNing Hu <[email protected]>---
[GSOC] commit: add --trailer optionNow 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.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v6
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v6
Pull-Request: https://github.com/gitgitgadget/git/pull/901Range-diff vs v5:
Quoted 7 lines
1:
ca91accb2852! 1:c99ce75da792[GSOC] commit: add --trailer option@@ builtin/commit.c: static int config_commit_verbose = -1; /* unspecified */ static int no_post_rewrite, allow_empty_message, pathspec_file_nul; static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg; static char *sign_commit, *pathspec_from_file; -+struct child_process run_trailer = CHILD_PROCESS_INIT; +struct strvec trailer_args = STRVEC_INIT;
I suggested added "static" in front of the above line, like this:
static struct strvec trailer_args = STRVEC_INIT;
You can check with git grep '^static struct strvec' '*.c' and git grep '^struct strvec' '*.c' that we use "static" when declaring a 'struct strvec' globally.
[...]
Quoted 2 lines
+ if (trailer_args.nr) {
++ static structchild_processrun_trailer=CHILD_PROCESS_INIT;
I didn't suggest using "static" here.
Quoted 2 lines
++
+ strvec_pushl(&run_trailer.args, "interpret-trailers",
Thanks for working on this!
Re: [PATCH v6] [GSOC] commit: add --trailer option
Quoted 51 lines · Christian Couder <[email protected]> 于2021年3月15日周一 下午4:03写道:
Quoted 27 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new
--trailer <token>[(=|:)<value>]option to pass other trailers tointerpret-trailersand insert them into commit messages.Signed-off-by ZheNing Hu <[email protected]>---
[GSOC] commit: add --trailer optionNow 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.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v6
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v6
Pull-Request: https://github.com/gitgitgadget/git/pull/901Range-diff vs v5:
Quoted 7 lines
1:
ca91accb2852! 1:c99ce75da792[GSOC] commit: add --trailer option@@ builtin/commit.c: static int config_commit_verbose = -1; /* unspecified */ static int no_post_rewrite, allow_empty_message, pathspec_file_nul; static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg; static char *sign_commit, *pathspec_from_file; -+struct child_process run_trailer = CHILD_PROCESS_INIT; +struct strvec trailer_args = STRVEC_INIT;I suggested added "static" in front of the above line, like this:
static struct strvec
trailer_args=STRVEC_INIT;You can check with
git grep '^static struct strvec' '*.c'andgit grep '^struct strvec' '*.c'that we use "static" when declaring a 'struct strvec' globally.[...]
Quoted 2 lines
+ if (trailer_args.nr) {
++ static structchild_processrun_trailer=CHILD_PROCESS_INIT;
Quoted 6 lines
I didn't suggest using "static" here.
Quoted 2 lines
++
+ strvec_pushl(&run_trailer.args, "interpret-trailers",Thanks for working on this!
Well, I was too eager to submit it.
There are many rules for git projects to explore.
Thanks.
PATCH v7 1/1 commit: add --trailer option
In reply to ZheNing Hu via GitGitGadgetFrom: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new --trailer <token>[(=|:)<value>] option to pass other trailers to interpret-trailers and insert them into commit messages.
---
[GSOC] commit: add --trailer option
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.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v7
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v7
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Range-diff vs v6:
1: c99ce75da792 ! 1: 3ce8e8cac24a [GSOC] commit: add --trailer option
@@ builtin/commit.c: static int config_commit_verbose = -1; /* unspecified */
static int no_post_rewrite, allow_empty_message, pathspec_file_nul;
static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;
static char *sign_commit, *pathspec_from_file;
-+struct strvec trailer_args = STRVEC_INIT;
++static struct strvec trailer_args = STRVEC_INIT;
/*
* The default commit message cleanup mode will remove the lines
@@ builtin/commit.c: static int prepare_to_commit(const char *index_file, const cha
fclose(s->fp);
+ if (trailer_args.nr) {
-+ static struct child_process run_trailer = CHILD_PROCESS_INIT;
++ struct child_process run_trailer = CHILD_PROCESS_INIT;
+
+ strvec_pushl(&run_trailer.args, "interpret-trailers",
+ "--in-place", "--where=end", git_path_commit_editmsg(), NULL);Documentation/git-commit.txt | 9 ++++++++- builtin/commit.c | 22 ++++++++++++++++++++++ t/t7502-commit-porcelain.sh | 20 ++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-)
Documentation/git-commit.txt +8 -1
@@ -14,7 +14,7 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...] DESCRIPTION -----------
@@ -166,6 +166,13 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off" trailer + and the "Helped-by" trailer in the commit message.) + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.
builtin/commit.c +22 -0
@@ -113,6 +113,7 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct strvec trailer_args =STRVEC_INIT ;/* * The default commit message cleanup mode will remove the lines
@@ -131,6 +132,14 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +BUG_ON_OPT_NEG (unset); + +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
@@ -958,6 +967,18 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +if (trailer_args.nr) { +struct child_process run_trailer =CHILD_PROCESS_INIT ; + +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--in-place" ,"--where=end" ,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); +strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be
@@ -1507,6 +1528,7 @@ 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_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 +20 -0
@@ -154,6 +154,26 @@ test_expect_success 'sign off' ' ' +test_expect_success 'trailer' ' + >file1 && + git add file1 && + git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ + --trailer "Helped-by:C O Mitter2 <[email protected]>" \ + --trailer "Reported-by:C O Mitter3 <[email protected]>" \ + --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ + -m "hello" && + git cat-file commit HEAD >commit.msg && + sed -e "1,7d" commit.msg >actual && + cat >expected <<-\EOF && + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter1 <[email protected]> + Helped-by: C O Mitter2 <[email protected]> + Reported-by: C O Mitter3 <[email protected]> + Mentored-by: C O Mitter4 <[email protected]> + EOF + test_cmp expected actual +' + test_expect_success 'multiple -m' ' >negative &&
base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945
Signature · 1 line
gitgitgadget
Re: [PATCH v7] [GSOC] commit: add --trailer option
Documentation/git-commit.txt The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. · line 173
Quoted 9 lines · ZheNing Hu via GitGitGadget
Documentation/git-commit.txt +5
-0@@ -166,6 +166,13 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off" trailer
s/"Signed-off"/"Signed-off-by"/
Documentation/git-commit.txt The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. · line 174
Quoted 1 line
Documentation/git-commit.txt +1
-0+ and the "Helped-by" trailer in the commit message.)
It might be useful to point users to git interpret-trailers' documentation, for example by adding: "See linkgit:git-interpret-trailers[1]."
Otherwise, this looks good to me!
Re: [PATCH v7] [GSOC] commit: add --trailer option
In reply to ZheNing Hu via GitGitGadgetQuoted 6 lines · ZheNing Hu via GitGitGadget
+ if (trailer_args.nr) {
-+ static structchild_processrun_trailer=CHILD_PROCESS_INIT;
++ structchild_processrun_trailer=CHILD_PROCESS_INIT;
+
+ strvec_pushl(&run_trailer.args, "interpret-trailers",
+ "--in-place", "--where=end",git_path_commit_editmsg(), NULL);
Actually I don't think "--where=end" should be used here. "end" is the default for the "trailer.where" config variable, so by default if nothing has been configured, it will work as if "--where=end" was passed above.
If a user has configured "trailer.where" or trailer.<token>.where, then this should be respected. And users should be able to override such config variable using for example:
git -c trailer.where=start commit --trailer "Signed-off-by:C O Mitter <[email protected]>"
Re: [PATCH v7] [GSOC] commit: add --trailer option
Quoted 16 lines · Christian Couder <[email protected]> 于2021年3月15日周一 下午6:14写道:
Quoted 6 lines · ZheNing Hu via GitGitGadget
+ if (trailer_args.nr) {
-+ static structchild_processrun_trailer=CHILD_PROCESS_INIT;
++ structchild_processrun_trailer=CHILD_PROCESS_INIT;
+
+ strvec_pushl(&run_trailer.args, "interpret-trailers",
+ "--in-place", "--where=end",git_path_commit_editmsg(), NULL);Actually I don't think "--where=end" should be used here. "end" is the default for the "trailer.where" config variable, so by default if nothing has been configured, it will work as if "--where=end" was passed above.
Quoted 6 lines
If a user has configured "trailer.where" or trailer.<token>.where, then this should be respected. And users should be able to override such config variable using for example:
git -c trailer.where=start commit --trailer "Signed-off-by:C O Mitter <[email protected]>"
Thanks for reminding, generally speaking, we will put the trailer at the end of the commit messages.Take trailers in start, this should be something I haven't considered.
I notice another question:
if we commit this again with same trailer (even same email or same commiter) --trailer will not work again, because in interpret_trailers, "if-exists" default
set to "addIfDifferentNeighbor", I addvice enforce use "if-exists="add".
Thanks.
Re: [PATCH v7] [GSOC] commit: add --trailer option
Quoted 22 lines · ZheNing Hu
Quoted 20 lines · Christian Couder <[email protected]> 于2021年3月15日周一 下午6:14写道:
Quoted 6 lines · ZheNing Hu via GitGitGadget
+ if (trailer_args.nr) {
-+ static structchild_processrun_trailer=CHILD_PROCESS_INIT;
++ structchild_processrun_trailer=CHILD_PROCESS_INIT;
+
+ strvec_pushl(&run_trailer.args, "interpret-trailers",
+ "--in-place", "--where=end",git_path_commit_editmsg(), NULL);Actually I don't think "--where=end" should be used here. "end" is the default for the "trailer.where" config variable, so by default if nothing has been configured, it will work as if "--where=end" was passed above.
If a user has configured "trailer.where" or trailer.<token>.where, then this should be respected. And users should be able to override such config variable using for example:
Quoted 6 lines
Quoted 2 lines
git -c trailer.where=start commit --trailer "Signed-off-by:C O Mitter <[email protected]>"
Thanks for reminding, generally speaking, we will put the trailer at the end of the commit messages.Take trailers in start, this should be something I haven't considered.
In general what I want to say is that git interpret-trailers should be considered to have sensible defaults, that can possibly be overridden using a number of config variables (or the git -c ... mechanism) which is a good thing. If something in it doesn't work well, it's possible to improve it of course. Otherwise it's better to just fully take advantage of it.
Quoted 5 lines
I notice another question:
if we commit this again with same trailer (even same email or same commiter)--trailerwill not work again, because ininterpret_trailers, "if-exists" default
set to "addIfDifferentNeighbor", I addvice enforce use "if-exists="add".
I don't agree with using "--if-exists=add". I think the default to not add a trailer line if it would be just above or below the same line is better, as doing that wouldn't add much information. It's better to encourage people to use trailers in a meaningful way.
And again if we use "--if-exists=add", then people who would want to take advantage of git interpret-trailers to customize what happens when the trailer already exists would not be able to do it.
For example if we don't use "--if-exists=add", then:
- people who want to customize what happens when the trailer already exists can do it with for example:
git -c trailer.ifexists=addIfDifferent commit --trailer "Signed-off-by:C O Mitter <[email protected]>"
- which means that people who want the "--if-exists=add" behavior can still have it with:
git -c trailer.ifexists=add commit --trailer "Signed-off-by:C O Mitter <[email protected]>"
While if we use "--if-exists=add", then using git -c trailer.ifexists=... commit ... will not customize anything as the "--if-exists=add" command line option will override any config customization.
Re: [PATCH v7] [GSOC] commit: add --trailer option
Quoted 37 lines · Christian Couder <[email protected]> 于2021年3月16日周二 下午1:37写道:
Quoted 3 lines
Thanks for reminding, generally speaking, we will put the trailer at the end of the commit messages.Take trailers in start, this should be something I haven't considered.
In general what I want to say is that
git interpret-trailersshould be considered to have sensible defaults, that can possibly be overridden using a number of config variables (or the git -c ... mechanism) which is a good thing. If something in it doesn't work well, it's possible to improve it of course. Otherwise it's better to just fully take advantage of it.Quoted 5 lines
I notice another question:
if we commit this again with same trailer (even same email or same commiter)--trailerwill not work again, because ininterpret_trailers, "if-exists" default
set to "addIfDifferentNeighbor", I addvice enforce use "if-exists="add".I don't agree with using "--if-exists=add". I think the default to not add a trailer line if it would be just above or below the same line is better, as doing that wouldn't add much information. It's better to encourage people to use trailers in a meaningful way.
And again if we use "--if-exists=add", then people who would want to take advantage of
git interpret-trailersto customize what happens when the trailer already exists would not be able to do it.For example if we don't use "--if-exists=add", then:
- people who want to customize what happens when the trailer already exists can do it with for example:
git -c trailer.ifexists=addIfDifferent commit --trailer "Signed-off-by:C O Mitter <[email protected]>"
- which means that people who want the "--if-exists=add" behavior can still have it with:
Quoted 7 lines
git -c trailer.ifexists=add commit --trailer "Signed-off-by:C O Mitter <[email protected]>"
While if we use "--if-exists=add", then using
git -c trailer.ifexists=... commit ...will not customize anything as the "--if-exists=add" command line option will override any config customization.
Well, I see what you mean, this will keep git better flexibility, give users more personalized configuration options.
And this should be more in line with git design philosophy, I will follow your suggestion.
v8 cover commit: add --trailer option
In reply to ZheNing Hu via GitGitGadgetNow 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 (2):
[GSOC] commit: add --trailer option
interpret_trailers: for three options parse add warning
Documentation/git-commit.txt | 9 ++++++++- builtin/commit.c | 23 +++++++++++++++++++++++ builtin/interpret-trailers.c | 25 ++++++++++++++++++++++--- t/t7502-commit-porcelain.sh | 20 ++++++++++++++++++++ 4 files changed, 73 insertions(+), 4 deletions(-)
base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v8
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v8
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Range-diff vs v7:
1: 3ce8e8cac24a ! 1: f81b6e66a6ba [GSOC] commit: add --trailer option
@@ Documentation/git-commit.txt: The `-m` option is mutually exclusive with `-c`, `
+ Specify a (<token>, <value>) pair that should be applied as a
+ trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \
+ <[email protected]>" --trailer "Helped-by:C O Mitter \
-+ <[email protected]>"` will add the "Signed-off" trailer
++ <[email protected]>"` will add the "Signed-off-by" trailer
+ and the "Helped-by" trailer in the commit message.)
-+
++ 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
+ struct child_process run_trailer = CHILD_PROCESS_INIT;
+
+ strvec_pushl(&run_trailer.args, "interpret-trailers",
-+ "--in-place", "--where=end", git_path_commit_editmsg(), NULL);
++ "--in-place", "--if-exists=add",
++ git_path_commit_editmsg(), NULL);
+ strvec_pushv(&run_trailer.args, trailer_args.v);
+ run_trailer.git_cmd = 1;
+ if (run_command(&run_trailer)) -: ------------ > 2: 68e0bd9e2d6f interpret_trailers: for three options parse add warning
Signature · 1 line
gitgitgadget
PATCH v8 1/2 commit: add --trailer option
From: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new --trailer <token>[(=|:)<value>] option to pass other trailers to interpret-trailers and insert them into commit messages.
--- Documentation/git-commit.txt | 9 ++++++++- builtin/commit.c | 23 +++++++++++++++++++++++ t/t7502-commit-porcelain.sh | 20 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-)
Documentation/git-commit.txt +8 -1
@@ -14,7 +14,7 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...] DESCRIPTION -----------
@@ -166,6 +166,13 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off-by" trailer + and the "Helped-by" trailer in the commit message.) + See linkgit:git-interpret-trailers[1] for details. -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.
builtin/commit.c +23 -0
@@ -113,6 +113,7 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct strvec trailer_args =STRVEC_INIT ;/* * The default commit message cleanup mode will remove the lines
@@ -131,6 +132,14 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +BUG_ON_OPT_NEG (unset); + +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
@@ -958,6 +967,19 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +if (trailer_args.nr) { +struct child_process run_trailer =CHILD_PROCESS_INIT ; + +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--in-place" ,"--if-exists=add" , +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); +strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be
@@ -1507,6 +1529,7 @@ 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_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 +20 -0
@@ -154,6 +154,26 @@ test_expect_success 'sign off' ' ' +test_expect_success 'trailer' ' + >file1 && + git add file1 && + git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ + --trailer "Helped-by:C O Mitter2 <[email protected]>" \ + --trailer "Reported-by:C O Mitter3 <[email protected]>" \ + --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ + -m "hello" && + git cat-file commit HEAD >commit.msg && + sed -e "1,7d" commit.msg >actual && + cat >expected <<-\EOF && + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter1 <[email protected]> + Helped-by: C O Mitter2 <[email protected]> + Reported-by: C O Mitter3 <[email protected]> + Mentored-by: C O Mitter4 <[email protected]> + EOF + test_cmp expected actual +' + test_expect_success 'multiple -m' ' >negative &&
Signature · 1 line
gitgitgadget
Re: [PATCH v8 1/2] [GSOC] commit: add --trailer option
Quoted 10 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new
--trailer <token>[(=|:)<value>]option to pass other trailers tointerpret-trailersand insert them into commit messages.
I paged through v1-v8, looking mostly good so far. Some comments:
Quoted 65 lines
Signed-off-by ZheNing Hu <[email protected]>--- Documentation/git-commit.txt | 9 ++++++++- builtin/commit.c | 23 +++++++++++++++++++++++ t/t7502-commit-porcelain.sh | 20 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-)Documentation/git-commit.txt +8
-1@@ -14,7 +14,7 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...] DESCRIPTION -----------@@ -166,6 +166,13 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off-by" trailer + and the "Helped-by" trailer in the commit message.) + See linkgit:git-interpret-trailers[1] for details. -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.builtin/commit.c +9
-0@@ -113,6 +113,7 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct strvec trailer_args =STRVEC_INIT ;/* * The default commit message cleanup mode will remove the lines @@ -131,6 +132,14 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +BUG_ON_OPT_NEG (unset); + +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;@@ -958,6 +967,19 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp);
builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 979
Quoted 10 lines
builtin/commit.c +10
-0+if (trailer_args.nr) { +struct child_process run_trailer =CHILD_PROCESS_INIT ; + +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--in-place" ,"--if-exists=add" , +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);
This is git-commit, shouldn't we die() here instead of ignoring errors in sub-processes?
builtin/commit.c int cmd_commit(int argc, const char **argv, const char *prefix) · line 1533
Quoted 12 lines
builtin/commit.c +4
-0+strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be @@ -1507,6 +1529,7 @@ 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_BOOL('s', "signoff", &signoff, N_("add a Signed-off-by trailer")),
Not required for this change, but perhaps a change here to N_() (if we can get it to fit) + doc update saying that we prefer --trailer="Signed-Off-By: to --signoff"? More on that later.
Quoted 20 lines
builtin/commit.c +0
-0OPT_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 +10
-0@@ -154,6 +154,26 @@ test_expect_success 'sign off' ' ' +test_expect_success 'trailer' ' + >file1 && + git add file1 && + git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ + --trailer "Helped-by:C O Mitter2 <[email protected]>" \ + --trailer "Reported-by:C O Mitter3 <[email protected]>" \ + --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ + -m "hello" && + git cat-file commit HEAD >commit.msg && + sed -e "1,7d" commit.msg >actual &&
t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 176
Quoted 10 lines
t/t7502-commit-porcelain.sh +10
-0+ cat >expected <<-\EOF && + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter1 <[email protected]> + Helped-by: C O Mitter2 <[email protected]> + Reported-by: C O Mitter3 <[email protected]> + Mentored-by: C O Mitter4 <[email protected]> + EOF + test_cmp expected actual +' +
How does this interact with cases where the user has configured "trailer.separators" to have a value that doesn't contain ":"? I haven't tested, but my reading of git-interpret-trailers(1) is that if you supplied "=" instead that case would just work:
By default only : is recognized as a trailer separator, except that = is always accepted on the command line for compatibility with other git commands.
I don't know if that does the right thing in the presence of --if-exists=add.
So it would be good to update these tests so you test:
* For the --if-exists=add case at all, there's no tests for it now. I.e. add some trailers manually to the commit (via -F or whatever) and then see if they get added to, replacet etc.
* Ditto but for the user having configured trailer.separators (see the test_config helper for how to set config in a test). I.e. if it's "=" does adding trailers work, how about if it's "=" on the CLI but the config/commit message has ";" instead of ":" or something?
* Hrm, actually I think tweaking "-c trailer.ifexists" won't work at all, since the CLI switch would override it. I honestly don't know, but why not not supply it and keep the addIfDifferentNeighbor default?
If it's essential that seems like a good test / documentation addition...
* For the above -c ... case I can't think of a good way to deal with it that doesn't involve pulling in git_trailer_config() into git_commit_config(), but perhaps the least nasty way is to just set a flag in git_commit_config() if we see a "trailer.ifexists" flag, and if so don't provide "--if-exists=add", if there's no config (this will include "git -c ... commit" we set provide "--if-exists=add" ) or as noted above, maybe we can skip the whole thing and use the addIfDifferentNeighbor default.
And, not needed for this patch but worth thinking about:
* We pass through --trailer to git-interpret-trailers, what should we do about the other options? Should git-commit eventually support --trailer-where and pass it along as --where to git-interpret-trailers, or is "git -c trailer.where=... commit" good enough?
* It would be good to test for and document if that "-c trailer.*" trick works (no reason it shouldn't). I.e. to add something like this after what you have (along with tests, and check if it's even true):
Only the --trailer argument to linkgit:git-interpret-trailers[1] is supported. Other pass-through switches may be added in the future, but currently you'll need to pass arguments to linkgit:git-interpret-trailers[1] along as config, e.g. git -c trailer.where=start commit [...] --trailer=[...].
* We have a longer-term goal of having the .mailmap apply to trailers, it would be nice if git-interpret-trailers had some fuzzy-matching to check if the RHS of a trailer is a name/E-Mail pair, and if so did stricter validation on it with the ident functions we use for fsck etc. (that's copied & subtly different in several different places in the codebase, unfortunately[1]).
More thoughts:
* Having written all the above I checked how --signoff is implemented.
It seems to me to be a good idea to (at least for testing) convert the --signoff trailer to your implementation. We have plenty of tests for it, does migrating it over pass or fail those?
* I also agree with Junio that we shouldn't have a --fixed-by or whatever and wouldn't add --signoff today, but it seems very useful to me to have a shortcut like:
--trailer "Signed-off-by"
I.e. omitting the value, or:
--trailer "Signed-off-by="
Or some other thing we deem sufficiently useful/sane syntax/unambiguous.n
Then the value would be provided by fmt_name(WANT_COMMITTER_IDENT) just as we do in append_signoff() now. I think a *very common* case for this would be something like:
git commit --amend -v --trailer "Reviewed-by"
And it would be useful to help that along and not have to do:
git commit --amend -v --trailer "Reviewed-by=$(git config user.name) <$(git config user.email)>"
Or worse yet, manually typo your name/e-mail address, as I'm sure I and many others will inevitably do when using this option...
Re: [PATCH v8 1/2] [GSOC] commit: add --trailer option
Quoted 5 lines · Ævar Arnfjörð Bjarmason <[email protected]> 于2021年3月16日周二 下午8:52写道:
builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 979
Quoted 2 lines
builtin/commit.c +2
-0+if (run_command (&run_trailer)) +strvec_clear (&run_trailer.args);This is git-commit, shouldn't we
die()here instead of ignoring errors in sub-processes?
After thinking about it carefully, your opinion is more reasonable, because if the user uses the wrong --trailer and does not get the information he needs, I think he will have to use --amend to modify, and die() can exit this commit directly.
Quoted 54 lines
builtin/commit.c int cmd_commit(int argc, const char **argv, const char *prefix) · line 1533
Quoted 13 lines
builtin/commit.c +4
-0+strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be @@ -1507,6 +1529,7 @@ 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_BOOL('s', "signoff", &signoff, N_("add a Signed-off-by trailer")),Not required for this change, but perhaps a change here to
N_()(if we can get it to fit) + doc update saying that we prefer --trailer="Signed-Off-By: to --signoff"? More on that later.Quoted 20 lines
builtin/commit.c +0
-0OPT_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 +10
-0@@ -154,6 +154,26 @@ test_expect_success 'sign off' ' ' +test_expect_success 'trailer' ' + >file1 && + git add file1 && + git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ + --trailer "Helped-by:C O Mitter2 <[email protected]>" \ + --trailer "Reported-by:C O Mitter3 <[email protected]>" \ + --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ + -m "hello" && + git cat-file commit HEAD >commit.msg && + sed -e "1,7d" commit.msg >actual &&t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 176
Quoted 10 lines
t/t7502-commit-porcelain.sh +10
-0+ cat >expected <<-\EOF && + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter1 <[email protected]> + Helped-by: C O Mitter2 <[email protected]> + Reported-by: C O Mitter3 <[email protected]> + Mentored-by: C O Mitter4 <[email protected]> + EOF + test_cmp expected actual +' +How does this interact with cases where the user has configured "trailer.separators" to have a value that doesn't contain ":"? I haven't tested, but my reading of git-interpret-trailers(1) is that if you supplied "=" instead that case would just work:
Quoted 4 lines
By default only : is recognized as a trailer separator, except that = is always accepted on the command line for compatibility with other git commands.
But interpret_trailers interface allow us use "=" instead of other separators.
I did a simple test and modified the configuration "trailer.separators" and it still works. Now things are good here:
$ git -c trailer.separators="@" commit --trailer="Signed-off-by=C O <email>"
or
$ git -c trailer.separators="@" commit --trailer="Signed-off-by@C O <email>"
Both can work normally,
--trailer="Signed-off-by@ C O <email>"
will output in the commit message.
Quoted 3 lines
I don't know if that does the right thing in the presence of --if-exists=add.
Yesterday, Christian Couder and I had already discussed this issue:
Your idea is correct, I should not add "--if-exists = add", this will destroy the user's rights to configure by using git -c trailer.if-exist.
Quoted 11 lines
So it would be good to update these tests so you test:
* For the --if-exists=add case at all, there's no tests for it now. I.e. add some trailers manually to the commit (via -F or whatever) and then see if they get added to, replacet etc.
* Ditto but for the user having configured trailer.separators (see the
test_confighelper for how to set config in a test). I.e. if it's "=" does adding trailers work, how about if it's "=" on the CLI but the config/commit message has ";" instead of ":" or something?
As mentioned above, it works normally.
Quoted 8 lines
* Hrm, actually I think tweaking "-c trailer.ifexists" won't work at all, since the CLI switch would override it. I honestly don't know, but why not not supply it and keep the addIfDifferentNeighbor default?
If it's essential that seems like a good test / documentation addition...
Quoted 9 lines
* For the above -c ... case I can't think of a good way to deal with it that doesn't involve pulling in
git_trailer_config()intogit_commit_config(), but perhaps the least nasty way is to just set a flag ingit_commit_config()if we see a "trailer.ifexists" flag, and if so don't provide "--if-exists=add", if there's no config (this will include "git -c ... commit" we set provide "--if-exists=add" ) or as noted above, maybe we can skip the whole thing and use the addIfDifferentNeighbor default.
Has been restored to the default settings.
Quoted 8 lines
And, not needed for this patch but worth thinking about:
* We pass through --trailer to git-interpret-trailers, what should we do about the other options? Should git-commit eventually support --trailer-where and pass it along as --where to git-interpret-trailers, or is "git -c trailer.where=... commit" good enough?
Logically speaking, interpret_trailers should be dedicated to commit or other sub-commands that require trailers.
But I think that in the later stage, the parse_options of the cmd_commit can keep the unrecognized options, and then these choices can be directly passed to the interpret_trailers backend.
Quoted 4 lines
* It would be good to test for and document if that "-c trailer.*" trick works (no reason it shouldn't). I.e. to add something like this after what you have (along with tests, and check if it's even true):
I haven't tested them for the time being, but I will do it.
Quoted 7 lines
Only the
--trailerargument to linkgit:git-interpret-trailers[1] is supported. Other pass-through switches may be added in the future, but currently you'll need to pass arguments to linkgit:git-interpret-trailers[1] along as config, e.g.git -c trailer.where=start commit [...] --trailer=[...].
I think this is worth writing in the documentation.
Quoted 7 lines
* We have a longer-term goal of having the .mailmap apply to trailers, it would be nice if git-interpret-trailers had some fuzzy-matching to check if the RHS of a trailer is a name/E-Mail pair, and if so did stricter validation on it with the ident functions we use for fsck etc. (that's copied & subtly different in several different places in the codebase, unfortunately[1]).
I may not know much about fuzzy-matching, which may be worth studying later.
Quoted 8 lines
More thoughts:
* Having written all the above I checked how --signoff is implemented.
It seems to me to be a good idea to (at least for testing) convert the --signoff trailer to your implementation. We have plenty of tests for it, does migrating it over pass or fail those?
I don’t know how to migrating yet, it may take a long time. Even I think I can leave it as #leftoverbit later.
Quoted 17 lines
* I also agree with Junio that we shouldn't have a --fixed-by or whatever and wouldn't add --signoff today, but it seems very useful to me to have a shortcut like:
--trailer "Signed-off-by"
I.e. omitting the value, or:
--trailer "Signed-off-by="Or some other thing we deem sufficiently useful/sane syntax/unambiguous.n
Then the value would be provided by
fmt_name(WANT_COMMITTER_IDENT)just as we do inappend_signoff()now. I think a *very common* case for this would be something like:
Quoted 9 lines
git commit --amend -v --trailer "Reviewed-by"And it would be useful to help that along and not have to do:
git commit --amend -v --trailer "Reviewed-by=$(git config user.name) <$(git config user.email)>"Or worse yet, manually typo your name/e-mail address, as I'm sure I and many others will inevitably do when using this option...
I think this idea is very good and easy to implement.
We only need to do a simple string match when we get the "trailer" string, If it can be completed, it can indeed bring great convenience to users.
Quoted 1 line
Thanks, Ævar Arnfjörð Bjarmason!
--
ZheNing Hu
Re: [PATCH v8 1/2] [GSOC] commit: add --trailer option
Quoted 4 lines · ZheNing Hu
Quoted 3 lines · Ævar Arnfjörð Bjarmason <[email protected]> 于2021年3月16日周二 下午8:52写道:
Quoted 2 lines
builtin/commit.c +2
-0+if (run_command (&run_trailer)) +strvec_clear (&run_trailer.args);
Quoted 8 lines
Quoted 2 lines
This is git-commit, shouldn't we
die()here instead of ignoring errors in sub-processes?After thinking about it carefully, your opinion is more reasonable, because if the user uses the wrong
--trailerand does not get the information he needs, I think he will have to use--amendto modify, anddie()can exit this commit directly.
Yeah, we don't want to silently lose data.
Quoted 115 lines
Quoted 54 lines
builtin/commit.c int cmd_commit(int argc, const char **argv, const char *prefix) · line 1533
Quoted 13 lines
builtin/commit.c +4
-0+strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be @@ -1507,6 +1529,7 @@ 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_BOOL('s', "signoff", &signoff, N_("add a Signed-off-by trailer")),Not required for this change, but perhaps a change here to
N_()(if we can get it to fit) + doc update saying that we prefer --trailer="Signed-Off-By: to --signoff"? More on that later.Quoted 20 lines
builtin/commit.c +0
-0OPT_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 +10
-0@@ -154,6 +154,26 @@ test_expect_success 'sign off' ' ' +test_expect_success 'trailer' ' + >file1 && + git add file1 && + git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ + --trailer "Helped-by:C O Mitter2 <[email protected]>" \ + --trailer "Reported-by:C O Mitter3 <[email protected]>" \ + --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ + -m "hello" && + git cat-file commit HEAD >commit.msg && + sed -e "1,7d" commit.msg >actual &&t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 176
Quoted 10 lines
t/t7502-commit-porcelain.sh +10
-0+ cat >expected <<-\EOF && + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter1 <[email protected]> + Helped-by: C O Mitter2 <[email protected]> + Reported-by: C O Mitter3 <[email protected]> + Mentored-by: C O Mitter4 <[email protected]> + EOF + test_cmp expected actual +' +How does this interact with cases where the user has configured "trailer.separators" to have a value that doesn't contain ":"? I haven't tested, but my reading of git-interpret-trailers(1) is that if you supplied "=" instead that case would just work:
Quoted 4 lines
By default only : is recognized as a trailer separator, except that = is always accepted on the command line for compatibility with other git commands.
But
interpret_trailersinterface allow us use "=" instead of other separators.I did a simple test and modified the configuration "trailer.separators" and it still works. Now things are good here:
$ git -c trailer.separators="@" commit --trailer="Signed-off-by=C O <email>"or
$ git -c trailer.separators="@" commit --trailer="Signed-off-by@C O <email>"Both can work normally,
--trailer="Signed-off-by@ C O <email>"
will output in the commit message.
Quoted 3 lines
I don't know if that does the right thing in the presence of --if-exists=add.
Yesterday, Christian Couder and I had already discussed this issue:
Your idea is correct, I should not add "--if-exists = add", this will destroy the user's rights to configure by usinggit -c trailer.if-exist.Quoted 11 lines
So it would be good to update these tests so you test:
* For the --if-exists=add case at all, there's no tests for it now. I.e. add some trailers manually to the commit (via -F or whatever) and then see if they get added to, replacet etc.
* Ditto but for the user having configured trailer.separators (see the
test_confighelper for how to set config in a test). I.e. if it's "=" does adding trailers work, how about if it's "=" on the CLI but the config/commit message has ";" instead of ":" or something?As mentioned above, it works normally.
Quoted 8 lines
* Hrm, actually I think tweaking "-c trailer.ifexists" won't work at all, since the CLI switch would override it. I honestly don't know, but why not not supply it and keep the addIfDifferentNeighbor default?
If it's essential that seems like a good test / documentation addition...
Quoted 9 lines
* For the above -c ... case I can't think of a good way to deal with it that doesn't involve pulling in
git_trailer_config()intogit_commit_config(), but perhaps the least nasty way is to just set a flag ingit_commit_config()if we see a "trailer.ifexists" flag, and if so don't provide "--if-exists=add", if there's no config (this will include "git -c ... commit" we set provide "--if-exists=add" ) or as noted above, maybe we can skip the whole thing and use the addIfDifferentNeighbor default.
Quoted 1 line
Has been restored to the default settings.
To clarify: What I really mean is for all these things you've tested:
let's add those to the tests as part of the patch.
Quoted 8 lines
Quoted 8 lines
And, not needed for this patch but worth thinking about:
* We pass through --trailer to git-interpret-trailers, what should we do about the other options? Should git-commit eventually support --trailer-where and pass it along as --where to git-interpret-trailers, or is "git -c trailer.where=... commit" good enough?
Quoted 6 lines
Logically speaking,
interpret_trailersshould be dedicated tocommitor other sub-commands that require trailers.But I think that in the later stage, the
parse_optionsof thecmd_commitcan keep the unrecognized options, and then these choices can be directly passed to theinterpret_trailersbackend.
We have this interaction with e.g. range-diff and "log", it's often surprising. You add an option to one command and it appears in the other.
Quoted 29 lines
Quoted 4 lines
* It would be good to test for and document if that "-c trailer.*" trick works (no reason it shouldn't). I.e. to add something like this after what you have (along with tests, and check if it's even true):
I haven't tested them for the time being, but I will do it.
Quoted 7 lines
Only the
--trailerargument to linkgit:git-interpret-trailers[1] is supported. Other pass-through switches may be added in the future, but currently you'll need to pass arguments to linkgit:git-interpret-trailers[1] along as config, e.g.git -c trailer.where=start commit [...] --trailer=[...].I think this is worth writing in the documentation.
Quoted 7 lines
* We have a longer-term goal of having the .mailmap apply to trailers, it would be nice if git-interpret-trailers had some fuzzy-matching to check if the RHS of a trailer is a name/E-Mail pair, and if so did stricter validation on it with the ident functions we use for fsck etc. (that's copied & subtly different in several different places in the codebase, unfortunately[1]).
I may not know much about fuzzy-matching, which may be worth studying later.
Quoted 2 lines
More thoughts:
Quoted 8 lines
Quoted 6 lines
* Having written all the above I checked how --signoff is implemented.
It seems to me to be a good idea to (at least for testing) convert the --signoff trailer to your implementation. We have plenty of tests for it, does migrating it over pass or fail those?
I don’t know how to migrating yet, it may take a long time. Even I think I can leave it as #leftoverbit later.
Sure, I mean (having looked at it) that at least for your own local testing it would make sense to change it (even if just search-replacing the --signoff in the test suite) to see if it behaves as you expect. I.e. does the --trailer behavior mirror --signoff?
Quoted 26 lines
Quoted 17 lines
* I also agree with Junio that we shouldn't have a --fixed-by or whatever and wouldn't add --signoff today, but it seems very useful to me to have a shortcut like:
--trailer "Signed-off-by"
I.e. omitting the value, or:
--trailer "Signed-off-by="Or some other thing we deem sufficiently useful/sane syntax/unambiguous.n
Then the value would be provided by
fmt_name(WANT_COMMITTER_IDENT)just as we do inappend_signoff()now. I think a *very common* case for this would be something like:Quoted 9 lines
git commit --amend -v --trailer "Reviewed-by"And it would be useful to help that along and not have to do:
git commit --amend -v --trailer "Reviewed-by=$(git config user.name) <$(git config user.email)>"Or worse yet, manually typo your name/e-mail address, as I'm sure I and many others will inevitably do when using this option...
Quoted 7 lines
I think this idea is very good and easy to implement.
We only need to do a simple string match when we get the "trailer" string, If it can be completed, it can indeed bring great convenience to users.Quoted 1 line
Thanks, Ævar Arnfjörð Bjarmason!
And thanks for working on this.
Re: [PATCH v8 1/2] [GSOC] commit: add --trailer option
Quoted 11 lines · Ævar Arnfjörð Bjarmason <[email protected]> 于2021年3月17日周三 下午4:08写道:
Quoted 6 lines
Logically speaking,
interpret_trailersshould be dedicated tocommitor other sub-commands that require trailers.But I think that in the later stage, the
parse_optionsof thecmd_commitcan keep the unrecognized options, and then these choices can be directly passed to theinterpret_trailersbackend.We have this interaction with e.g. range-diff and "log", it's often surprising. You add an option to one command and it appears in the other.
All right, I'm wrong, I may have reference to an wrong experience of difftool-->diff.
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
It seems to me to be a good idea to (at least for testing) convert the --signoff trailer to your implementation. We have plenty of tests for it, does migrating it over pass or fail those?
Quoted 34 lines
Quoted 2 lines
I don’t know how to migrating yet, it may take a long time. Even I think I can leave it as #leftoverbit later.
Sure, I mean (having looked at it) that at least for your own local testing it would make sense to change it (even if just search-replacing the --signoff in the test suite) to see if it behaves as you expect. I.e. does the --trailer behavior mirror --signoff?
Quoted 26 lines
Quoted 26 lines
* I also agree with Junio that we shouldn't have a --fixed-by or whatever and wouldn't add --signoff today, but it seems very useful to me to have a shortcut like:
--trailer "Signed-off-by"
I.e. omitting the value, or:
--trailer "Signed-off-by="Or some other thing we deem sufficiently useful/sane syntax/unambiguous.n
Then the value would be provided by
fmt_name(WANT_COMMITTER_IDENT)just as we do inappend_signoff()now. I think a *very common* case for this would be something like:git commit --amend -v --trailer "Reviewed-by"And it would be useful to help that along and not have to do:
git commit --amend -v --trailer "Reviewed-by=$(git config user.name) <$(git config user.email)>"Or worse yet, manually typo your name/e-mail address, as I'm sure I and many others will inevitably do when using this option...
Well, that's what I think here:
Now we can go through:
$ git -c trailer.signoff.key = "Signed-off-by" commit --trailer "signoff = commiter <email>"
to get a trailer: "Signed-off-by: commiter <email>", this means we can't just do simple string
matching in cmd_commit to replace --trailer="Signed-off-by" or --trailer="Reviewed-by" to
user's own identity, to replace the trailers which have omitting value
we passed in, but I think
we can provide a new option to commit which can mandatory that trailers with no value can be
replaced with the identity of the user.
e.g.
$ git -c trailer.signoff.key = "Signed-off-by" commit --trailer "signoff" --trailer "Helped-by" \ --trailer "Helped-by = C <E>" --own_ident
will output like this:
Signed-off-by: $(git config user.name) <$(git config user.email)>
Signed-off-by: $(git config user.name) <$(git config user.email)>
Helped-by: $(git config user.name) <$(git config user.email)>
Helped-by: C <E>
I don't know if this idea is good, I will try to do it first.
Thanks.
PATCH v8 2/2 interpret_trailers: for three options parse add warning
In reply to ZheNing Hu via GitGitGadgetFrom: ZheNing Hu <[email protected]>
When using interpret-trailers, if user accidentally fill in the wrong option values (e.g. --if-exists=addd or --where=begin or --if-missing=do-nothing), git will exit quietly, and the user may not even know what happened.
So lets provides warnings when git parsing this three options:
"unknown value '%s' for key ('where'|'--if-exist'|'--if-missing')". This will remind the user :"Oh, it was because of my spelling error." (or using a synonym for error).
--- builtin/interpret-trailers.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-)
builtin/interpret-trailers.c +22 -3
@@ -24,19 +24,38 @@ static enum trailer_if_missing if_missing;static int option_parse_where (const struct option *opt,const char *arg,int unset) { -return trailer_set_where (&where, arg); +int ret; + + ret =trailer_set_where (&where, arg); +if (ret) +warning (_ ("unknown value '%s' for key 'where'" ), + arg); +return ret; + }static int option_parse_if_exists (const struct option *opt,const char *arg,int unset) { -return trailer_set_if_exists (&if_exists, arg); +int ret; + + ret =trailer_set_if_exists (&if_exists, arg); +if (ret) +warning (_ ("unknown value '%s' for key 'if_exists'" ), + arg); +return ret; }static int option_parse_if_missing (const struct option *opt,const char *arg,int unset) { -return trailer_set_if_missing (&if_missing, arg); +int ret; + + ret =trailer_set_if_missing (&if_missing, arg); +if (ret) +warning (_ ("unknown value '%s' for key 'if_missing'" ), + arg); +return ret; }static void new_trailers_clear (struct list_head *trailers)
Signature · 1 line
gitgitgadget
Re: [PATCH v8 2/2] interpret_trailers: for three options parse add warning
Quoted 8 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
When using
interpret-trailers, if user accidentally fill in the wrong option values (e.g.--if-exists=adddor--where=beginor--if-missing=do-nothing), git will exit quietly, and the user may not even know what happened.
Quoted 4 lines
So lets provides warnings when git parsing this three options:
"unknown value '%s' for key ('where'|'--if-exist'|'--if-missing')". This will remind the user :"Oh, it was because of my spelling error." (or using a synonym for error).
I am not against this, but I just want to say that when I previously worked on interpret-trailers I think I implemented or suggested such warnings, but they were rejected.
I think the reason they were rejected was to improve compatibility with future versions of Git where more options would be implemented.
For example if in a few years someone implements --where=middle and some people use it in a script like this:
git interpret-trailers --where=middle --trailer foo=bar
Then when such a script would be used with a recent version of Git it would work well, while if it would be used with an old version of Git it would emit warnings. And these warnings might actually be more annoying than the fact that the trailer is not put in the middle.
I might be wrong and there might have been other reasons though. Also things might have changed since that time, as not many options if any have been added since then.
Re: [PATCH v8 2/2] interpret_trailers: for three options parse add warning
Quoted 10 lines · Christian Couder <[email protected]> 于2021年3月16日周二 下午1:53写道:
I am not against this, but I just want to say that when I previously worked on
interpret-trailersI think I implemented or suggested such warnings, but they were rejected.I think the reason they were rejected was to improve compatibility with future versions of Git where more options would be implemented.
For example if in a few years someone implements
--where=middleand some people use it in a script like this:
Quoted 7 lines
git interpret-trailers --where=middle --trailer foo=bar
Then when such a script would be used with a recent version of Git it would work well, while if it would be used with an old version of Git it would emit warnings. And these warnings might actually be more annoying than the fact that the trailer is not put in the middle.
Well, this is indeed a situation I did not foresee. As a user, I don't see an error | warning reminder which may make me a little confused.
At the same time, some sub-command like git cat-file, If user give a wrong format:
$ git cat-file --batch-check="%(deltabases)"
git will tell us, "fatal: unknown format element: deltabases". It's easy for user to check.
Quoted 3 lines
I might be wrong and there might have been other reasons though. Also things might have changed since that time, as not many options if any have been added since then.
Thanks for your patiently explanation.
If these warnings are really unnecessary, I will drop this patch.
PATCH v9 1/1 commit: add --trailer option
In reply to ZheNing Hu via GitGitGadgetFrom: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new --trailer <token>[(=|:)<value>] option to pass other trailers to interpret-trailers and insert them into commit messages.
---
[GSOC] commit: add --trailer option
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.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v9
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v9
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Range-diff vs v8:
1: f81b6e66a6ba ! 1: e524c4ba5dc1 [GSOC] commit: add --trailer option
@@ builtin/commit.c: static int prepare_to_commit(const char *index_file, const cha
+ struct child_process run_trailer = CHILD_PROCESS_INIT;
+
+ strvec_pushl(&run_trailer.args, "interpret-trailers",
-+ "--in-place", "--if-exists=add",
-+ git_path_commit_editmsg(), NULL);
++ "--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)) 2: 68e0bd9e2d6f < -: ------------ interpret_trailers: for three options parse add warning
Documentation/git-commit.txt | 9 ++++++++- builtin/commit.c | 22 ++++++++++++++++++++++ t/t7502-commit-porcelain.sh | 20 ++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-)
Documentation/git-commit.txt +8 -1
@@ -14,7 +14,7 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...] DESCRIPTION -----------
@@ -166,6 +166,13 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off-by" trailer + and the "Helped-by" trailer in the commit message.) + See linkgit:git-interpret-trailers[1] for details. -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.
builtin/commit.c +22 -0
@@ -113,6 +113,7 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct strvec trailer_args =STRVEC_INIT ;/* * The default commit message cleanup mode will remove the lines
@@ -131,6 +132,14 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +BUG_ON_OPT_NEG (unset); + +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
@@ -958,6 +967,18 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +if (trailer_args.nr) { +struct child_process run_trailer =CHILD_PROCESS_INIT ; + +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--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); +strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be
@@ -1507,6 +1528,7 @@ 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_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 +20 -0
@@ -154,6 +154,26 @@ test_expect_success 'sign off' ' ' +test_expect_success 'trailer' ' + >file1 && + git add file1 && + git commit -s --trailer "Signed-off-by:C O Mitter1 <[email protected]>" \ + --trailer "Helped-by:C O Mitter2 <[email protected]>" \ + --trailer "Reported-by:C O Mitter3 <[email protected]>" \ + --trailer "Mentored-by:C O Mitter4 <[email protected]>" \ + -m "hello" && + git cat-file commit HEAD >commit.msg && + sed -e "1,7d" commit.msg >actual && + cat >expected <<-\EOF && + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter1 <[email protected]> + Helped-by: C O Mitter2 <[email protected]> + Reported-by: C O Mitter3 <[email protected]> + Mentored-by: C O Mitter4 <[email protected]> + EOF + test_cmp expected actual +' + test_expect_success 'multiple -m' ' >negative &&
base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945
Signature · 1 line
gitgitgadget
Re: [PATCH v9] [GSOC] commit: add --trailer option
On 16/03 10:39, ZheNing Hu via GitGitGadget wrote:
Hey ZheNing!
Quoted 7 lines
From: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Quoted 5 lines
Now implement a new
--trailer <token>[(=|:)<value>]option to pass other trailers tointerpret-trailersand insert them into commit messages.Signed-off-by ZheNing Hu <[email protected]>
I have been away for a while and directly seeing a V9 of this patch feels great! Its good that you have worked upon the patch. The above approach seems good to me!
builtin/commit.c int cmd_commit(int argc, const char **argv, const char *prefix) · line 1531
Quoted 8 lines
builtin/commit.c +1
-0/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be @@ -1507,6 +1528,7 @@ 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),
I feel that a better option description could be offered? Maybe something like: 'add custom trailer(s)'.
builtin/commit.c int cmd_commit(int argc, const char **argv, const char *prefix) · line 1534
Quoted 3 lines
builtin/commit.c +0
-0OPT_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")),
I have not yet gone through the the V2-V8s but I have a comment not associated with the contents of the patch. I feel that you should wait a little before posting a new version of the patch. I see that V4-V8 are put up in almost 3 hour gaps. This isn't technically wrong or prohibited by the communication rules of the List but I feel that posting a patch in such short intervals makes it hard to review and unnecessarily increases the versions of the patch. The reviewer lags behind the patch series in fact.
What you could do instead is post one patch per day instead of 3-4 in one single day so that your patches get thorough reviews. This way, you won't create 3-4 new versions of the patch containing not-so-many significant changes. You get me?
Also, in your reply on the V1 here:
https://lore.kernel.org/git/CAOLTT8SpAOj51jqYUYqYwXaVKSn1fANvetauaG0z4etiBMzVEw@mail.gmail.com/
I read:
Quoted 2 lines
It's exactly what you said.
My lack of English sometimes limits my expression.
It is okay please do not worry. Neither do we have English as our first language nor have we ever communicated this much with an English speaking audience online. I struggled initially too especially with many American terms used here. You will get the hang of it soon.
Keep contributing!
Regards,
Shourya Shukla
Re: [PATCH v9] [GSOC] commit: add --trailer option
Quoted 10 lines · Shourya Shukla <[email protected]> 于2021年3月17日周三 下午1:26写道:
On 16/03 10:39, ZheNing Hu via GitGitGadget wrote:
Hey ZheNing!
I have been away for a while and directly seeing a V9 of this patch feels great! Its good that you have worked upon the patch. The above approach seems good to me!
Hi! :-)
Quoted 12 lines
builtin/commit.c int cmd_commit(int argc, const char **argv, const char *prefix) · line 1531
Quoted 8 lines
/*
* Reject an attempt to record a non-merge empty commit without
* explicit --allow-empty. In the cherry-pick case, it may bebuiltin/commit.c +1
-0@@ -1507,6 +1528,7 @@ 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),I feel that a better option description could be offered? Maybe something like: 'add custom trailer(s)'.
Feel ok.
Quoted 14 lines
builtin/commit.c int cmd_commit(int argc, const char **argv, const char *prefix) · line 1534
Quoted 4 lines
builtin/commit.c +0
-0OPT_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")),I have not yet gone through the the V2-V8s but I have a comment not associated with the contents of the patch. I feel that you should wait a little before posting a new version of the patch. I see that V4-V8 are put up in almost 3 hour gaps. This isn't technically wrong or prohibited by the communication rules of the List but I feel that posting a patch in such short intervals makes it hard to review and unnecessarily increases the versions of the patch. The reviewer lags behind the patch series in fact.
Quoted 5 lines
What you could do instead is post one patch per day instead of 3-4 in one single day so that your patches get thorough reviews. This way, you won't create 3-4 new versions of the patch containing not-so-many significant changes. You get me?
Get it. Especially seeing Ævar Arnfjörð Bjarmason give me comments behind the new iterations I posted, I knew that I might be sending new versions too frequently.
Quoted 8 lines
Also, in your reply on the V1 here:
https://lore.kernel.org/git/CAOLTT8SpAOj51jqYUYqYwXaVKSn1fANvetauaG0z4etiBMzVEw@mail.gmail.com/I read:
Quoted 2 lines
It's exactly what you said.
My lack of English sometimes limits my expression.
Quoted 7 lines
It is okay please do not worry. Neither do we have English as our first language nor have we ever communicated this much with an English speaking audience online. I struggled initially too especially with many American terms used here. You will get the hang of it soon.
Keep contributing!
Thank you for your encouragement. Many people come to discuss and share some ideas in English with me every day. It is a cool thing in itself.
Quoted 3 lines
Regards,
Shourya Shukla
Regards,
ZheNing Hu
v10 cover commit: add --trailer option
In reply to ZheNing Hu via GitGitGadgetNow 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`, `
+ <[email protected]>" --trailer "Helped-by:C O Mitter \
+ <[email protected]>"` 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 <[email protected]>" \
-+ --trailer "Helped-by:C O Mitter2 <[email protected]>" \
-+ --trailer "Reported-by:C O Mitter3 <[email protected]>" \
-+ --trailer "Mentored-by:C O Mitter4 <[email protected]>" \
++test_expect_success 'commit --trailer without -c' '
++ echo "fun" >>file &&
++ git add file &&
++ cat >expected <<-\EOF &&
++
++ Signed-off-by: C O Mitter <[email protected]>
++ 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 <[email protected]>
++ 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 <[email protected]>
++ 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 <[email protected]>
-+ Signed-off-by: C O Mitter1 <[email protected]>
-+ Helped-by: C O Mitter2 <[email protected]>
-+ Reported-by: C O Mitter3 <[email protected]>
-+ Mentored-by: C O Mitter4 <[email protected]>
++ 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 <[email protected]>
++ 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 <[email protected]>
++ 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 <[email protected]>
++ 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 <[email protected]>
++ 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 <[email protected]>
++ 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 <[email protected]>
++ 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 <[email protected]>
++ 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 <[email protected]>
++ 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 optionSignature · 1 line
gitgitgadget
PATCH v10 1/3 commit: add --trailer option
From: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new --trailer <token>[(=|:)<value>] option to pass other trailers to interpret-trailers and insert them into commit messages.
--- Documentation/git-commit.txt | 10 +- builtin/commit.c | 23 +++ t/t7502-commit-porcelain.sh | 336 +++++++++++++++++++++++++++++++++++ 3 files changed, 368 insertions(+), 1 deletion(-)
Documentation/git-commit.txt +9 -1
@@ -14,7 +14,7 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...] DESCRIPTION -----------
@@ -166,6 +166,14 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off-by" trailer + and the "Helped-by" trailer in the commit message.) + 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 +23 -0
@@ -113,6 +113,7 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct strvec trailer_args =STRVEC_INIT ;/* * The default commit message cleanup mode will remove the lines
@@ -131,6 +132,14 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +BUG_ON_OPT_NEG (unset); + +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
@@ -958,6 +967,19 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +if (trailer_args.nr) { +struct child_process run_trailer =CHILD_PROCESS_INIT ; + +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--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)) { +die (_ ("unable to pass tailers to --trailers" )); + } +strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be
@@ -1507,6 +1529,7 @@ 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_ ("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 +336 -0
342 lines not on this page · raw message
Signature · 1 line
gitgitgadget
Re: [PATCH v10 1/3] [GSOC] commit: add --trailer option
Quoted 23 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new
--trailer <token>[(=|:)<value>]option to pass other trailers tointerpret-trailersand insert them into commit messages.Signed-off-by ZheNing Hu <[email protected]>--- Documentation/git-commit.txt | 10 +- builtin/commit.c | 23 +++ t/t7502-commit-porcelain.sh | 336 +++++++++++++++++++++++++++++++++++ 3 files changed, 368 insertions(+), 1 deletion(-)Documentation/git-commit.txt +0
-0
Documentation/git-commit.txt SYNOPSIS · line 17
Quoted 5 lines
Documentation/git-commit.txt +1
-1@@ -14,7 +14,7 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...]
Please move all options before non-option arguments. In other words, please move --trailer before [--].
This form implies that there are no way to specify pathspec "--trailer"
Quoted 48 lines
Documentation/git-commit.txt +8
-0DESCRIPTION -----------@@ -166,6 +166,14 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off-by" trailer + and the "Helped-by" trailer in the commit message.) + 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 +9
-0@@ -113,6 +113,7 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct strvec trailer_args =STRVEC_INIT ;/* * The default commit message cleanup mode will remove the lines @@ -131,6 +132,14 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +BUG_ON_OPT_NEG (unset); + +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;@@ -958,6 +967,19 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp);
builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 978
Quoted 10 lines
builtin/commit.c +9
-0+if (trailer_args.nr) { +struct child_process run_trailer =CHILD_PROCESS_INIT ; + +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--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)) { +die (_ ("unable to pass tailers to --trailers" ));
s/tailers/trailers/ perhap?
Also we usually not put {} around single statement.
Quoted 29 lines
builtin/commit.c +5
-0+ } +strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be @@ -1507,6 +1529,7 @@ 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_ ("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 +6
-0@@ -154,6 +154,342 @@ test_expect_success 'sign off' ' ' +test_expect_success 'commit --trailer without -c' ' + echo "fun" >>file && + git add file && + cat >expected <<-\EOF && + + Signed-off-by: C O Mitter <[email protected]>
t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 172
Quoted 10 lines
t/t7502-commit-porcelain.sh +10
-0+ 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" &&
It's documented that we're supporting --trailer <token>[(=|:)<value>] However, only --trailer <token>:<value> is tested.
I think it's better to have
--trailer "Helped-by=C2 E2" --trailer "Reported-by"
Signature · 1 line
Danh
Re: [PATCH v10 1/3] [GSOC] commit: add --trailer option
Quoted 34 lines · Đoàn Trần Công Danh <[email protected]> 于2021年3月19日周五 上午12:29写道:
Quoted 23 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new
--trailer <token>[(=|:)<value>]option to pass other trailers tointerpret-trailersand insert them into commit messages.Signed-off-by ZheNing Hu <[email protected]>--- Documentation/git-commit.txt | 10 +- builtin/commit.c | 23 +++ t/t7502-commit-porcelain.sh | 336 +++++++++++++++++++++++++++++++++++ 3 files changed, 368 insertions(+), 1 deletion(-)Documentation/git-commit.txt +0
-0Documentation/git-commit.txt SYNOPSIS · line 17
Quoted 5 lines
Documentation/git-commit.txt +1
-1@@ -14,7 +14,7 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...]Please move all options before non-option arguments. In other words, please move --trailer before [--].
Quoted 1 line
This form implies that there are no way to specify pathspec "--trailer"
Thanks, I didn't pay attention to this little detail before.
Quoted 50 lines
Quoted 50 lines
Documentation/git-commit.txt +8
-0DESCRIPTION -----------@@ -166,6 +166,14 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off-by" trailer + and the "Helped-by" trailer in the commit message.) + 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 +9
-0@@ -113,6 +113,7 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct strvec trailer_args =STRVEC_INIT ;/* * The default commit message cleanup mode will remove the lines @@ -131,6 +132,14 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +BUG_ON_OPT_NEG (unset); + +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;@@ -958,6 +967,19 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp);
Quoted 13 lines
builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 978
Quoted 9 lines
builtin/commit.c +9
-0+if (trailer_args.nr) { +struct child_process run_trailer =CHILD_PROCESS_INIT ; + +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--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)) { +die (_ ("unable to pass tailers to --trailers" ));s/tailers/trailers/ perhap?
Also we usually not put {} around single statement.
OK.
Quoted 44 lines
Quoted 29 lines
builtin/commit.c +5
-0+ } +strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be @@ -1507,6 +1529,7 @@ 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_ ("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 +6
-0@@ -154,6 +154,342 @@ test_expect_success 'sign off' ' ' +test_expect_success 'commit --trailer without -c' ' + echo "fun" >>file && + git add file && + cat >expected <<-\EOF && + + Signed-off-by: C O Mitter <[email protected]>t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 172
Quoted 10 lines
t/t7502-commit-porcelain.sh +10
-0+ 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" &&It's documented that we're supporting --trailer <token>[(=|:)<value>] However, only --trailer <token>:<value> is tested.
I think it's better to have
Quoted 2 lines
--trailer "Helped-by=C2 E2" --trailer "Reported-by"
In fact, I want to test in test_expect_success'commit --trailer with -c and "=" as separators',
but some changes are needed.
Quoted 3 lines
--
Danh
Signature · 1 line
ZheNing Hu
PATCH v10 2/3 interpret-trailers: add own-identity option
In reply to ZheNing Hu via GitGitGadgetFrom: ZheNing Hu <[email protected]>
Beacuse `git commit --trailer="Signed-off-by: \
$(git config user.name) <$(git config user.email)>" is difficult for users to add their own identities, so teach interpret-trailers a new option --own-identity which allow those trailers with no value add the user’s own identity. This will help the use of commit --trailer as easy as --signoff`.
--- Documentation/git-interpret-trailers.txt | 14 ++++++++++++++ builtin/interpret-trailers.c | 6 ++++-- t/t7513-interpret-trailers.sh | 12 ++++++++++++ trailer.c | 18 ++++++++++++++++-- trailer.h | 3 ++- 5 files changed, 48 insertions(+), 5 deletions(-)
Documentation/git-interpret-trailers.txt +14 -0
@@ -84,6 +84,19 @@ OPTIONS trailer to the input messages. See the description of this command. +--own-identity:: + Used with `--trailer`. Those trailers without value with the + `--own-identity` option all will add the user's own identity. + For example,` git interpret-trailers --trailer "A:B" --trailer \ + "Signed-off-by" --trailer "Helped-by" --own-identity --inplace a.txt` + will output: + " + A:B + Signed-off-by: C O Mitter <[email protected]> + Helped-by: C O Mitter <[email protected]> + " + in `a.txt`. + --where <placement>:: --no-where:: Specify where all new trailers will be added. A setting
@@ -131,6 +144,7 @@ OPTIONS when you know your input contains just the commit message itself (and not an email or the output of `git format-patch`). + CONFIGURATION VARIABLES -----------------------
builtin/interpret-trailers.c +4 -2
@@ -47,6 +47,7 @@ static void new_trailers_clear(struct list_head *trailers)list_for_each_safe (pos, tmp, trailers) { item = list_entry(pos, struct new_trailer_item, list);list_del (pos); +free (item->text);free (item); } }
@@ -66,7 +67,7 @@ static int option_parse_trailer(const struct option *opt,return -1 ; item =xmalloc (sizeof (*item)); - item->text = arg; + item->text =xstrdup (arg); item->where = where; item->if_exists = if_exists; item->if_missing = if_missing;
@@ -94,7 +95,8 @@ int cmd_interpret_trailers(int argc, const char **argv, const char *prefix)struct option options[] = {OPT_BOOL (0 ,"in-place" , &opts.in_place,N_ ("edit files in place" )),OPT_BOOL (0 ,"trim-empty" , &opts.trim_empty,N_ ("trim empty trailers" )), - +OPT_BOOL (0 ,"own-identity" , &opts.own_identity, +N_ ("specify the user's own identity for omitted trailers value" )),OPT_CALLBACK (0 ,"where" ,NULL ,N_ ("action" ),N_ ("where to place the new trailer" ), option_parse_where), OPT_CALLBACK(0, "if-exists", NULL, N_("action"),
t/t7513-interpret-trailers.sh +12 -0
@@ -63,6 +63,18 @@ test_expect_success 'without config' ' test_cmp expected actual ' +test_expect_success 'without config with --own-identity' ' + cat >expected <<-\EOF && + + Acked-by: A B <C> + Helped-by: C O Mitter <[email protected]> + Signed-off-by: C O Mitter <[email protected]> + EOF + git interpret-trailers --trailer "Acked-by: A B <C>" --trailer "Helped-by" \ + --trailer "Signed-off-by" --own-identity empty >actual && + test_cmp expected actual +' + test_expect_success 'without config in another order' ' sed -e "s/ Z\$/ /" >expected <<-\EOF &&
trailer.c +16 -2
@@ -690,8 +690,18 @@ static void add_arg_item(struct list_head *arg_head, char *tok, char *val,list_add_tail (&new_item->list, arg_head); } +static void add_user_own_identity (struct new_trailer_item *item) +{ +struct strbuf buf =STRBUF_INIT ; +strbuf_addstr (&buf, item->text); +strbuf_add (&buf,"=" ,1 ); +strbuf_addstr (&buf,fmt_name (WANT_COMMITTER_IDENT )); +free (item->text); + item->text = buf.buf; +} +static void process_command_line_args (struct list_head *arg_head, -struct list_head *new_trailer_head) +struct list_head *new_trailer_head,int own_identity) {struct arg_item *item;struct strbuf tok =STRBUF_INIT ;
@@ -728,6 +738,10 @@ static void process_command_line_args(struct list_head *arg_head,error (_ ("empty trailer token in trailer '%.*s'" ), (int ) sb.len, sb.buf);strbuf_release (&sb); + }else if (separator_pos ==-1 && own_identity) { +add_user_own_identity (tr); + pos = pos->prev; +continue ; }else {parse_trailer (&tok, &val, &conf, tr->text, separator_pos);
@@ -1048,7 +1062,7 @@ void process_trailers(const char *file,if (!opts->only_input) {LIST_HEAD (arg_head); -process_command_line_args (&arg_head, new_trailer_head); +process_command_line_args (&arg_head, new_trailer_head ,opts->own_identity);process_trailers_lists (&head, &arg_head); }
trailer.h +2 -1
@@ -57,7 +57,7 @@ struct trailer_info {struct new_trailer_item {struct list_head list; -const char *text; +char *text;enum trailer_where where;enum trailer_if_exists if_exists;
@@ -73,6 +73,7 @@ struct process_trailer_options {int no_divider;int key_only;int value_only; +int own_identity;const struct strbuf *separator;const struct strbuf *key_value_separator;int (*filter)(const struct strbuf *,void *);
Signature · 1 line
gitgitgadget
Re: [PATCH v10 2/3] interpret-trailers: add own-identity option
Quoted 3 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Beacuse `git commit --trailer="Signed-off-by: \
s/Beacuse/Because/
And I think, it's easier to read if we write the command in its own (indented) line.
Quoted 6 lines
$(git config user.name) <$(git config user.email)>"
is difficult for users to add their own identities, so teach interpret-trailers a new option--own-identitywhich allow those trailers with no value add the user’s own identity. This will help the use ofcommit --traileras easy as--signoff`.
Perhap, saying that we're optionalise <value> in --trailer, by substitute user's identity if missing instead?
Documentation/git-interpret-trailers.txt OPTIONS · line 147
Quoted 5 lines
Documentation/git-interpret-trailers.txt +1
-0@@ -131,6 +144,7 @@ OPTIONS when you know your input contains just the commit message itself (and not an email or the output of `git format-patch`). +
I think it's better to not add this line change
Quoted 7 lines
Documentation/git-interpret-trailers.txt +0
-0CONFIGURATION VARIABLES -----------------------builtin/interpret-trailers.c +0
-0
Signature · 1 line
Danh
Re: [PATCH v10 2/3] interpret-trailers: add own-identity option
Quoted 18 lines · Đoàn Trần Công Danh <[email protected]> 于2021年3月19日周五 上午12:45写道:
Quoted 3 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Beacuse `git commit --trailer="Signed-off-by: \
s/Beacuse/Because/
And I think, it's easier to read if we write the command in its own (indented) line.
Quoted 6 lines
$(git config user.name) <$(git config user.email)>"
is difficult for users to add their own identities, so teach interpret-trailers a new option--own-identitywhich allow those trailers with no value add the user’s own identity. This will help the use ofcommit --traileras easy as--signoff`.
Quoted 2 lines
Perhap, saying that we're optionalise <value> in --trailer, by substitute user's identity if missing instead?
Indeed so.
Quoted 9 lines
Documentation/git-interpret-trailers.txt OPTIONS · line 147
Quoted 6 lines
Documentation/git-interpret-trailers.txt +1
-0@@ -131,6 +144,7 @@ OPTIONS when you know your input contains just the commit message itself (and not an email or the output of `git format-patch`). +I think it's better to not add this line change
Quoted 8 lines
builtin/interpret-trailers.c
Quoted 7 lines
Documentation/git-interpret-trailers.txt +0
-0CONFIGURATION VARIABLES -----------------------builtin/interpret-trailers.c +0
-0
Thanks for these kindful advices.
Quoted 2 lines
--
Danh
--
ZheNing Hu
Re: [PATCH v10 2/3] interpret-trailers: add own-identity option
In reply to ZheNing Hu via GitGitGadgetQuoted 9 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Beacuse `git commit --trailer="Signed-off-by: \
$(git config user.name) <$(git config user.email)>"is difficult for users to add their own identities, so teach interpret-trailers a new option--own-identitywhich allow those trailers with no value add the user’s own identity. This will help the use ofcommit --traileras easy as--signoff`.
I have a suspicion that this is too narrowly focused to be useful in practice, and I find that the proposed "--own-identity" is quite a mouthful.
Documentation/git-interpret-trailers.txt OPTIONS · line 89
Quoted 3 lines
+--own-identity::
Documentation/git-interpret-trailers.txt +2
-0+ Used with `--trailer`. Those trailers without value with the + `--own-identity` option all will add the user's own identity.
So, the assumption here is that the name of the trailer tag alone, without the ':' separator, can identify which trailer the user is talking about, and it can be distinguished from the tag name plus ':' and nothing else which is calling for a trailer entry with an empty string as its value?
OK.
The reason why this looks too narrowly focused on oneself alone to be useful to me is because I often need to add various -by trailers to incoming patches, and have a script to do exactly that (which does not use interpret-trailers, as I do not think interpret-trailers can accept a patch email as its input, and the script predates interpret-trailers) but it will be useless if that script were limited to add -by for myself.
Wouldn't it be a lot more useful if
git commit --trailer="Helped-by:@Ch.*Couder"
is expanded (note: I am not married to the syntax, but only for illustration purposes, I am using "a value prefixed by @ triggers the 'name expansion'" convention in this example. People can come up with better convention) by finding an author or a committer whose name matches the given pattern from "git log"? Then, instead of
git commit --own-identity --trailer=Signed-off-by
I can say
git commit --trailer=Signed-off-by:@gitster
and I can even add more than one, e.g.
git commit --trailer=Helped-by:@peff --trailer=Signed-off-by:@gitster
Re: [PATCH v10 2/3] interpret-trailers: add own-identity option
Quoted 13 lines · Junio C Hamano <[email protected]> 于2021年3月19日周五 上午3:20写道:
Quoted 9 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Beacuse `git commit --trailer="Signed-off-by: \
$(git config user.name) <$(git config user.email)>"is difficult for users to add their own identities, so teach interpret-trailers a new option--own-identitywhich allow those trailers with no value add the user’s own identity. This will help the use ofcommit --traileras easy as--signoff`.
Quoted 4 lines
I have a suspicion that this is too narrowly focused to be useful in practice, and I find that the proposed "--own-identity" is quite a mouthful.
Well, the original meaning of this --trailerand--own-identity option is to imitate the behavior of --signoff to create other trailers, For the time being,
it can only "imitation", it does not yet support the ability to provide multiple identities instead of "own-identity".
If --own-identity is mouthful, is there a better name?
Quoted 10 lines
Documentation/git-interpret-trailers.txt OPTIONS · line 89
Quoted 3 lines
+--own-identity::
Documentation/git-interpret-trailers.txt +2
-0+ Used with `--trailer`. Those trailers without value with the + `--own-identity` option all will add the user's own identity.So, the assumption here is that the name of the trailer tag alone, without the ':' separator, can identify which trailer the user is talking about, and it can be distinguished from the tag name plus ':' and nothing else which is calling for a trailer entry with an empty string as its value?
Yes. --own-ident is for trailers without a separator.
Quoted 10 lines
OK.
The reason why this looks too narrowly focused on oneself alone to be useful to me is because I often need to add various -by trailers to incoming patches, and have a script to do exactly that (which does not use interpret-trailers, as I do not think interpret-trailers can accept a patch email as its input, and the script predates interpret-trailers) but it will be useless if that script were limited to add -by for myself.
I understand it. But I think --own-ident is more inclined to add identities for users. If users want to add other people’s identities, they need to use another method.
Quoted 12 lines
Wouldn't it be a lot more useful if
git commit --trailer="Helped-by:@Ch.*Couder"is expanded (note: I am not married to the syntax, but only for illustration purposes, I am using "a value prefixed by @ triggers the 'name expansion'" convention in this example. People can come up with better convention) by finding an author or a committer whose name matches the given pattern from "git log"? Then, instead of
git commit --own-identity --trailer=Signed-off-by
Quoted 8 lines
I can say
git commit --trailer=Signed-off-by:@gitsterand I can even add more than one, e.g.
git commit --trailer=Helped-by:@peff --trailer=Signed-off-by:@gitster
I agree that this idea can be extended again from "own-identity " mode to "multiple-identity mode",‘@’ seems to have a lot of
important meanings in git, but I don’t know how to design a solution that is more suitable than yours for the time being.
Another doubt is what happens if one person corresponds to multiple mailboxes or one mailbox corresponds to multiple people?
I think --own-ident may be a somewhat "narrow" option that can be kept. Also add a new option for interpret-trailers to resolve the identity of other people?
Thanks for suggestions.
Re: [PATCH v10 2/3] interpret-trailers: add own-identity option
Quoted 1 line · ZheNing Hu
If
--own-identityis mouthful, is there a better name?
I originally had "perhaps XXXX?" in the message you are responding to, but I hoped that the message, especially the examples at the end, would be sufficient to make you realize that the option itself is not such a great idea (an additional ":@gitster" in whatever syntax used would be even shorter than "--own-identity", and obviously more flexible in that it can name other people).
If you really want to have this option, perhaps call it "--self"? I still do not think it is a good idea, though.
Re: [PATCH v10 2/3] interpret-trailers: add own-identity option
Quoted 12 lines · Junio C Hamano <[email protected]> 于2021年3月19日周五 下午11:36写道:
Quoted 1 line · ZheNing Hu
If
--own-identityis mouthful, is there a better name?I originally had "perhaps XXXX?" in the message you are responding to, but I hoped that the message, especially the examples at the end, would be sufficient to make you realize that the option itself is not such a great idea (an additional ":@gitster" in whatever syntax used would be even shorter than "--own-identity", and obviously more flexible in that it can name other people).
Quoted 2 lines
If you really want to have this option, perhaps call it "--self"? I still do not think it is a good idea, though.
Fine, If this option is really not particularly useful, I am willing to give it up.
I am looking for how to extract each author or committer from the log. I just know I can use:
$ git log --pretty="%an %ae" | sort | uniq
get all unique author <email> from a git repo.
Is there any function in the source code of git to get them?
I notice Ævar Arnfjörð Bjarmason mentioned .mailmap, I have seen the
.mailmap under git repo. Would it be better to extract the author
or committer
from the .mailmap than to extract it from git log?
If so, the operation of the trailer may depend on the contents of .mailmap. If there is no .mailmap in the user git repo, then the identity in the trailer cannot be parsed.
Thanks.
Re: [PATCH v10 2/3] interpret-trailers: add own-identity option
Quoted 7 lines · ZheNing Hu
I am looking for how to extract each author or committer from the log. I just know I can use:
$ git log --pretty="%an %ae" | sort | uniqget all unique author <email> from a git repo.
Is there any function in the source code of git to get them?
If I understand Junio's suggestion correctly, it is very similar to how "commit --author" works. See how it calls find_author_by_nickname(), which finds the first commit matching the name, and then pulls out the full name from format_commit_message().
-Peff
Re: [PATCH v10 2/3] interpret-trailers: add own-identity option
Quoted 4 lines · Jeff King
If I understand Junio's suggestion correctly, it is very similar to how "commit --author" works. See how it calls
find_author_by_nickname(), which finds the first commit matching the name, and then pulls out the full name fromformat_commit_message().
Yup.
But I have to warn readers that it would not be a sane approach to simply expose find_author_by_nickname() from builtin/commit.c as if it is a generally reusable helper function. In a very limited context of "git commit", what the helper does is OK to run a single revision traversal without cleaning the parsed commit objects and object flag bits after finding a single commit.
But generally, it would not be an approach that would scale (e.g. I do not know if we can expect to be able to call the helper function twice and get sensible results out of it).
Re: [PATCH v10 2/3] interpret-trailers: add own-identity option
Quoted 17 lines · Junio C Hamano <[email protected]> 于2021年3月20日周六 下午1:50写道:
Quoted 4 lines · Jeff King
If I understand Junio's suggestion correctly, it is very similar to how "commit --author" works. See how it calls
find_author_by_nickname(), which finds the first commit matching the name, and then pulls out the full name fromformat_commit_message().Yup.
But I have to warn readers that it would not be a sane approach to simply expose
find_author_by_nickname()frombuiltin/commit.cas if it is a generally reusable helper function. In a very limited context of "git commit", what the helper does is OK to run a single revision traversal without cleaning the parsed commit objects and object flag bits after finding a single commit.
Quoted 3 lines
But generally, it would not be an approach that would scale (e.g. I do not know if we can expect to be able to call the helper function twice and get sensible results out of it).
Hi, Jeff and Junio,
find_author_by_nickname is indeed a good way to find
the author <email> in the "last" commit that matches
the specified name, but after testing, find_author_by_nickname is as Junio say, it is not reusable(use it twice, git will call die), but why?
Re: [PATCH v10 2/3] interpret-trailers: add own-identity option
In actually ,
@@ -1071,6 +1071,7 @@ static const char *find_author_by_nickname(const char *name)
strbuf_release(&buf);
format_commit_message(commit, "%aN <%aE>", &buf, &ctx);
clear_mailmap(&mailmap);
+ reset_revision_walk();
return strbuf_detach(&buf, NULL);
}then we can reuse this function.
But I think I can give find_author_by_nickname another arg for choice if we want
reset_revision_walk().
Thanks, Junio and Jeff.
Re: [PATCH v10 2/3] interpret-trailers: add own-identity option
Quoted 11 lines · ZheNing Hu
In actually ,
(quoted diff) +1
-0@@ -1071,6 +1071,7 @@ static const char *find_author_by_nickname(const char *name) strbuf_release(&buf); format_commit_message(commit, "%aN <%aE>", &buf, &ctx); clear_mailmap(&mailmap); + reset_revision_walk(); return strbuf_detach(&buf, NULL); }
Quoted 4 lines
then we can reuse this function.
But I think I can give
find_author_by_nicknameanother arg for choice if we want
reset_revision_walk().
That is half fixing and half breaking. It would allow us to call the helper number of times as long as there is no other revision traversal is in progress; calling reset_revision_walk() would mean any and all revision traversal in progress will be broken. So we cannot use the helper to tweak each and every commit we encounter while running "git log", for example. Imagine adding an option to "git format-patch" to allow each commit it formats to be tweaked by adding "--trailers=foo:@ZheNing" and the like. There is one primary traversal that is used to list which commit to format in what order, and every time that primary traversal yields a commit, if we run find_author_by_nickname(), we end up initiating another traversal, and then by calling reset, we clear all object flags that are used for revision traversal, thereby breaking the primary traversal.
The only safe way to introduce a generally usable helper (without rewriting the revision traversal machinery) is to spawn a subprocess and do an equivalent of find_author_by_nickname() in it.
A standalone "interpret-trailers" command, as long as it won't do any other revision traversal, would not have such a problem, and calling reset every time find_author_by_nickname() is called may be sufficient. The only thing I care about is *not* to pretend that find_author_by_nickname() plus reset() is the generally reusable helper function and advertise it as such, which will mislead future developers into misusing the function in a context they shouldn't (i.e. while they are performing their own revision traversal).
Thanks.
Re: [PATCH v10 2/3] interpret-trailers: add own-identity option
Quoted 16 lines · Junio C Hamano <[email protected]> 于2021年3月20日周六 下午2:53写道:
Quoted 13 lines · ZheNing Hu
In actually ,
(quoted diff) +1
-0@@ -1071,6 +1071,7 @@ static const char *find_author_by_nickname(const char *name) strbuf_release(&buf); format_commit_message(commit, "%aN <%aE>", &buf, &ctx); clear_mailmap(&mailmap); + reset_revision_walk(); return strbuf_detach(&buf, NULL); }then we can reuse this function.
Quoted 17 lines
Quoted 2 lines
But I think I can give
find_author_by_nicknameanother arg for choice if we want
reset_revision_walk().That is half fixing and half breaking. It would allow us to call the helper number of times as long as there is no other revision traversal is in progress; calling
reset_revision_walk()would mean any and all revision traversal in progress will be broken. So we cannot use the helper to tweak each and every commit we encounter while running "git log", for example. Imagine adding an option to "git format-patch" to allow each commit it formats to be tweaked by adding "--trailers=foo:@ZheNing" and the like. There is one primary traversal that is used to list which commit to format in what order, and every time that primary traversal yields a commit, if we runfind_author_by_nickname(), we end up initiating another traversal, and then by calling reset, we clear all object flags that are used for revision traversal, thereby breaking the primary traversal.
I understand what you meaning. I may not be very thorough in considering
the potential problems. This is as dangerous as calling list_del in the middle of list_for_each.
Quoted 4 lines
The only safe way to introduce a generally usable helper (without rewriting the revision traversal machinery) is to spawn a subprocess and do an equivalent of
find_author_by_nickname()in it.
If I didn't notice what you mentioned later, I might think about it for a long time.
Execute a child process specifically to execute find_author_by_nickname(), which feels a bit wasteful.
Quoted 10 lines
A standalone "interpret-trailers" command, as long as it won't do any other revision traversal, would not have such a problem, and calling reset every time
find_author_by_nickname()is called may be sufficient. The only thing I care about is *not* to pretend thatfind_author_by_nickname()plusreset()is the generally reusable helper function and advertise it as such, which will mislead future developers into misusing the function in a context they shouldn't (i.e. while they are performing their own revision traversal).Thanks.
After listening to your previous explanation, I agree with this view. interpret-trailers alone as a process, as long as it does not traverse the revision externally, It is safe for us to call reset_revision_walk() after find_author_by_nickname() inside interpret-trailers.
Thank you for your thoughts and answers.
PATCH v10 3/3 commit: add own-identity option
In reply to ZheNing Hu via GitGitGadgetFrom: ZheNing Hu <[email protected]>
Use the newly added option --own-identity in interpret-trailers, implement new commit option --own-identity to allow those trailers with no value add the user’s own identity. Using the --own-identity option, users can directly use --trailer="Signed-off-by" to generate a signoff trailer with their own identities in commit messages,
The effect is basically the same as the --signoff option. However, users can add more useful options at the same time. e.g. --trailer="Helped-by" --own-identity can general Helped-by: C O Mitter <[email protected]>; Or through appropriate configuration:
`git -c trailer.signoff.key="Signed-off-by" commit --trailer="signoff" \
--own-identity` can also general their needs trailers with their favorite keys and their own identities.
--- Documentation/git-commit.txt | 15 +++++ builtin/commit.c | 8 +++ t/t7501-commit-basic-functionality.sh | 91 +++++++++++++++++++++++++++ t/t7502-commit-porcelain.sh | 20 ++++++ 4 files changed, 134 insertions(+)
Documentation/git-commit.txt +15 -0
@@ -174,6 +174,21 @@ include::signoff-option.txt[] and the "Helped-by" trailer in the commit message.) Use `git -c trailer.* commit --trailer` to make the appropriate configuration. See linkgit:git-interpret-trailers[1] for details. + +--own-identity:: + Used with `--trailer`. Those trailers without value with the + `--own-identity` option all will add the user's own identity. + For example, `git commit --trailer \ + "A:B" --trailer "Signed-off-by" --trailer "Helped-by" --own-identity`, + will output: + " + A:B + Signed-off-by: C O Mitter <[email protected]> + Helped-by: C O Mitter <[email protected]> + " + in commit messages. + See linkgit:git-interpret-trailers[1]for details. + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.
builtin/commit.c +8 -0
@@ -114,6 +114,7 @@ static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file;static struct strvec trailer_args =STRVEC_INIT ; +static int own_identity;/* * The default commit message cleanup mode will remove the lines
@@ -972,6 +973,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,strvec_pushl (&run_trailer.args,"interpret-trailers" ,"--in-place" ,git_path_commit_editmsg (),NULL ); +if (own_identity) +strvec_push (&run_trailer.args,"--own-identity" );strvec_pushv (&run_trailer.args, trailer_args.v); run_trailer.git_cmd =1 ;if (run_command (&run_trailer)) {
@@ -1530,6 +1533,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)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_ ("add custom trailer(s)" ),PARSE_OPT_NONEG , opt_pass_trailer), +OPT_BOOL (0 ,"own-identity" , &own_identity, +N_ ("specify the user's own identity for omitted trailers value" )),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")),
@@ -1606,6 +1611,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)if (verbose ==-1 ) verbose = (config_commit_verbose <0 ) ?0 : config_commit_verbose; +if (own_identity && !trailer_args.nr) +die (_ ("--own_identity requires --trailer" )); +if (dry_run)return dry_run_commit (argv, prefix, current_head, &s); index_file =prepare_index (argv, prefix, current_head,0 );
t/t7501-commit-basic-functionality.sh +91 -0
115 lines not on this page · raw message
t/t7502-commit-porcelain.sh +20 -0
@@ -490,6 +490,26 @@ test_expect_success 'commit --trailer with -c and ":=#" as separators' ' test_cmp expected actual ' +test_expect_success 'commit --trailer with -c and --own-identity' ' + echo "fun" >>file1 && + git add file1 && + cat >expected <<-\EOF && + + Signed-off-by: C O Mitter <[email protected]> + EOF + git -c trailer.signoff.key="Signed-off-by: " \ + commit --trailer "signoff" --own-identity -m "abc" && + git cat-file commit HEAD >commit.msg && + sed -e "1,6d" commit.msg >actual && + test_cmp expected actual +' + +test_expect_success 'commit --own-identity without --trailer' ' + echo "fun" >>file1 && + git add file1 && + test_must_fail git -c commit --own-identity -m "abc" +' + test_expect_success 'multiple -m' ' >negative &&
Signature · 1 line
gitgitgadget
Re: [PATCH v10 0/3] [GSOC] commit: add --trailer option
In reply to ZheNing Hu via GitGitGadgetQuoted 9 lines · ZheNing Hu via GitGitGadget
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
I see that you discussed an own-identity option in this thread recently, but this is version 10 of a patch series, so I don't think it's a good idea to introduce new features at this point. I think it's better to not tie the work that has already been done on polishing the first patch to new patches implementing an additional feature. The additional feature can be discussed and worked on in its own patch series building on top of this one.
Also it feels strange that only the first patch has "[GSOC]".
Re: [PATCH v10 0/3] [GSOC] commit: add --trailer option
Quoted 13 lines · Christian Couder <[email protected]> 于2021年3月18日周四 下午9:48写道:
Quoted 9 lines · ZheNing Hu via GitGitGadget
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
Quoted 8 lines
I see that you discussed an own-identity option in this thread recently, but this is version 10 of a patch series, so I don't think it's a good idea to introduce new features at this point. I think it's better to not tie the work that has already been done on polishing the first patch to new patches implementing an additional feature. The additional feature can be discussed and worked on in its own patch series building on top of this one.
OK, I understand that now. I will divide this patch series into two parts.
Quoted 1 line
Also it feels strange that only the first patch has "[GSOC]".
I forgot to add [GSOC]...
Thanks.
PATCH v11 1/1 commit: add --trailer option
In reply to ZheNing Hu via GitGitGadgetFrom: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new --trailer <token>[(=|:)<value>] option to pass other trailers to interpret-trailers and insert them into commit messages.
---
[GSOC] commit: add --trailer option
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.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v11
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v11
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Range-diff vs v10:
1: 949faf9ee56a ! 1: 0db1210ffd6d [GSOC] commit: add --trailer option
@@ Documentation/git-commit.txt: SYNOPSIS
[--date=<date>] [--cleanup=<mode>] [--[no-]status]
[-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]]
- [-S[<keyid>]] [--] [<pathspec>...]
-+ [-S[<keyid>]] [--] [<pathspec>...] [(--trailer <token>[(=|:)<value>])...]
++ [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]
++ [--] [<pathspec>...]
DESCRIPTION
-----------
@@ 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)) {
-+ die(_("unable to pass tailers to --trailers"));
-+ }
++ if (run_command(&run_trailer))
++ die(_("unable to pass trailers to --trailers"));
+ strvec_clear(&trailer_args);
+ }
+
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' '
+ test_cmp expected actual
+'
+
-+test_expect_success 'commit --trailer with -c and "=" as separators' '
++test_expect_success 'commit --trailer with "=" ' '
+ echo "fun" >>file1 &&
+ git add file1 &&
+ cat >expected <<-\EOF &&
+
-+ Acked-by= Peff
++ Acked-by: Peff
+ EOF
-+ git -c trailer.separators="=" \
-+ -c trailer.ack.key="Acked-by= " \
++ git -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 &&
2: 42590e95deee < -: ------------ interpret-trailers: add own-identity option
3: 2dfcc20f0e9f < -: ------------ commit: add own-identity optionDocumentation/git-commit.txt | 11 +- builtin/commit.c | 22 +++ t/t7502-commit-porcelain.sh | 335 +++++++++++++++++++++++++++++++++++ 3 files changed, 367 insertions(+), 1 deletion(-)
Documentation/git-commit.txt +10 -1
@@ -14,7 +14,8 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]] + [--] [<pathspec>...] DESCRIPTION -----------
@@ -166,6 +167,14 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off-by" trailer + and the "Helped-by" trailer in the commit message.) + 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 +22 -0
@@ -113,6 +113,7 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct strvec trailer_args =STRVEC_INIT ;/* * The default commit message cleanup mode will remove the lines
@@ -131,6 +132,14 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +BUG_ON_OPT_NEG (unset); + +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
@@ -958,6 +967,18 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +if (trailer_args.nr) { +struct child_process run_trailer =CHILD_PROCESS_INIT ; + +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--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)) +die (_ ("unable to pass trailers to --trailers" )); +strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be
@@ -1507,6 +1528,7 @@ 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_ ("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 +335 -0
341 lines not on this page · raw message
base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945
Signature · 1 line
gitgitgadget
Re: [PATCH v11] [GSOC] commit: add --trailer option
Documentation/git-commit.txt The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. · line 175
Quoted 6 lines · ZheNing Hu via GitGitGadget
+--trailer <token>[(=|:)<value>]::
Documentation/git-commit.txt +5
-0+ Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off-by" trailer + and the "Helped-by" trailer in the commit message.)
s/in the commit message/to the commit message/ probably.
Documentation/git-commit.txt The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. · line 177
Quoted 2 lines
Documentation/git-commit.txt +2
-0+ Use `git -c trailer.* commit --trailer` to make the appropriate + configuration. See linkgit:git-interpret-trailers[1] for details.
I doubt this is a good advice for a few reasons.
(1) The "git -c var=val" is meant to be used as a single-shot oddball configuration. If the user will be working on the project long enough to be worth using the --trailer option (otherwise a single-shot drive-by patch can just add these trailers while editing the log message in the editor), the user would not want to use "git -c var=val" mechanism to use different configuration every time the --trailer option is used.
(2) The "appropriate configuration" is too vague and does not give enough incentive to the reader to go look in the other manual page. At least there should be a cursory mention of what kind of things are possible by the configuration.
Prehaps
The trailer.* configuration variables (see linkgit:...) can be used to define if a duplicated trailer is omitted, where in the run of trailers each trailer would appear, and other details.
or something along the line (Christian would be a better person to suggest what good examples are than I am, though).
Quoted 31 lines
builtin/commit.c +9
-0@@ -113,6 +113,7 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct strvec trailer_args =STRVEC_INIT ;/* * The default commit message cleanup mode will remove the lines @@ -131,6 +132,14 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +BUG_ON_OPT_NEG (unset); + +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;@@ -958,6 +967,18 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp);
builtin/commit.c static int prepare_to_commit(const char *index_file, const char *prefix, · line 979
Quoted 10 lines
builtin/commit.c +10
-0+if (trailer_args.nr) { +struct child_process run_trailer =CHILD_PROCESS_INIT ; + +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--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)) +die (_ ("unable to pass trailers to --trailers" )); +strvec_clear (&trailer_args);
OK. run_command() cleans the run_trailer.args when it returns, so we only need to clear our own array here.
Quoted 19 lines
builtin/commit.c +2
-0+ } +t/t7502-commit-porcelain.sh +8
-0@@ -154,6 +154,341 @@ test_expect_success 'sign off' ' ' +test_expect_success 'commit --trailer without -c' ' + echo "fun" >>file && + git add file && + cat >expected <<-\EOF && + + Signed-off-by: C O Mitter <[email protected]> + Signed-off-by: C1 E1 + Helped-by: C2 E2
t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 174
Quoted 10 lines
t/t7502-commit-porcelain.sh +10
-0+ 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,6d" commit.msg >actual &&
This 1,6d depends on the exact line organization of the underlying object detail, which is not good. You'd want to grab the run of the consecutive non-empty lines at the end, so that commit object headers and the log message "fun" can change over time by changes to Git and changes to this test, without breaking this test.
Quoted 11 lines
t/t7502-commit-porcelain.sh +11
-0+ 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 <[email protected]> + Signed-off-by: C1 E1 + Reported-by: C3 E3
t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 195
Quoted 10 lines
t/t7502-commit-porcelain.sh +10
-0+ 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
The same comment applies, and also by using "--amend", this relies on the outcome of the previous test, which is not great.
Quoted 9 lines
t/t7502-commit-porcelain.sh +9
-0+' + +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 <[email protected]> + Signed-off-by: C1 E1
t/t7502-commit-porcelain.sh test_expect_success 'sign off' ' · line 214
Quoted 10 lines
t/t7502-commit-porcelain.sh +10
-0+ 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 &&
And it makes things worse by keep amending.
At least, establish a baseline commit that has known set of trailers, tag it, and reset the HEAD to that commit at the beginning of each test that tries to amend an existing commit. That way, the correctness of each individual test would depend only on the test that creates the baseline commit and tags it.
PATCH v12 1/1 commit: add --trailer option
In reply to ZheNing Hu via GitGitGadgetFrom: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new --trailer <token>[(=|:)<value>] option to pass other trailers to interpret-trailers and insert them into commit messages.
---
[GSOC] commit: add --trailer option
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.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v12
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v12
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Range-diff vs v11:
1: 0db1210ffd6d ! 1: 2378e3b4c1ae [GSOC] commit: add --trailer option
@@ Documentation/git-commit.txt: The `-m` option is mutually exclusive with `-c`, `
+ trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \
+ <[email protected]>" --trailer "Helped-by:C O Mitter \
+ <[email protected]>"` will add the "Signed-off-by" trailer
-+ and the "Helped-by" trailer in the commit message.)
-+ Use `git -c trailer.* commit --trailer` to make the appropriate
-+ configuration. See linkgit:git-interpret-trailers[1] for details.
++ and the "Helped-by" trailer to the commit message.)
++ The `trailer.*` configuration variables
++ (linkgit:git-interpret-trailers[1]) can be used to define if
++ a duplicated trailer is omitted, where in the run of trailers
++ each trailer would appear, and other details.
++
-n::
--no-verify::
This option bypasses the pre-commit and commit-msg hooks.
@@ builtin/commit.c: int cmd_commit(int argc, const char **argv, const char *prefix
OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")),
## t/t7502-commit-porcelain.sh ##
+@@ t/t7502-commit-porcelain.sh: check_summary_oneline() {
+ test_cmp exp act
+ }
+
++trailer_commit_base () {
++ echo "fun" >>file &&
++ git add file &&
++ 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"
++}
++
+ test_expect_success 'output summary format' '
+
+ echo new >file1 &&
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' '
'
-+test_expect_success 'commit --trailer without -c' '
-+ echo "fun" >>file &&
-+ git add file &&
++test_expect_success 'commit --trailer with "="' '
++ trailer_commit_base &&
+ cat >expected <<-\EOF &&
++ hello
+
+ Signed-off-by: C O Mitter <[email protected]>
+ Signed-off-by: C1 E1
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' '
+ 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,6d" commit.msg >actual &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'commit --trailer with -c and "replace" as ifexists' '
-+ echo "fun" >>file1 &&
-+ git add file1 &&
++ trailer_commit_base &&
+ cat >expected <<-\EOF &&
++ hello
+
+ Signed-off-by: C O Mitter <[email protected]>
+ Signed-off-by: C1 E1
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' '
+ --trailer "Helped-by: C3 E3" \
+ --amend &&
+ git cat-file commit HEAD >commit.msg &&
-+ sed -e "1,6d" commit.msg >actual &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'commit --trailer with -c and "add" as ifexists' '
-+ echo "fun" >>file1 &&
-+ git add file1 &&
++ trailer_commit_base &&
+ cat >expected <<-\EOF &&
++ hello
+
+ Signed-off-by: C O Mitter <[email protected]>
+ Signed-off-by: C1 E1
++ Helped-by: C2 E2
++ Reported-by: C3 E3
++ Mentored-by: C4 E4
+ 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" \
++ commit --trailer "Reported-by: C3 E3" \
++ --trailer "Mentored-by: C4 E4" \
+ --amend &&
+ git cat-file commit HEAD >commit.msg &&
-+ sed -e "1,6d" commit.msg >actual &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'commit --trailer with -c and "donothing" as ifexists' '
-+ echo "fun" >>file1 &&
-+ git add file1 &&
++ trailer_commit_base &&
+ cat >expected <<-\EOF &&
++ hello
+
+ Signed-off-by: C O Mitter <[email protected]>
+ Signed-off-by: C1 E1
++ Helped-by: C2 E2
+ 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" \
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' '
+ --trailer "Reviewed-by: C6 E6" \
+ --amend &&
+ git cat-file commit HEAD >commit.msg &&
-+ sed -e "1,6d" commit.msg >actual &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'commit --trailer with -c and "addIfDifferent" as ifexists' '
-+ echo "fun" >>file1 &&
-+ git add file1 &&
++ trailer_commit_base &&
+ cat >expected <<-\EOF &&
++ hello
+
+ Signed-off-by: C O Mitter <[email protected]>
+ Signed-off-by: C1 E1
++ Helped-by: C2 E2
+ 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
++ Mentored-by: C5 E5
+ EOF
+ git -c trailer.ifexists="addIfDifferent" \
-+ commit --trailer "Reviewed-by: C6 E6" \
-+ --trailer "Reported-by: C5 E5" \
++ commit --trailer "Reported-by: C3 E3" \
++ --trailer "Mentored-by: C5 E5" \
+ --amend &&
+ git cat-file commit HEAD >commit.msg &&
-+ sed -e "1,6d" commit.msg >actual &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'commit --trailer with -c and "addIfDifferentNeighbor" as ifexists' '
-+ echo "fun" >>file1 &&
-+ git add file1 &&
++ trailer_commit_base &&
+ cat >expected <<-\EOF &&
++ hello
+
+ Signed-off-by: C O Mitter <[email protected]>
+ Signed-off-by: C1 E1
++ Helped-by: C2 E2
+ 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: C3 E3
+ EOF
-+ git -c trailer.ifexists="addIfDifferent" \
-+ commit --trailer "Reported-by: C5 E5" \
-+ --trailer "Reviewed-by: C6 E6" \
++ git -c trailer.ifexists="addIfDifferentNeighbor" \
++ commit --trailer "Mentored-by: C4 E4" \
++ --trailer "Reported-by: C3 E3" \
+ --amend &&
+ git cat-file commit HEAD >commit.msg &&
-+ sed -e "1,6d" commit.msg >actual &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'commit --trailer with -c and "end" as where' '
-+ echo "fun" >>file1 &&
-+ git add file1 &&
++ trailer_commit_base &&
+ cat >expected <<-\EOF &&
++ hello
+
+ Signed-off-by: C O Mitter <[email protected]>
+ Signed-off-by: C1 E1
++ Helped-by: C2 E2
++ Reported-by: C3 E3
++ Mentored-by: C4 E4
+ 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" \
++ commit --trailer "Reported-by: C3 E3" \
++ --trailer "Mentored-by: C4 E4" \
+ --amend &&
+ git cat-file commit HEAD >commit.msg &&
-+ sed -e "1,6d" commit.msg >actual &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'commit --trailer with -c and "start" as where' '
-+ echo "fun" >>file1 &&
-+ git add file1 &&
++ trailer_commit_base &&
+ cat >expected <<-\EOF &&
++ hello
+
-+ Signed-off-by: C8 E8
++ Signed-off-by: C1 E1
+ Signed-off-by: C O Mitter <[email protected]>
+ Signed-off-by: C1 E1
++ Helped-by: C2 E2
+ 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" \
++ commit --trailer "Signed-off-by: C O Mitter <[email protected]>" \
++ --trailer "Signed-off-by: C1 E1" \
+ --amend &&
+ git cat-file commit HEAD >commit.msg &&
-+ sed -e "1,6d" commit.msg >actual &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'commit --trailer with -c and "after" as where' '
-+ echo "fun" >>file1 &&
-+ git add file1 &&
++ trailer_commit_base &&
+ cat >expected <<-\EOF &&
++ hello
+
-+ Signed-off-by: C8 E8
+ Signed-off-by: C O Mitter <[email protected]>
+ Signed-off-by: C1 E1
++ Helped-by: C2 E2
+ 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
++ Mentored-by: C5 E5
+ EOF
+ git -c trailer.where="after" \
-+ commit --trailer "Mentored-by: C9 E9" \
-+ --trailer "Reported-by: C10 E10" \
++ commit --trailer "Mentored-by: C4 E4" \
++ --trailer "Mentored-by: C5 E5" \
+ --amend &&
+ git cat-file commit HEAD >commit.msg &&
-+ sed -e "1,6d" commit.msg >actual &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'commit --trailer with -c and "before" as where' '
-+ echo "fun" >>file1 &&
-+ git add file1 &&
++ trailer_commit_base &&
+ cat >expected <<-\EOF &&
++ hello
+
-+ Signed-off-by: C8 E8
+ Signed-off-by: C O Mitter <[email protected]>
+ Signed-off-by: C1 E1
-+ Reported-by: C11 E11
++ Helped-by: C2 E2
+ Reported-by: C3 E3
++ Mentored-by: C2 E2
++ Mentored-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" \
++ commit --trailer "Mentored-by: C3 E3" \
++ --trailer "Mentored-by: C2 E2" \
+ --amend &&
+ git cat-file commit HEAD >commit.msg &&
-+ sed -e "1,6d" commit.msg >actual &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'commit --trailer with -c and "donothing" as ifmissing' '
-+ echo "fun" >>file1 &&
-+ git add file1 &&
++ trailer_commit_base &&
+ cat >expected <<-\EOF &&
++ hello
+
-+ Signed-off-by: C8 E8
+ Signed-off-by: C O Mitter <[email protected]>
+ Signed-off-by: C1 E1
-+ Reported-by: C11 E11
++ Helped-by: C2 E2
+ 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
++ Helped-by: C5 E5
+ EOF
+ git -c trailer.ifmissing="donothing" \
-+ commit --trailer "Helped-by: C12 E12" \
-+ --trailer "Based-by: C13 E13" \
++ commit --trailer "Helped-by: C5 E5" \
++ --trailer "Based-by: C6 E6" \
+ --amend &&
+ git cat-file commit HEAD >commit.msg &&
-+ sed -e "1,6d" commit.msg >actual &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'commit --trailer with -c and "add" as ifmissing' '
-+ echo "fun" >>file1 &&
-+ git add file1 &&
++ trailer_commit_base &&
+ cat >expected <<-\EOF &&
++ hello
+
-+ Signed-off-by: C8 E8
+ Signed-off-by: C O Mitter <[email protected]>
+ Signed-off-by: C1 E1
-+ Reported-by: C11 E11
++ Helped-by: C2 E2
+ 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
++ Helped-by: C5 E5
++ Based-by: C6 E6
+ EOF
+ git -c trailer.ifmissing="add" \
-+ commit --trailer "Helped-by: C12 E12" \
-+ --trailer "Based-by: C13 E13" \
++ commit --trailer "Helped-by: C5 E5" \
++ --trailer "Based-by: C6 E6" \
+ --amend &&
+ git cat-file commit HEAD >commit.msg &&
-+ sed -e "1,6d" commit.msg >actual &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+
-+test_expect_success 'commit --trailer with "=" ' '
++test_expect_success 'commit --trailer with -c ack.key ' '
+ echo "fun" >>file1 &&
+ git add file1 &&
+ cat >expected <<-\EOF &&
++ hello
+
+ Acked-by: Peff
+ EOF
+ git -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 &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' '
+ echo "fun" >>file1 &&
+ git add file1 &&
+ cat >expected <<-\EOF &&
++ I hate bug
+
+ Bug #42
+ EOF
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' '
+ -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 &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
+Documentation/git-commit.txt | 14 +- builtin/commit.c | 22 +++ t/t7502-commit-porcelain.sh | 291 +++++++++++++++++++++++++++++++++++ 3 files changed, 326 insertions(+), 1 deletion(-)
Documentation/git-commit.txt +13 -1
@@ -14,7 +14,8 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]] + [--] [<pathspec>...] DESCRIPTION -----------
@@ -166,6 +167,17 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off-by" trailer + and the "Helped-by" trailer to the commit message.) + The `trailer.*` configuration variables + (linkgit:git-interpret-trailers[1]) can be used to define if + a duplicated trailer is omitted, where in the run of trailers + each trailer would appear, and other details. + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.
builtin/commit.c +22 -0
@@ -113,6 +113,7 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct strvec trailer_args =STRVEC_INIT ;/* * The default commit message cleanup mode will remove the lines
@@ -131,6 +132,14 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +BUG_ON_OPT_NEG (unset); + +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
@@ -958,6 +967,18 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +if (trailer_args.nr) { +struct child_process run_trailer =CHILD_PROCESS_INIT ; + +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--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)) +die (_ ("unable to pass trailers to --trailers" )); +strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be
@@ -1507,6 +1528,7 @@ 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_ ("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 +291 -0
303 lines not on this page · raw message
base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945
Signature · 1 line
gitgitgadget
PATCH v13 1/1 commit: add --trailer option
From: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new --trailer <token>[(=|:)<value>] option to pass other trailers to interpret-trailers and insert them into commit messages.
Reported-by:
---
[GSOC] commit: add --trailer option
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.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v13
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v13
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Range-diff vs v12:
1: 2378e3b4c1ae ! 1: 98b0c470e141 [GSOC] commit: add --trailer option
@@ Commit message
messages.
Signed-off-by: ZheNing Hu <[email protected]>
+ Reported-by:
## Documentation/git-commit.txt ##
@@ Documentation/git-commit.txt: SYNOPSIS
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' '
+ sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
++
++test_expect_success 'commit --trailer with -c and command' '
++ trailer_commit_base &&
++ cat >expected <<-\EOF &&
++ hello
++
++ Signed-off-by: C O Mitter <[email protected]>
++ Signed-off-by: C1 E1
++ Helped-by: C2 E2
++ Mentored-by: C4 E4
++ Reported-by: A U Thor <[email protected]>
++ EOF
++ git -c trailer.report.key="Reported-by: " \
++ -c trailer.report.ifexists="replace" \
++ -c trailer.report.command="git log --author=\"\$ARG\" -1 \
++ --format=\"format:%aN <%aE>\"" \
++ commit --trailer "report = author" --amend &&
++ git cat-file commit HEAD >commit.msg &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
++ test_cmp expected actual
++'
+
test_expect_success 'multiple -m' 'Documentation/git-commit.txt | 14 +- builtin/commit.c | 22 +++ t/t7502-commit-porcelain.sh | 312 +++++++++++++++++++++++++++++++++++ 3 files changed, 347 insertions(+), 1 deletion(-)
Documentation/git-commit.txt +13 -1
@@ -14,7 +14,8 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]] + [--] [<pathspec>...] DESCRIPTION -----------
@@ -166,6 +167,17 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off-by" trailer + and the "Helped-by" trailer to the commit message.) + The `trailer.*` configuration variables + (linkgit:git-interpret-trailers[1]) can be used to define if + a duplicated trailer is omitted, where in the run of trailers + each trailer would appear, and other details. + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.
builtin/commit.c +22 -0
@@ -113,6 +113,7 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct strvec trailer_args =STRVEC_INIT ;/* * The default commit message cleanup mode will remove the lines
@@ -131,6 +132,14 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +BUG_ON_OPT_NEG (unset); + +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
@@ -958,6 +967,18 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +if (trailer_args.nr) { +struct child_process run_trailer =CHILD_PROCESS_INIT ; + +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--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)) +die (_ ("unable to pass trailers to --trailers" )); +strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be
@@ -1507,6 +1528,7 @@ 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_ ("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 +312 -0
324 lines not on this page · raw message
base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945
Signature · 1 line
gitgitgadget
Re: [PATCH v13] [GSOC] commit: add --trailer option
Quoted 8 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Quoted 6 lines
Now implement a new
--trailer <token>[(=|:)<value>]option to pass other trailers tointerpret-trailersand insert them into commit messages.Signed-off-by ZheNing Hu <[email protected]>Reported-by:
Why is there this "Reported-by:" trailer with an empty value? If you are looking to add trailers to this commit message, you might want to add them before your "Signed-off-by".
Quoted 7 lines
---
[GSOC] commit: add --trailer optionNow 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.
It's not a big deal as this is not going into the commit message, but at this point (v13) you might want to tell explicitly what solution v1 implemented, instead of referring to it.
Quoted 16 lines
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' '> + sed -e "1,/^\$/d" commit.msg >actual &&
+ test_cmp expected actual
+'
++
++test_expect_success 'commit --trailer with -c and command' '
++ trailer_commit_base &&
++ cat >expected <<-\EOF &&
++ hello
++
++ Signed-off-by: C O Mitter <[email protected]>
++ Signed-off-by: C1 E1
++ Helped-by: C2 E2
++ Mentored-by: C4 E4
++ Reported-by: A U Thor <[email protected]>
++ EOF
++ git -c trailer.report.key="Reported-by: " \Quoted 8 lines
++ -c trailer.report.ifexists="replace" \
++ -c trailer.report.command="git log --author=\"\$ARG\" -1 \
++ --format=\"format:%aN <%aE>\"" \
++ commit --trailer "report = author" --amend &&
++ git cat-file commit HEAD >commit.msg &&
++ sed -e "1,/^\$/d" commit.msg >actual &&
++ test_cmp expected actual
++'Nice that you have added such a test!
Re: [PATCH v13] [GSOC] commit: add --trailer option
Quoted 15 lines · Christian Couder <[email protected]> 于2021年3月22日周一 下午3:43写道:
Quoted 12 lines · ZheNing Hu via GitGitGadget
From: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new
--trailer <token>[(=|:)<value>]option to pass other trailers tointerpret-trailersand insert them into commit messages.
Quoted 7 lines
Quoted 2 lines
Signed-off-by ZheNing Hu <[email protected]>Reported-by:
Why is there this "Reported-by:" trailer with an empty value? If you are looking to add trailers to this commit message, you might want to add them before your "Signed-off-by".
Sorry, It was purely a small accident during testing and I didn't notice it.
Quoted 11 lines
Quoted 7 lines
---
[GSOC] commit: add --trailer optionNow 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.
It's not a big deal as this is not going into the commit message, but at this point (v13) you might want to tell explicitly what solution v1 implemented, instead of referring to it.
Ok.
Quoted 26 lines
Quoted 17 lines
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' '> + sed -e "1,/^\$/d" commit.msg >actual && + test_cmp expected actual +' ++ ++test_expect_success 'commit --trailer with -c and command' ' ++ trailer_commit_base && ++ cat >expected <<-\EOF && ++ hello ++ ++ Signed-off-by: C O Mitter <[email protected]> ++ Signed-off-by: C1 E1 ++ Helped-by: C2 E2 ++ Mentored-by: C4 E4 ++ Reported-by: A U Thor <[email protected]> ++ EOF ++ git -c trailer.report.key="Reported-by: " \Quoted 8 lines
++ -c trailer.report.ifexists="replace" \ ++ -c trailer.report.command="git log --author=\"\$ARG\" -1 \ ++ --format=\"format:%aN <%aE>\"" \ ++ commit --trailer "report = author" --amend && ++ git cat-file commit HEAD >commit.msg && ++ sed -e "1,/^\$/d" commit.msg >actual && ++ test_cmp expected actual ++'
Quoted 1 line
Nice that you have added such a test!
Thanks.
But at the same time I have two little doubt.
1.
If we have your config:
$ git config trailer.sign.key "Signed-off-by: " $ git config trailer.sign.ifexists replace $ git config trailer.sign.command "git log --author='\$ARG' -1 --format='format:%aN <%aE>'"
Then I touch a test.c and use:
$ git interpret-trailers --in-place test.c
without --trailer, See what is happen:
It seem like your local repo last commit "name <email>" pair have been record in test.c.
Could this be considered a bug?
2.git interpret-trailers --in-place seem like work on git top-dir, If I am in a sub-dir b and I want to change a file such as d.c, then I must use git interpret-trailers --in-place b/d.c to add some trailers.
I think the original intention of --in-place is to modify a file similar to "$COMMIT_MSG_FILE", so make it run at top-dir, but this is not reflected in the git documentation. This at least confuses people who use this option for the first time. Is it worth modifying? Or is there something wrong with the design of --in-place?
--
ZheNing Hu
Re: [PATCH v13] [GSOC] commit: add --trailer option
Quoted 19 lines · ZheNing Hu
Quoted 1 line · Christian Couder <[email protected]> 于2021年3月22日周一 下午3:43写道:
Nice that you have added such a test!
Thanks.
But at the same time I have two little doubt.
1.
If we have your config:$ git config trailer.sign.key "Signed-off-by: " $ git config trailer.sign.ifexists replace $ git config trailer.sign.command "git log --author='\$ARG' -1 --format='format:%aN <%aE>'"Then I touch a
test.cand use:
Quoted 8 lines
$ git interpret-trailers --in-place test.cwithout
--trailer, See what is happen:It seem like your local repo last commit "name <email>" pair have been record in
test.c.Could this be considered a bug?
First it seems strange to use git interpret-trailers on a "test.c" file. It's supposed to be used on commit messages.
Then, as the doc says, every command specified by any "trailer.<token>.command" config option is run at least once when git interpret-trailers is run. This is because users might want to automatically add some trailers all the time.
If you want nothing to happen when $ARG isn't set, you can change the config option to something like:
$ git config trailer.sign.command "NAME='\$ARG'; test -n \"\$NAME\" && git log --author=\"\$NAME\" -1 --format='format:%aN <%aE>' || true"
(This is because it looks like $ARG is replaced only once with the actual value, which is perhaps a bug. Otherwise something like the following might work:
git config trailer.sign.command "test -n '\$ARG' && git log --author='\$ARG' -1 --format='format:%aN <%aE>' || true")
Then you can run git interpret-trailers with the --trim-empty option like this:
------
$ git interpret-trailers --trim-empty --trailer sign=Linus<<EOF EOF
------
or like:
------
$ git interpret-trailers --trim-empty<<EOF
Quoted 1 line
EOF
------
Re: [PATCH v13] [GSOC] commit: add --trailer option
Quoted 30 lines · Christian Couder <[email protected]> 于2021年3月23日周二 上午5:34写道:
Quoted 19 lines · ZheNing Hu
Quoted 1 line · Christian Couder <[email protected]> 于2021年3月22日周一 下午3:43写道:
Nice that you have added such a test!
Thanks.
But at the same time I have two little doubt.
1.
If we have your config:$ git config trailer.sign.key "Signed-off-by: " $ git config trailer.sign.ifexists replace $ git config trailer.sign.command "git log --author='\$ARG' -1 --format='format:%aN <%aE>'"Then I touch a
test.cand use:Quoted 8 lines
$ git interpret-trailers --in-place test.cwithout
--trailer, See what is happen:It seem like your local repo last commit "name <email>" pair have been record in
test.c.Could this be considered a bug?
Quoted 8 lines
First it seems strange to use
git interpret-trailerson a "test.c" file. It's supposed to be used on commit messages.Then, as the doc says, every command specified by any "trailer.<token>.command" config option is run at least once when
git interpret-trailersis run. This is because users might want to automatically add some trailers all the time.
Well, I understand it now.
Quoted 9 lines
If you want nothing to happen when $ARG isn't set, you can change the config option to something like:
$ git config trailer.sign.command "NAME='\$ARG'; test -n \"\$NAME\" && git log --author=\"\$NAME\" -1 --format='format:%aN <%aE>' || true"(This is because it looks like $ARG is replaced only once with the actual value, which is perhaps a bug. Otherwise something like the following might work:
this is because $ARG is replaced in "trailer.c" by "strbuf_replace" which only replcae the specified string for only one time,
I think strbuf_replace() can be changed like:
@@ -110,8 +110,9 @@ static inline int is_blank_line(const char *str)
static inline void strbuf_replace(struct strbuf *sb, const char *a,
const char *b)
{
- const char *ptr = strstr(sb->buf, a);
- if (ptr)
+ char *ptr = sb->buf;
+
+ while ((ptr = strstr(ptr, a)))
strbuf_splice(sb, ptr - sb->buf, strlen(a), b, strlen(b));}
Quoted 14 lines
git config trailer.sign.command "test -n '\$ARG' && git log --author='\$ARG' -1 --format='format:%aN <%aE>' || true")
Then you can run
git interpret-trailerswith the --trim-empty option like this:------
$ git interpret-trailers --trim-empty --trailer sign=Linus<<EOF EOFSigned-off-by Linus Torvalds <[email protected]>------
Quoted 7 lines
or like:
------
$ git interpret-trailers --trim-empty<<EOFQuoted 1 line
EOF
------
Thanks for effective solution.
Maybe I should also correct this part of the test.
Re: [PATCH v13] [GSOC] commit: add --trailer option
In reply to Christian CouderQuoted 9 lines · Christian Couder
If you want nothing to happen when $ARG isn't set, you can change the config option to something like:
$ git config trailer.sign.command "NAME='\$ARG'; test -n \"\$NAME\" && git log --author=\"\$NAME\" -1 --format='format:%aN <%aE>' || true"(This is because it looks like $ARG is replaced only once with the actual value, which is perhaps a bug. Otherwise something like the following might work:
I do not know the origin of that code in trailers.c but it feels quite confused and error prone to use textual replacement with strbuf_replace(). Why doesn't the code, which knows it will use shell to execute the command line given by the end user in the configuration, to just export ARG as an environment variable and be done with it? It would also avoid quoting problem etc.
Re: [PATCH v13] [GSOC] commit: add --trailer option
Quoted 13 lines · Junio C Hamano
Quoted 9 lines · Christian Couder
If you want nothing to happen when $ARG isn't set, you can change the config option to something like:
$ git config trailer.sign.command "NAME='\$ARG'; test -n \"\$NAME\" && git log --author=\"\$NAME\" -1 --format='format:%aN <%aE>' || true"(This is because it looks like $ARG is replaced only once with the actual value, which is perhaps a bug. Otherwise something like the following might work:
Quoted 6 lines
I do not know the origin of that code in
trailers.cbut it feels quite confused and error prone to use textual replacement withstrbuf_replace(). Why doesn't the code, which knows it will use shell to execute the command line given by the end user in the configuration, to just export ARG as an environment variable and be done with it? It would also avoid quoting problem etc.
Yeah, I agree that would be better.
Re: [PATCH v13] [GSOC] commit: add --trailer option
Quoted 14 lines · Christian Couder
Quoted 13 lines · Junio C Hamano
Quoted 9 lines · Christian Couder
If you want nothing to happen when $ARG isn't set, you can change the config option to something like:
$ git config trailer.sign.command "NAME='\$ARG'; test -n \"\$NAME\" && git log --author=\"\$NAME\" -1 --format='format:%aN <%aE>' || true"(This is because it looks like $ARG is replaced only once with the actual value, which is perhaps a bug. Otherwise something like the following might work:
Quoted 8 lines
Quoted 6 lines
I do not know the origin of that code in
trailers.cbut it feels quite confused and error prone to use textual replacement withstrbuf_replace(). Why doesn't the code, which knows it will use shell to execute the command line given by the end user in the configuration, to just export ARG as an environment variable and be done with it? It would also avoid quoting problem etc.Yeah, I agree that would be better.
It probably would have been better to do so before the feature got unleased to the public, but doing such a change retroactively would introduce regression for those who were using ARG that happens to be safe from shell quoting rules.
For example, if the trailer.*.command were
echo '$ARG'
and the argument 'h e l l o' were to be given to it, then the current code would have textually expanded $ARG with the argument and caused
echo 'h e l l o'
to run, which would have been "fine" [*1*].
But exporting the environment ARG would "break" such a setting that has been "working perfectly well" for the user. Because of the single-quotes around $ARG, the command now will give literal four letter string $ARG and not 'h e l l o'.
We should think such potential ramifications of changing it (and also not changing it) through before deciding what to do about it.
Although I have a feeling that not many people would miss '$ARG' inside a pair of single-quotes to be replaced textually and it would be OK to make a backward incompatible bugfix, the safer and better way is not all that difficult, so I am inclined to suggest going the usual "deprecate and replace and then later remove" dance.
The normal sequence of replacing a "sort of works but not recommended" feature with a "better and safer, but can break a setting that has been 'working'" feature is:
- Announce deprecation of trailer.x.command and add and advertise a similar traier.x.cmd that (1) exports environment variable ARG, or (2) passes the argument as a positional parameter [*], as a replacement. Explain the reason for deprecation (i.e. unsafe substitution that works only once). When .cmd exists, .command is ignored for the corresponding trailer.x
- Wait for a few releases and then remove trailer.x.command.
and that is the safest way to fix this "bug".
[Footnotes]
*1* If the argument were
';rm -rf .;'
then it wouldn't have been fine, though, and that is how the current code solicited "Huh?" reaction out of me.
*2* If we passed the argument as a positional parameter, the example
you gave in the quoted part of the message would become something like this:
[trailer "sign"]
cmd = test -n "$1" && git log --author="$1" -1 --format='%aN <%aE>'
Re: [PATCH v13] [GSOC] commit: add --trailer option
Quoted 23 lines
It probably would have been better to do so before the feature got unleased to the public, but doing such a change retroactively would introduce regression for those who were using ARG that happens to be safe from shell quoting rules.
For example, if the trailer.*.command were
echo '$ARG'and the argument 'h e l l o' were to be given to it, then the current code would have textually expanded $ARG with the argument and caused
echo 'h e l l o'
to run, which would have been "fine" [*1*].
But exporting the environment ARG would "break" such a setting that has been "working perfectly well" for the user. Because of the single-quotes around $ARG, the command now will give literal four letter string $ARG and not 'h e l l o'.
Quoted 9 lines
We should think such potential ramifications of changing it (and also not changing it) through before deciding what to do about it.
Although I have a feeling that not many people would miss '$ARG' inside a pair of single-quotes to be replaced textually and it would be OK to make a backward incompatible bugfix, the safer and better way is not all that difficult, so I am inclined to suggest going the usual "deprecate and replace and then later remove" dance.
I think what you mean is that my patch breaks the principle of "forward compatibility", which may make it impossible for users who previously worked with '$ARG'.
Quoted 11 lines
The normal sequence of replacing a "sort of works but not recommended" feature with a "better and safer, but can break a setting that has been 'working'" feature is:
- Announce deprecation of trailer.x.command and add and advertise a similar traier.x.cmd that (1) exports environment variable ARG, or (2) passes the argument as a positional parameter [*], as a replacement. Explain the reason for deprecation (i.e. unsafe substitution that works only once). When .cmd exists, .command is ignored for the corresponding trailer.x
As your example below:
cmd = test -n "$1" && git log --author="$1" -1 --format='%aN <%aE>'
I would like to use this way.
It may be a bit cumbersome to do "deprecate and replace and then later remove", Should documents tell users that the old method "trailer.command" has been replaced by "trialer.cmd"? Or tell users that "trailer.cmd" is a new feature?
Keep these doubts, I will try go to code it.
Quoted 5 lines
- Wait for a few releases and then remove trailer.x.command.
and that is the safest way to fix this "bug".
Quoted 9 lines
[Footnotes]
*1* If the argument were
';rm -rf .;'
then it wouldn't have been fine, though, and that is how the current code solicited "Huh?" reaction out of me.
A little scary. :-)
Quoted 7 lines
*2* If we passed the argument as a positional parameter, the example
you gave in the quoted part of the message would become something like this:[trailer "sign"]
cmd = test -n "$1" && git log --author="$1" -1 --format='%aN <%aE>'
Re: [PATCH v13] [GSOC] commit: add --trailer option
In reply to Junio C HamanoQuoted 13 lines · Junio C Hamano <[email protected]> 于2021年3月23日周二 下午2:19写道:
Quoted 9 lines · Christian Couder
If you want nothing to happen when $ARG isn't set, you can change the config option to something like:
$ git config trailer.sign.command "NAME='\$ARG'; test -n \"\$NAME\" && git log --author=\"\$NAME\" -1 --format='format:%aN <%aE>' || true"(This is because it looks like $ARG is replaced only once with the actual value, which is perhaps a bug. Otherwise something like the following might work:
Quoted 7 lines
I do not know the origin of that code in
trailers.cbut it feels quite confused and error prone to use textual replacement withstrbuf_replace(). Why doesn't the code, which knows it will use shell to execute the command line given by the end user in the configuration, to just export ARG as an environment variable and be done with it? It would also avoid quoting problem etc.
Maybe like this?
-#define TRAILER_ARG_STRING "$ARG"
-
static const char *git_generated_prefixes[] = {
"Signed-off-by: ",
"(cherry picked from commit ",
@@ -222,13 +220,17 @@ static char *apply_command(const char *command, const char *arg)
struct strbuf buf = STRBUF_INIT;
struct child_process cp = CHILD_PROCESS_INIT;
char *result;+ const char *const *var;
strbuf_addstr(&cmd, command);
- if (arg)
- strbuf_replace(&cmd, TRAILER_ARG_STRING, arg);
+ for (var = local_repo_env; *var; var++)
+ strvec_push(&cp.env_array, *var);
+ if (arg) {
+ strvec_pushf(&cp.env_array, "ARG=%s", arg);
+ }
strvec_push(&cp.args, cmd.buf);
- cp.env = local_repo_env;
+
cp.no_stdin = 1;
cp.use_shell = 1;Re: [PATCH v13] [GSOC] commit: add --trailer option
Quoted 4 lines · ZheNing Hu
Junio C Hamano <[email protected]> 于2021年3月23日周二 下午2:19写道:
Maybe like this?
Yeah, it's a good idea to work on this, but please make it an independent patch unrelated to adding --trailer to git commit.
Also the documentation might need a bit of tweeking to tell that ARG is now an exported environment variable.
Quoted 1 line
-#define
TRAILER_ARG_STRING"$ARG"
It might still be better to use a #define or a const char [] to avoid hard coding "ARG" below.
Quoted 8 lines
static const char *git_generated_prefixes[] = {
"Signed-off-by: ",
"(cherry picked from commit ",(quoted diff) +0
-0@@ -222,13 +220,17 @@ static char *apply_command(const char *command, const char *arg) struct strbuf buf = STRBUF_INIT; struct child_process cp = CHILD_PROCESS_INIT; char *result;
Review static char *apply_command(const char *command, · line 231
Quoted 10 lines
(quoted diff) +6
-2+ const char *const *var; strbuf_addstr(&cmd, command); - if (arg) - strbuf_replace(&cmd, TRAILER_ARG_STRING, arg); + for (var = local_repo_env; *var; var++) + strvec_push(&cp.env_array, *var); + if (arg) { + strvec_pushf(&cp.env_array, "ARG=%s", arg); + }
You can drop the "{" and "}" above.
Review static char *apply_command(const char *command, · line 235
Quoted 5 lines
(quoted diff) +1
-1strvec_push(&cp.args, cmd.buf); - cp.env = local_repo_env; + cp.no_stdin = 1; cp.use_shell = 1;
Thanks!
Re: [PATCH v13] [GSOC] commit: add --trailer option
In reply to ZheNing HuQuoted 22 lines · ZheNing Hu
Quoted 13 lines · Junio C Hamano <[email protected]> 于2021年3月23日周二 下午2:19写道:
Quoted 9 lines · Christian Couder
If you want nothing to happen when $ARG isn't set, you can change the config option to something like:
$ git config trailer.sign.command "NAME='\$ARG'; test -n \"\$NAME\" && git log --author=\"\$NAME\" -1 --format='format:%aN <%aE>' || true"(This is because it looks like $ARG is replaced only once with the actual value, which is perhaps a bug. Otherwise something like the following might work:
Quoted 7 lines
I do not know the origin of that code in
trailers.cbut it feels quite confused and error prone to use textual replacement withstrbuf_replace(). Why doesn't the code, which knows it will use shell to execute the command line given by the end user in the configuration, to just export ARG as an environment variable and be done with it? It would also avoid quoting problem etc.
Quoted 1 line
Maybe like this?
Code is not an important part. We should think through ramifications of making (and not making) such a change first.
Re: [PATCH v13] [GSOC] commit: add --trailer option
Quoted 4 lines
Quoted 1 line
Maybe like this?
Code is not an important part. We should think through ramifications of making (and not making) such a change first.
Sorry for without careful consideration.
Thank for this valuable suggestion.
Re: [PATCH v13] [GSOC] commit: add --trailer option
In reply to ZheNing HuQuoted 5 lines · ZheNing Hu
2.
git interpret-trailers --in-placeseem like work on git top-dir, If I am in a sub-dirband I want to change a file such asd.c, then I must usegit interpret-trailers --in-place b/d.cto add some trailers.
What happens without --in-place? Are the input files read correctly?
Quoted 5 lines
I think the original intention of
--in-placeis to modify a file similar to "$COMMIT_MSG_FILE", so make it run at top-dir, but this is not reflected in the git documentation. This at least confuses people who use this option for the first time. Is it worth modifying? Or is there something wrong with the design of--in-place?
I haven't checked but there is perhaps a bug increate_in_place_tempfile() in "trailer.c".
Re: [PATCH v13] [GSOC] commit: add --trailer option
Quoted 10 lines · Christian Couder <[email protected]> 于2021年3月23日周二 上午5:55写道:
Quoted 5 lines · ZheNing Hu
2.
git interpret-trailers --in-placeseem like work on git top-dir, If I am in a sub-dirband I want to change a file such asd.c, then I must usegit interpret-trailers --in-place b/d.cto add some trailers.What happens without --in-place? Are the input files read correctly?
It's still wrong.
the git die() in read_input_file of "trailer.c".
Quoted 9 lines
Quoted 6 lines
I think the original intention of
--in-placeis to modify a file similar to "$COMMIT_MSG_FILE", so make it run at top-dir, but this is not reflected in the git documentation. This at least confuses people who use this option for the first time. Is it worth modifying? Or is there something wrong with the design of--in-place?I haven't checked but there is perhaps a bug in
create_in_place_tempfile()in "trailer.c".
I haven't check finished. But I think it may do something like chdir().
Thanks.
PATCH v14 1/1 commit: add --trailer option
In reply to ZheNing Hu via GitGitGadgetFrom: ZheNing Hu <[email protected]>
Historically, Git has supported the 'Signed-off-by' commit trailer using the '--signoff' and the '-s' option from the command line. But users may need to provide other trailer information from the command line such as "Helped-by", "Reported-by", "Mentored-by",
Now implement a new --trailer <token>[(=|:)<value>] option to pass other trailers to interpret-trailers and insert them into commit messages.
---
[GSOC] commit: add --trailer option
commit --trailer connecting to the interpret-trailers backend, which can directly generate trailers similar to "Signed-off-by". Hope this will make it easier for programmers and maintainers :)
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-901%2Fadlternative%2Fcommit-with-multiple-signatures-v14
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-901/adlternative/commit-with-multiple-signatures-v14
Pull-Request: https://github.com/gitgitgadget/git/pull/901
Range-diff vs v13:
1: 98b0c470e141 ! 1: bb36af7c4827 [GSOC] commit: add --trailer option
@@ Commit message
messages.
Signed-off-by: ZheNing Hu <[email protected]>
- Reported-by:
## Documentation/git-commit.txt ##
@@ Documentation/git-commit.txt: SYNOPSIS
@@ t/t7502-commit-porcelain.sh: test_expect_success 'sign off' '
+ EOF
+ git -c trailer.report.key="Reported-by: " \
+ -c trailer.report.ifexists="replace" \
-+ -c trailer.report.command="git log --author=\"\$ARG\" -1 \
-+ --format=\"format:%aN <%aE>\"" \
++ -c trailer.report.command="NAME=\"\$ARG\"; test -n \"\$NAME\" && \
++ git log --author=\"\$NAME\" -1 --format=\"format:%aN <%aE>\" || true" \
+ commit --trailer "report = author" --amend &&
+ git cat-file commit HEAD >commit.msg &&
+ sed -e "1,/^\$/d" commit.msg >actual &&Documentation/git-commit.txt | 14 +- builtin/commit.c | 22 +++ t/t7502-commit-porcelain.sh | 312 +++++++++++++++++++++++++++++++++++ 3 files changed, 347 insertions(+), 1 deletion(-)
Documentation/git-commit.txt +13 -1
@@ -14,7 +14,8 @@ SYNOPSIS [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] - [-S[<keyid>]] [--] [<pathspec>...] + [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]] + [--] [<pathspec>...] DESCRIPTION -----------
@@ -166,6 +167,17 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. include::signoff-option.txt[] +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <[email protected]>" --trailer "Helped-by:C O Mitter \ + <[email protected]>"` will add the "Signed-off-by" trailer + and the "Helped-by" trailer to the commit message.) + The `trailer.*` configuration variables + (linkgit:git-interpret-trailers[1]) can be used to define if + a duplicated trailer is omitted, where in the run of trailers + each trailer would appear, and other details. + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks.
builtin/commit.c +22 -0
@@ -113,6 +113,7 @@ static int config_commit_verbose = -1; /* unspecified */static int no_post_rewrite, allow_empty_message, pathspec_file_nul;static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;static char *sign_commit, *pathspec_from_file; +static struct strvec trailer_args =STRVEC_INIT ;/* * The default commit message cleanup mode will remove the lines
@@ -131,6 +132,14 @@ static struct strbuf message = STRBUF_INIT;static enum wt_status_format status_format =STATUS_FORMAT_UNSPECIFIED ; +static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +BUG_ON_OPT_NEG (unset); + +strvec_pushl (&trailer_args,"--trailer" , arg,NULL ); +return 0 ; +} +static int opt_parse_porcelain (const struct option *opt,const char *arg,int unset) {enum wt_status_format *value = (enum wt_status_format *)opt->value;
@@ -958,6 +967,18 @@ static int prepare_to_commit(const char *index_file, const char *prefix,fclose (s->fp); +if (trailer_args.nr) { +struct child_process run_trailer =CHILD_PROCESS_INIT ; + +strvec_pushl (&run_trailer.args,"interpret-trailers" , +"--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)) +die (_ ("unable to pass trailers to --trailers" )); +strvec_clear (&trailer_args); + } +/* * Reject an attempt to record a non-merge empty commit without * explicit --allow-empty. In the cherry-pick case, it may be
@@ -1507,6 +1528,7 @@ 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_ ("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 +312 -0
324 lines not on this page · raw message
base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945
Signature · 1 line
gitgitgadget
Re: [PATCH v4] [GSOC] commit: add --trailer option
In reply to ZheNing Hu via GitGitGadget"ZheNing Hu via GitGitGadget" <[email protected]> writes:
One thing I forgot to mention.
builtin/commit.c static struct strbuf message = STRBUF_INIT; · line 140
Quoted 5 lines
builtin/commit.c +5
-0+static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +if (unset) { +strvec_clear (&run_trailer.args); +return -1 ;
What input is this part of the code designed to handle, and what outcome does it want to show to the user?
Does the test added in this patch cover this codepath, where unset is true?
I think this codepath is reached when the command line says "--no-trailer", and I am guessing that by clearing the code wants to say "ignore the accumulated trailers and start accumulating afresh", i.e.
git commit --trailer='T1: V1' --trailer='T2: V2' \ --no-trailer \ --trailer='T3: V3'
would want to add only the "T3: V3" trailer; which is a sensible design, but I do not think returning -1 would be compatible with that design.
If on the other hand the code wants to say "--no-trailer is a command line error", then using PARSE_OPT_NONEG to let the parse-options API issue an error message and die would be more appropriate. That is an often used pattern for an option that can appear on the command line only once without accumulating, which may be less appropriate for the "--trailer", though.
Quoted 4 lines
builtin/commit.c +4
-0+ } +strvec_pushl (&run_trailer.args,"--trailer" , arg,NULL ); +return 0 ; +}
Re: [PATCH v4] [GSOC] commit: add --trailer option
Quoted 30 lines · Junio C Hamano <[email protected]> 于2021年3月15日周一 下午12:38写道:
"ZheNing Hu via GitGitGadget" <[email protected]> writes:
One thing I forgot to mention.
builtin/commit.c static struct strbuf message = STRBUF_INIT; · line 140
Quoted 5 lines
builtin/commit.c +5
-0+static int opt_pass_trailer (const struct option *opt,const char *arg,int unset) +{ +if (unset) { +strvec_clear (&run_trailer.args); +return -1 ;What input is this part of the code designed to handle, and what outcome does it want to show to the user?
Does the test added in this patch cover this codepath, where unset is true?
I think this codepath is reached when the command line says "--no-trailer", and I am guessing that by clearing the code wants to say "ignore the accumulated trailers and start accumulating afresh", i.e.
git commit --trailer='T1: V1' --trailer='T2: V2' \ --no-trailer \ --trailer='T3: V3'would want to add only the "T3: V3" trailer; which is a sensible design, but I do not think returning -1 would be compatible with that design.
Quoted 7 lines
If on the other hand the code wants to say "--no-trailer is a command line error", then using
PARSE_OPT_NONEGto let the parse-options API issue an error message and die would be more appropriate. That is an often used pattern for an option that can appear on the command line only once without accumulating, which may be less appropriate for the "--trailer", though.
As you said, what I want to express is "--no-trailer is acommand line error". --no-trailer may don't have any big benefits for users.
I will follow you suggections.
Quoted 5 lines
Quoted 4 lines
builtin/commit.c +4
-0+ } +strvec_pushl (&run_trailer.args,"--trailer" , arg,NULL ); +return 0 ; +}