Hi Junio, On Thu, 18 Feb 2021 at 01:20, Junio C Hamano <gitster@xxxxxxxxx> wrote: [...] > The second one, even with s|HEAD|HEAD~3| is even less clear. > Without the "-m", the resulting commit will have the subject that > begins with !amend but the log message body is taken from the given > commit, but with "-m", what happens? Does a single-liner 'clever > commit message' _replace_ the log message of the named commit, > resulting in an !amend commit that has no message from the original? > Or does 'clever commit message' get _appended_ the log message? > Yes, here it gets _appended_ the log message. I agree this seems a bit confusing. > I think we can just remove the "example" from here and explain the > feature well in the end-user facing documentation. > Okay, I will remove it from here and add it in the documentation. > > + if (fixup_message) { > > + /* > > + * check if ':' occurs before '^' or '@', otherwise > > + * fixup_message is a commit reference. > > + */ > > Isn't it that you only intend to parse: > > --fixup > --fixup=amend:<any string that names a commit> > --fixup=<any string that names a commit> > > and later extend it to allow keywords other than "amend"? > Agree. > I can understand that you are trying to avoid getting fooled by > things like > > --fixup='HEAD^{/commit message with a colon : in it}' > > but why special case only ^ and @? This feels brittle (note that I > said "things like", exactly because I do not know if any string that > can name a commit must have "@" or "^" appear before ":" if it is to > have ":" in anywhere, which is what this code assumes). > Okay, I got this... > Instead, you can find the first colon, check for known keywords (or > a string that consists only of alnums to accomodate for future > enhancement), and treat any garbage that happens to have a colon > without the "keyword" as fixup_commit. I.e. something along this > line... > > const char alphas[] = "abcde...xyz"; > size_t kwd_len; > > kwd_len = strspn(fixup_message, alphas); > if (kwd_len && fixup_message[kwd_len] == ':') { > /* found keyword? */ > fixup_message[kwd_len] = '\0'; > if (!strcmp("amend", fixup_message)) { > ... do the amend:<commit> thing ... > #if in-next-step-when-you-add-support-for-reword > } else if (!strcmp("reword", fixup_message)) { > ... do the reword:<commit> thing ... > #endif > } else { > die(_("unknown --fixup=%s:<commit>", > fixup_message)); > } > } else { > /* the entire fixup_message is the commit */ > } > ...Thanks, for pointing this out. Also, in the above method for alnum I think we can initialize an array of alnum[] instead of alphas[]. Or otherwise I was thinking to instead check: if (!isalnum(*c) && *c == ':') i.e to check that first non alnum char in fixup_message is ':' and returning it's position to extract both fixup_prefix and fixup_commit. Will look into it and update in the next revision.