Skip to content

Commit 768c7cb

Browse files
committed
Merge branch 'gb/rebase-signoff'
"git rebase" learns "--signoff" option. * gb/rebase-signoff: rebase: pass --[no-]signoff option to git am builtin/am: fold am_signoff() into am_append_signoff() builtin/am: honor --signoff also when --rebasing
2 parents e2cb6ab + 9f79524 commit 768c7cb

File tree

4 files changed

+71
-22
lines changed

4 files changed

+71
-22
lines changed

Documentation/git-rebase.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,11 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`.
370370
of the rebased commits (see linkgit:git-am[1]).
371371
Incompatible with the --interactive option.
372372

373+
--signoff::
374+
This flag is passed to 'git am' to sign off all the rebased
375+
commits (see linkgit:git-am[1]). Incompatible with the
376+
--interactive option.
377+
373378
-i::
374379
--interactive::
375380
Make a list of the commits which are about to be rebased. Let the

builtin/am.c

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,42 +1185,39 @@ static void NORETURN die_user_resolve(const struct am_state *state)
11851185
exit(128);
11861186
}
11871187

1188-
static void am_signoff(struct strbuf *sb)
1188+
/**
1189+
* Appends signoff to the "msg" field of the am_state.
1190+
*/
1191+
static void am_append_signoff(struct am_state *state)
11891192
{
11901193
char *cp;
11911194
struct strbuf mine = STRBUF_INIT;
1195+
struct strbuf sb = STRBUF_INIT;
11921196

1193-
/* Does it end with our own sign-off? */
1197+
strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);
1198+
1199+
/* our sign-off */
11941200
strbuf_addf(&mine, "\n%s%s\n",
11951201
sign_off_header,
11961202
fmt_name(getenv("GIT_COMMITTER_NAME"),
11971203
getenv("GIT_COMMITTER_EMAIL")));
1198-
if (mine.len < sb->len &&
1199-
!strcmp(mine.buf, sb->buf + sb->len - mine.len))
1204+
1205+
/* Does sb end with it already? */
1206+
if (mine.len < sb.len &&
1207+
!strcmp(mine.buf, sb.buf + sb.len - mine.len))
12001208
goto exit; /* no need to duplicate */
12011209

12021210
/* Does it have any Signed-off-by: in the text */
1203-
for (cp = sb->buf;
1211+
for (cp = sb.buf;
12041212
cp && *cp && (cp = strstr(cp, sign_off_header)) != NULL;
12051213
cp = strchr(cp, '\n')) {
1206-
if (sb->buf == cp || cp[-1] == '\n')
1214+
if (sb.buf == cp || cp[-1] == '\n')
12071215
break;
12081216
}
12091217

1210-
strbuf_addstr(sb, mine.buf + !!cp);
1218+
strbuf_addstr(&sb, mine.buf + !!cp);
12111219
exit:
12121220
strbuf_release(&mine);
1213-
}
1214-
1215-
/**
1216-
* Appends signoff to the "msg" field of the am_state.
1217-
*/
1218-
static void am_append_signoff(struct am_state *state)
1219-
{
1220-
struct strbuf sb = STRBUF_INIT;
1221-
1222-
strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);
1223-
am_signoff(&sb);
12241221
state->msg = strbuf_detach(&sb, &state->msg_len);
12251222
}
12261223

@@ -1325,9 +1322,6 @@ static int parse_mail(struct am_state *state, const char *mail)
13251322
strbuf_addbuf(&msg, &mi.log_message);
13261323
strbuf_stripspace(&msg, 0);
13271324

1328-
if (state->signoff)
1329-
am_signoff(&msg);
1330-
13311325
assert(!state->author_name);
13321326
state->author_name = strbuf_detach(&author_name, NULL);
13331327

@@ -1852,6 +1846,9 @@ static void am_run(struct am_state *state, int resume)
18521846
if (skip)
18531847
goto next; /* mail should be skipped */
18541848

1849+
if (state->signoff)
1850+
am_append_signoff(state);
1851+
18551852
write_author_script(state);
18561853
write_commit_msg(state);
18571854
}

git-rebase.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ root! rebase all reachable commits up to the root(s)
3434
autosquash move commits that begin with squash!/fixup! under -i
3535
committer-date-is-author-date! passed to 'git am'
3636
ignore-date! passed to 'git am'
37+
signoff passed to 'git am'
3738
whitespace=! passed to 'git apply'
3839
ignore-whitespace! passed to 'git apply'
3940
C=! passed to 'git apply'
@@ -321,7 +322,7 @@ do
321322
--ignore-whitespace)
322323
git_am_opt="$git_am_opt $1"
323324
;;
324-
--committer-date-is-author-date|--ignore-date)
325+
--committer-date-is-author-date|--ignore-date|--signoff|--no-signoff)
325326
git_am_opt="$git_am_opt $1"
326327
force_rebase=t
327328
;;

t/t3428-rebase-signoff.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/bin/sh
2+
3+
test_description='git rebase --signoff
4+
5+
This test runs git rebase --signoff and make sure that it works.
6+
'
7+
8+
. ./test-lib.sh
9+
10+
# A simple file to commit
11+
cat >file <<EOF
12+
a
13+
EOF
14+
15+
# Expected commit message after rebase --signoff
16+
cat >expected-signed <<EOF
17+
first
18+
19+
Signed-off-by: $(git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/")
20+
EOF
21+
22+
# Expected commit message after rebase without --signoff (or with --no-signoff)
23+
cat >expected-unsigned <<EOF
24+
first
25+
EOF
26+
27+
28+
# We configure an alias to do the rebase --signoff so that
29+
# on the next subtest we can show that --no-signoff overrides the alias
30+
test_expect_success 'rebase --signoff adds a sign-off line' '
31+
git commit --allow-empty -m "Initial empty commit" &&
32+
git add file && git commit -m first &&
33+
git config alias.rbs "rebase --signoff" &&
34+
git rbs HEAD^ &&
35+
git cat-file commit HEAD | sed -e "1,/^\$/d" > actual &&
36+
test_cmp expected-signed actual
37+
'
38+
39+
test_expect_success 'rebase --no-signoff does not add a sign-off line' '
40+
git commit --amend -m "first" &&
41+
git rbs --no-signoff HEAD^ &&
42+
git cat-file commit HEAD | sed -e "1,/^\$/d" > actual &&
43+
test_cmp expected-unsigned actual
44+
'
45+
46+
test_done

0 commit comments

Comments
 (0)