Skip to content

Commit a852ec7

Browse files
phillipwoodgitster
authored andcommitted
rebase: extend --signoff support
Allow --signoff to be used with --interactive and --merge. In interactive mode only commits marked to be picked, edited or reworded will be signed off. The main motivation for this patch was to allow one to run 'git rebase --exec "make check" --signoff' which is useful when preparing a patch series for publication and is more convenient than doing the signoff with another --exec command. This change also allows --root without --onto to work with --signoff as well (--root with --onto was already supported). Signed-off-by: Phillip Wood <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 56173d2 commit a852ec7

File tree

6 files changed

+72
-9
lines changed

6 files changed

+72
-9
lines changed

Documentation/git-rebase.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,10 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`.
354354
Incompatible with the --interactive option.
355355

356356
--signoff::
357-
This flag is passed to 'git am' to sign off all the rebased
358-
commits (see linkgit:git-am[1]). Incompatible with the
359-
--interactive option.
357+
Add a Signed-off-by: trailer to all the rebased commits. Note
358+
that if `--interactive` is given then only commits marked to be
359+
picked, edited or reworded will have the trailer added. Incompatible
360+
with the `--preserve-merges` option.
360361

361362
-i::
362363
--interactive::

git-rebase--interactive.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ pick_one () {
283283
pick_one_preserving_merges "$@" && return
284284
output eval git cherry-pick $allow_rerere_autoupdate \
285285
${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
286-
"$strategy_args" $empty_args $ff "$@"
286+
$signoff "$strategy_args" $empty_args $ff "$@"
287287

288288
# If cherry-pick dies it leaves the to-be-picked commit unrecorded. Reschedule
289289
# previous task so this commit is not lost.
@@ -524,10 +524,10 @@ do_pick () {
524524
# resolve before manually running git commit --amend then git
525525
# rebase --continue.
526526
git commit --allow-empty --allow-empty-message --amend \
527-
--no-post-rewrite -n -q -C $sha1 &&
527+
--no-post-rewrite -n -q -C $sha1 $signoff &&
528528
pick_one -n $sha1 &&
529529
git commit --allow-empty --allow-empty-message \
530-
--amend --no-post-rewrite -n -q -C $sha1 \
530+
--amend --no-post-rewrite -n -q -C $sha1 $signoff \
531531
${gpg_sign_opt:+"$gpg_sign_opt"} ||
532532
die_with_patch $sha1 "$(eval_gettext "Could not apply \$sha1... \$rest")"
533533
else

git-rebase--merge.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ continue_merge () {
2727
cmt=$(cat "$state_dir/current")
2828
if ! git diff-index --quiet --ignore-submodules HEAD --
2929
then
30-
if ! git commit ${gpg_sign_opt:+"$gpg_sign_opt"} --no-verify -C "$cmt"
30+
if ! git commit ${gpg_sign_opt:+"$gpg_sign_opt"} $signoff --no-verify -C "$cmt"
3131
then
3232
echo "Commit failed, please do not call \"git commit\""
3333
echo "directly, but instead do one of the following: "

git-rebase.sh

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ action=
9090
preserve_merges=
9191
autosquash=
9292
keep_empty=
93+
signoff=
9394
test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
9495
case "$(git config --bool commit.gpgsign)" in
9596
true) gpg_sign_opt=-S ;;
@@ -119,6 +120,10 @@ read_basic_state () {
119120
allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)"
120121
test -f "$state_dir"/gpg_sign_opt &&
121122
gpg_sign_opt="$(cat "$state_dir"/gpg_sign_opt)"
123+
test -f "$state_dir"/signoff && {
124+
signoff="$(cat "$state_dir"/signoff)"
125+
force_rebase=t
126+
}
122127
}
123128

124129
write_basic_state () {
@@ -133,6 +138,7 @@ write_basic_state () {
133138
test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \
134139
"$state_dir"/allow_rerere_autoupdate
135140
test -n "$gpg_sign_opt" && echo "$gpg_sign_opt" > "$state_dir"/gpg_sign_opt
141+
test -n "$signoff" && echo "$signoff" >"$state_dir"/signoff
136142
}
137143

138144
output () {
@@ -328,7 +334,13 @@ do
328334
--ignore-whitespace)
329335
git_am_opt="$git_am_opt $1"
330336
;;
331-
--committer-date-is-author-date|--ignore-date|--signoff|--no-signoff)
337+
--signoff)
338+
signoff=--signoff
339+
;;
340+
--no-signoff)
341+
signoff=
342+
;;
343+
--committer-date-is-author-date|--ignore-date)
332344
git_am_opt="$git_am_opt $1"
333345
force_rebase=t
334346
;;
@@ -458,6 +470,12 @@ then
458470
git_format_patch_opt="$git_format_patch_opt --progress"
459471
fi
460472

473+
if test -n "$signoff"
474+
then
475+
git_am_opt="$git_am_opt $signoff"
476+
force_rebase=t
477+
fi
478+
461479
if test -z "$rebase_root"
462480
then
463481
case "$#" in

sequencer.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ static GIT_PATH_FUNC(rebase_path_rewritten_pending,
127127
static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, "rebase-merge/gpg_sign_opt")
128128
static GIT_PATH_FUNC(rebase_path_orig_head, "rebase-merge/orig-head")
129129
static GIT_PATH_FUNC(rebase_path_verbose, "rebase-merge/verbose")
130+
static GIT_PATH_FUNC(rebase_path_signoff, "rebase-merge/signoff")
130131
static GIT_PATH_FUNC(rebase_path_head_name, "rebase-merge/head-name")
131132
static GIT_PATH_FUNC(rebase_path_onto, "rebase-merge/onto")
132133
static GIT_PATH_FUNC(rebase_path_autostash, "rebase-merge/autostash")
@@ -1605,7 +1606,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
16051606
}
16061607
}
16071608

1608-
if (opts->signoff)
1609+
if (opts->signoff && !is_fixup(command))
16091610
append_signoff(&msgbuf, 0, 0);
16101611

16111612
if (is_rebase_i(opts) && write_author_script(msg.message) < 0)
@@ -2035,6 +2036,11 @@ static int read_populate_opts(struct replay_opts *opts)
20352036
if (file_exists(rebase_path_verbose()))
20362037
opts->verbose = 1;
20372038

2039+
if (file_exists(rebase_path_signoff())) {
2040+
opts->allow_ff = 0;
2041+
opts->signoff = 1;
2042+
}
2043+
20382044
read_strategy_opts(opts, &buf);
20392045
strbuf_release(&buf);
20402046

t/t3428-rebase-signoff.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ cat >file <<EOF
1212
a
1313
EOF
1414

15+
# Expected commit message for initial commit after rebase --signoff
16+
cat >expected-initial-signed <<EOF
17+
Initial empty commit
18+
19+
Signed-off-by: $(git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/")
20+
EOF
21+
1522
# Expected commit message after rebase --signoff
1623
cat >expected-signed <<EOF
1724
first
@@ -43,4 +50,35 @@ test_expect_success 'rebase --no-signoff does not add a sign-off line' '
4350
test_cmp expected-unsigned actual
4451
'
4552

53+
test_expect_success 'rebase --exec --signoff adds a sign-off line' '
54+
test_when_finished "rm exec" &&
55+
git commit --amend -m "first" &&
56+
git rebase --exec "touch exec" --signoff HEAD^ &&
57+
test_path_is_file exec &&
58+
git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
59+
test_cmp expected-signed actual
60+
'
61+
62+
test_expect_success 'rebase --root --signoff adds a sign-off line' '
63+
git commit --amend -m "first" &&
64+
git rebase --root --keep-empty --signoff &&
65+
git cat-file commit HEAD^ | sed -e "1,/^\$/d" >actual &&
66+
test_cmp expected-initial-signed actual &&
67+
git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
68+
test_cmp expected-signed actual
69+
'
70+
71+
test_expect_success 'rebase -i --signoff fails' '
72+
git commit --amend -m "first" &&
73+
git rebase -i --signoff HEAD^ &&
74+
git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
75+
test_cmp expected-signed actual
76+
'
77+
78+
test_expect_success 'rebase -m --signoff fails' '
79+
git commit --amend -m "first" &&
80+
git rebase -m --signoff HEAD^ &&
81+
git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
82+
test_cmp expected-signed actual
83+
'
4684
test_done

0 commit comments

Comments
 (0)