Currently, if the s-o-b footer of a commit message contains a
"(cherry picked from ..." line that was added by a previous cherry-pick -x,
it is not recognized as a s-o-b footer and will cause a newline to be
inserted before an additional s-o-b is added.

So, rework ends_rfc2822_footer to recognize the "(cherry picked from ..."
string as part of the footer.  Plus mark the test in t3511 as fixed.

Signed-off-by: Brandon Casey <bca...@nvidia.com>
---
 sequencer.c              | 44 +++++++++++++++++++++++++++++---------------
 t/t3511-cherry-pick-x.sh |  2 +-
 2 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/sequencer.c b/sequencer.c
index 01edec2..27e684c 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -18,6 +18,7 @@
 #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
 
 const char sign_off_header[] = "Signed-off-by: ";
+const char cherry_picked_prefix[] = "(cherry picked from commit ";
 
 static void remove_sequencer_state(void)
 {
@@ -492,7 +493,7 @@ static int do_pick_commit(struct commit *commit, struct 
replay_opts *opts)
                }
 
                if (opts->record_origin) {
-                       strbuf_addstr(&msgbuf, "(cherry picked from commit ");
+                       strbuf_addstr(&msgbuf, cherry_picked_prefix);
                        strbuf_addstr(&msgbuf, 
sha1_to_hex(commit->object.sha1));
                        strbuf_addstr(&msgbuf, ")\n");
                }
@@ -1017,13 +1018,34 @@ int sequencer_pick_revisions(struct replay_opts *opts)
        return pick_commits(todo_list, opts);
 }
 
+static int is_rfc2822_line(const char *buf, int len)
+{
+       int i;
+
+       for (i = 0; i < len; i++) {
+               int ch = buf[i];
+               if (ch == ':')
+                       break;
+               if (isalnum(ch) || (ch == '-'))
+                       continue;
+               return 0;
+       }
+
+       return 1;
+}
+
+static int is_cherry_pick_from_line(const char *buf, int len)
+{
+       return (strlen(cherry_picked_prefix) + 41) <= len &&
+               !prefixcmp(buf, cherry_picked_prefix);
+}
+
 static int ends_rfc2822_footer(struct strbuf *sb, int ignore_footer)
 {
-       int ch;
        int hit = 0;
-       int i, j, k;
+       int i, k;
        int len = sb->len - ignore_footer;
-       int first = 1;
+       int last_was_rfc2822 = 0;
        const char *buf = sb->buf;
 
        for (i = len - 1; i > 0; i--) {
@@ -1040,20 +1062,12 @@ static int ends_rfc2822_footer(struct strbuf *sb, int 
ignore_footer)
                        ; /* do nothing */
                k++;
 
-               if ((buf[i] == ' ' || buf[i] == '\t') && !first)
+               if (last_was_rfc2822 && (buf[i] == ' ' || buf[i] == '\t'))
                        continue;
 
-               first = 0;
-
-               for (j = 0; i + j < len; j++) {
-                       ch = buf[i + j];
-                       if (ch == ':')
-                               break;
-                       if (isalnum(ch) ||
-                           (ch == '-'))
-                               continue;
+               if (!((last_was_rfc2822 = is_rfc2822_line(buf+i, k-i)) ||
+                       is_cherry_pick_from_line(buf+i, k-i)))
                        return 0;
-               }
        }
        return 1;
 }
diff --git a/t/t3511-cherry-pick-x.sh b/t/t3511-cherry-pick-x.sh
index b2098e0..785486e 100755
--- a/t/t3511-cherry-pick-x.sh
+++ b/t/t3511-cherry-pick-x.sh
@@ -63,7 +63,7 @@ test_expect_success 'cherry-pick -s not confused by rfc2822 
continuation line' '
        test_cmp expect actual
 '
 
-test_expect_failure 'cherry-pick treats -s "(cherry picked from..." line as 
part of footer' '
+test_expect_success 'cherry-pick treats -s "(cherry picked from..." line as 
part of footer' '
        pristine_detach initial &&
        git cherry-pick -s rfc2822-cherry-base &&
        cat <<-EOF >expect &&
-- 
1.8.0

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to