Merge branch 'pw/am-signoff'

"git am -s" has been taught that some input may end with a trailer
block that is not Signed-off-by: and it should refrain from adding
an extra blank line before adding a new sign-off in such a case.

* pw/am-signoff:
  am: fix signoff when other trailers are present
This commit is contained in:
Junio C Hamano 2017-08-22 10:29:07 -07:00
commit 5c3895dfbd
2 changed files with 64 additions and 45 deletions

View file

@ -1193,34 +1193,10 @@ static void NORETURN die_user_resolve(const struct am_state *state)
*/ */
static void am_append_signoff(struct am_state *state) static void am_append_signoff(struct am_state *state)
{ {
char *cp;
struct strbuf mine = STRBUF_INIT;
struct strbuf sb = STRBUF_INIT; struct strbuf sb = STRBUF_INIT;
strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len); strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);
append_signoff(&sb, 0, 0);
/* our sign-off */
strbuf_addf(&mine, "\n%s%s\n",
sign_off_header,
fmt_name(getenv("GIT_COMMITTER_NAME"),
getenv("GIT_COMMITTER_EMAIL")));
/* Does sb end with it already? */
if (mine.len < sb.len &&
!strcmp(mine.buf, sb.buf + sb.len - mine.len))
goto exit; /* no need to duplicate */
/* Does it have any Signed-off-by: in the text */
for (cp = sb.buf;
cp && *cp && (cp = strstr(cp, sign_off_header)) != NULL;
cp = strchr(cp, '\n')) {
if (sb.buf == cp || cp[-1] == '\n')
break;
}
strbuf_addstr(&sb, mine.buf + !!cp);
exit:
strbuf_release(&mine);
state->msg = strbuf_detach(&sb, &state->msg_len); state->msg = strbuf_detach(&sb, &state->msg_len);
} }

View file

@ -40,6 +40,8 @@ test_expect_success 'setup: messages' '
dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te
feugait nulla facilisi. feugait nulla facilisi.
Reported-by: A N Other <a.n.other@example.com>
EOF EOF
cat >failmail <<-\EOF && cat >failmail <<-\EOF &&
@ -93,7 +95,7 @@ test_expect_success setup '
echo world >>file && echo world >>file &&
git add file && git add file &&
test_tick && test_tick &&
git commit -s -F msg && git commit -F msg &&
git tag second && git tag second &&
git format-patch --stdout first >patch1 && git format-patch --stdout first >patch1 &&
@ -124,8 +126,6 @@ test_expect_success setup '
echo "Date: $GIT_AUTHOR_DATE" && echo "Date: $GIT_AUTHOR_DATE" &&
echo && echo &&
sed -e "1,2d" msg && sed -e "1,2d" msg &&
echo &&
echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" &&
echo "---" && echo "---" &&
git diff-tree --no-commit-id --stat -p second git diff-tree --no-commit-id --stat -p second
} >patch1-stgit.eml && } >patch1-stgit.eml &&
@ -144,8 +144,6 @@ test_expect_success setup '
echo "# Parent $_z40" && echo "# Parent $_z40" &&
cat msg && cat msg &&
echo && echo &&
echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" &&
echo &&
git diff-tree --no-commit-id -p second git diff-tree --no-commit-id -p second
} >patch1-hg.eml && } >patch1-hg.eml &&
@ -470,13 +468,15 @@ test_expect_success 'am --signoff adds Signed-off-by: line' '
git reset --hard && git reset --hard &&
git checkout -b master2 first && git checkout -b master2 first &&
git am --signoff <patch2 && git am --signoff <patch2 &&
printf "%s\n" "$signoff" >expected && {
echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected && printf "third\n\nSigned-off-by: %s <%s>\n\n" \
git cat-file commit HEAD^ | grep "Signed-off-by:" >actual && "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
test_cmp expected actual && cat msg &&
echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected && printf "Signed-off-by: %s <%s>\n\n" \
git cat-file commit HEAD | grep "Signed-off-by:" >actual && "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
test_cmp expected actual } >expected-log &&
git log --pretty=%B -2 HEAD >actual &&
test_cmp expected-log actual
' '
test_expect_success 'am stays in branch' ' test_expect_success 'am stays in branch' '
@ -486,17 +486,60 @@ test_expect_success 'am stays in branch' '
' '
test_expect_success 'am --signoff does not add Signed-off-by: line if already there' ' test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
git format-patch --stdout HEAD^ >patch3 && git format-patch --stdout first >patch3 &&
sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," patch3 >patch4 && git reset --hard first &&
rm -fr .git/rebase-apply && git am --signoff <patch3 &&
git reset --hard && git log --pretty=%B -2 HEAD >actual &&
git checkout HEAD^ && test_cmp expected-log actual
git am --signoff patch4 && '
git cat-file commit HEAD >actual &&
test $(grep -c "^Signed-off-by:" actual) -eq 1 test_expect_success 'am --signoff adds Signed-off-by: if another author is preset' '
NAME="A N Other" &&
EMAIL="a.n.other@example.com" &&
{
printf "third\n\nSigned-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
"$NAME" "$EMAIL" &&
cat msg &&
printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
"$NAME" "$EMAIL"
} >expected-log &&
git reset --hard first &&
GIT_COMMITTER_NAME="$NAME" GIT_COMMITTER_EMAIL="$EMAIL" \
git am --signoff <patch3 &&
git log --pretty=%B -2 HEAD >actual &&
test_cmp expected-log actual
'
test_expect_success 'am --signoff duplicates Signed-off-by: if it is not the last one' '
NAME="A N Other" &&
EMAIL="a.n.other@example.com" &&
{
printf "third\n\nSigned-off-by: %s <%s>\n\
Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
"$NAME" "$EMAIL" \
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
cat msg &&
printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\
Signed-off-by: %s <%s>\n\n" \
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
"$NAME" "$EMAIL" \
"$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
} >expected-log &&
git format-patch --stdout first >patch3 &&
git reset --hard first &&
git am --signoff <patch3 &&
git log --pretty=%B -2 HEAD >actual &&
test_cmp expected-log actual
' '
test_expect_success 'am without --keep removes Re: and [PATCH] stuff' ' test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
git format-patch --stdout HEAD^ >tmp &&
sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," tmp >patch4 &&
git reset --hard HEAD^ &&
git am <patch4 &&
git rev-parse HEAD >expected && git rev-parse HEAD >expected &&
git rev-parse master2 >actual && git rev-parse master2 >actual &&
test_cmp expected actual test_cmp expected actual