{"thread":{"id":"45726","subject":"[PATCH v4 0/3] rebase: --signoff support","startedAt":"2017-04-18T09:30:09Z","lastAt":"2017-04-19T03:44:08Z","messageCount":5,"participants":["Giuseppe Bilotta","Junio C Hamano"],"isPatch":true,"patchVersion":4,"patchTotal":3},"messages":[{"id":"317089","messageId":"20170418092905.20097-1-giuseppe.bilotta@gmail.com","threadId":"45726","inReplyTo":null,"subject":"[PATCH v4 0/3] rebase: --signoff support","fromName":"Giuseppe Bilotta","fromEmail":"giuseppe.bilotta@gmail.com","sentAt":"2017-04-18T09:29:02Z","receivedAt":"2017-04-18T09:30:09Z","isPatch":true,"sender":{"key":"giuseppe.bilotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1464?v=4"},"body":"Allow signing off a whole patchset by rebasing it with the `--signoff`\noption, which is simply passed through to `git am`.\n\nChanges since v3:\n\n* --no-signoff is actually accepted;\n* the paragraph documenting --signoff is now in the correct place and\n  it mentions explicitly that the option is not compatible with\ninteractive mode.\n\nThe patchset is also available in the git repository at:\n\n  git://git.oblomov.eu/git rebase-signoff\n\n(Unrelated note: it just occurred to me while preparing this cover\nletter that it would be nice if there was a way to combine `format-patch\n--cover-letter` and `request-pull`.)\n\nSome work about extending --signoff support to interactive rebases is\nunderway in the `rebase-signoff-ext` branch, but there's a lot of\ncorner cases to test and work-out, so I guess that'll be fore some\nother time.\n\nGiuseppe Bilotta (3):\n  builtin/am: obey --signoff also when --rebasing\n  builtin/am: fold am_signoff() into am_append_signoff()\n  rebase: pass --[no-]signoff option to git am\n\n Documentation/git-rebase.txt |  5 +++++\n builtin/am.c                 | 39 +++++++++++++++++--------------------\n git-rebase.sh                |  3 ++-\n t/t3428-rebase-signoff.sh    | 46 ++++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 71 insertions(+), 22 deletions(-)\n create mode 100755 t/t3428-rebase-signoff.sh\n\n-- \n2.12.2.820.g78c033c3a1.dirty\n\n"},{"id":"317090","messageId":"20170418092905.20097-2-giuseppe.bilotta@gmail.com","threadId":"45726","inReplyTo":"20170418092905.20097-1-giuseppe.bilotta@gmail.com","subject":"[PATCH v4 1/3] builtin/am: obey --signoff also when --rebasing","fromName":"Giuseppe Bilotta","fromEmail":"giuseppe.bilotta@gmail.com","sentAt":"2017-04-18T09:29:03Z","receivedAt":"2017-04-18T09:30:12Z","isPatch":true,"sender":{"key":"giuseppe.bilotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1464?v=4"},"body":"Signoff is handled in parse_mail(), but not in parse_mail_rebasing(),\nsince the latter is only used when git-rebase calls git-am with the\n--rebasing option, and --signoff is never passed in this case.\n\nIn order to introduce (in the upcoming commits) support for `git-rebase\n--signoff`, we must make gi-am obey it also in the rebase case. This is\ntrivially fixed by moving the conditional addition of the signoff from\nparse_mail() to the caller am_run(), after either of the parse_mail*()\nfunctions were called.\n\nSigned-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>\n---\n builtin/am.c | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex f7a7a971fb..d072027b5a 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1321,9 +1321,6 @@ static int parse_mail(struct am_state *state, const char *mail)\n \tstrbuf_addbuf(&msg, &mi.log_message);\n \tstrbuf_stripspace(&msg, 0);\n \n-\tif (state->signoff)\n-\t\tam_signoff(&msg);\n-\n \tassert(!state->author_name);\n \tstate->author_name = strbuf_detach(&author_name, NULL);\n \n@@ -1848,6 +1845,9 @@ static void am_run(struct am_state *state, int resume)\n \t\t\tif (skip)\n \t\t\t\tgoto next; /* mail should be skipped */\n \n+\t\t\tif (state->signoff)\n+\t\t\t\tam_append_signoff(state);\n+\n \t\t\twrite_author_script(state);\n \t\t\twrite_commit_msg(state);\n \t\t}\n-- \n2.12.2.820.g78c033c3a1.dirty\n\n"},{"id":"317091","messageId":"20170418092905.20097-3-giuseppe.bilotta@gmail.com","threadId":"45726","inReplyTo":"20170418092905.20097-1-giuseppe.bilotta@gmail.com","subject":"[PATCH v4 2/3] builtin/am: fold am_signoff() into am_append_signoff()","fromName":"Giuseppe Bilotta","fromEmail":"giuseppe.bilotta@gmail.com","sentAt":"2017-04-18T09:29:04Z","receivedAt":"2017-04-18T09:30:26Z","isPatch":true,"sender":{"key":"giuseppe.bilotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1464?v=4"},"body":"There are no more direct calls to am_signoff(), so we can fold its\nlogic  in am_append_signoff().\n\n(This is done in a separate commit rather than in the previous one, to\nmake it easier to revert this specific change if additional calls are\never introduced.)\n\nSigned-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>\n---\n builtin/am.c | 33 +++++++++++++++------------------\n 1 file changed, 15 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex d072027b5a..b29f885e41 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1181,42 +1181,39 @@ static void NORETURN die_user_resolve(const struct am_state *state)\n \texit(128);\n }\n \n-static void am_signoff(struct strbuf *sb)\n+/**\n+ * Appends signoff to the \"msg\" field of the am_state.\n+ */\n+static void am_append_signoff(struct am_state *state)\n {\n \tchar *cp;\n \tstruct strbuf mine = STRBUF_INIT;\n+\tstruct strbuf sb = STRBUF_INIT;\n \n-\t/* Does it end with our own sign-off? */\n+\tstrbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);\n+\n+\t/* our sign-off */\n \tstrbuf_addf(&mine, \"\\n%s%s\\n\",\n \t\t    sign_off_header,\n \t\t    fmt_name(getenv(\"GIT_COMMITTER_NAME\"),\n \t\t\t     getenv(\"GIT_COMMITTER_EMAIL\")));\n-\tif (mine.len < sb->len &&\n-\t    !strcmp(mine.buf, sb->buf + sb->len - mine.len))\n+\n+\t/* Does sb end with it already? */\n+\tif (mine.len < sb.len &&\n+\t    !strcmp(mine.buf, sb.buf + sb.len - mine.len))\n \t\tgoto exit; /* no need to duplicate */\n \n \t/* Does it have any Signed-off-by: in the text */\n-\tfor (cp = sb->buf;\n+\tfor (cp = sb.buf;\n \t     cp && *cp && (cp = strstr(cp, sign_off_header)) != NULL;\n \t     cp = strchr(cp, '\\n')) {\n-\t\tif (sb->buf == cp || cp[-1] == '\\n')\n+\t\tif (sb.buf == cp || cp[-1] == '\\n')\n \t\t\tbreak;\n \t}\n \n-\tstrbuf_addstr(sb, mine.buf + !!cp);\n+\tstrbuf_addstr(&sb, mine.buf + !!cp);\n exit:\n \tstrbuf_release(&mine);\n-}\n-\n-/**\n- * Appends signoff to the \"msg\" field of the am_state.\n- */\n-static void am_append_signoff(struct am_state *state)\n-{\n-\tstruct strbuf sb = STRBUF_INIT;\n-\n-\tstrbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);\n-\tam_signoff(&sb);\n \tstate->msg = strbuf_detach(&sb, &state->msg_len);\n }\n \n-- \n2.12.2.820.g78c033c3a1.dirty\n\n"},{"id":"317092","messageId":"20170418092905.20097-4-giuseppe.bilotta@gmail.com","threadId":"45726","inReplyTo":"20170418092905.20097-1-giuseppe.bilotta@gmail.com","subject":"[PATCH v4 3/3] rebase: pass --[no-]signoff option to git am","fromName":"Giuseppe Bilotta","fromEmail":"giuseppe.bilotta@gmail.com","sentAt":"2017-04-18T09:29:05Z","receivedAt":"2017-04-18T09:30:30Z","isPatch":true,"sender":{"key":"giuseppe.bilotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1464?v=4"},"body":"This makes it easy to sign off a whole patchset before submission.\n\nSigned-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>\n---\n Documentation/git-rebase.txt |  5 +++++\n git-rebase.sh                |  3 ++-\n t/t3428-rebase-signoff.sh    | 46 ++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 53 insertions(+), 1 deletion(-)\n create mode 100755 t/t3428-rebase-signoff.sh\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 67d48e6883..53f4e14444 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -370,6 +370,11 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`.\n \tof the rebased commits (see linkgit:git-am[1]).\n \tIncompatible with the --interactive option.\n \n+--signoff::\n+\tThis flag is passed to 'git am' to sign off all the rebased\n+\tcommits (see linkgit:git-am[1]). Incompatible with the\n+\t--interactive option.\n+\n -i::\n --interactive::\n \tMake a list of the commits which are about to be rebased.  Let the\ndiff --git a/git-rebase.sh b/git-rebase.sh\nindex 48d7c5ded4..db1deed846 100755\n--- a/git-rebase.sh\n+++ b/git-rebase.sh\n@@ -34,6 +34,7 @@ root!              rebase all reachable commits up to the root(s)\n autosquash         move commits that begin with squash!/fixup! under -i\n committer-date-is-author-date! passed to 'git am'\n ignore-date!       passed to 'git am'\n+signoff            passed to 'git am'\n whitespace=!       passed to 'git apply'\n ignore-whitespace! passed to 'git apply'\n C=!                passed to 'git apply'\n@@ -321,7 +322,7 @@ do\n \t--ignore-whitespace)\n \t\tgit_am_opt=\"$git_am_opt $1\"\n \t\t;;\n-\t--committer-date-is-author-date|--ignore-date)\n+\t--committer-date-is-author-date|--ignore-date|--signoff|--no-signoff)\n \t\tgit_am_opt=\"$git_am_opt $1\"\n \t\tforce_rebase=t\n \t\t;;\ndiff --git a/t/t3428-rebase-signoff.sh b/t/t3428-rebase-signoff.sh\nnew file mode 100755\nindex 0000000000..2afb564701\n--- /dev/null\n+++ b/t/t3428-rebase-signoff.sh\n@@ -0,0 +1,46 @@\n+#!/bin/sh\n+\n+test_description='git rebase --signoff\n+\n+This test runs git rebase --signoff and make sure that it works.\n+'\n+\n+. ./test-lib.sh\n+\n+# A simple file to commit\n+cat >file <<EOF\n+a\n+EOF\n+\n+# Expected commit message after rebase --signoff\n+cat >expected-signed <<EOF\n+first\n+\n+Signed-off-by: $(git var GIT_COMMITTER_IDENT | sed -e \"s/>.*/>/\")\n+EOF\n+\n+# Expected commit message after rebase without --signoff (or with --no-signoff)\n+cat >expected-unsigned <<EOF\n+first\n+EOF\n+\n+\n+# We configure an alias to do the rebase --signoff so that\n+# on the next subtest we can show that --no-signoff overrides the alias\n+test_expect_success 'rebase --signoff adds a sign-off line' '\n+\tgit commit --allow-empty -m \"Initial empty commit\" &&\n+\tgit add file && git commit -m first &&\n+\tgit config alias.rbs \"rebase --signoff\" &&\n+\tgit rbs HEAD^ &&\n+\tgit cat-file commit HEAD | sed -e \"1,/^\\$/d\" > actual &&\n+\ttest_cmp expected-signed actual\n+'\n+\n+test_expect_success 'rebase --no-signoff does not add a sign-off line' '\n+\tgit commit --amend -m \"first\" &&\n+\tgit rbs --no-signoff HEAD^ &&\n+\tgit cat-file commit HEAD | sed -e \"1,/^\\$/d\" > actual &&\n+\ttest_cmp expected-unsigned actual\n+'\n+\n+test_done\n-- \n2.12.2.820.g78c033c3a1.dirty\n\n"},{"id":"317183","messageId":"xmqqshl5awp0.fsf@gitster.mtv.corp.google.com","threadId":"45726","inReplyTo":"20170418092905.20097-1-giuseppe.bilotta@gmail.com","subject":"Re: [PATCH v4 0/3] rebase: --signoff support","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-04-19T03:43:55Z","receivedAt":"2017-04-19T03:44:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Giuseppe Bilotta <giuseppe.bilotta@gmail.com> writes:\n\n> Some work about extending --signoff support to interactive rebases is\n> underway in the `rebase-signoff-ext` branch, but there's a lot of\n> corner cases to test and work-out, so I guess that'll be fore some\n> other time.\n\nYup, that is fine.\n\nWill queue.  Thanks.\n"}]}