Skip to content

Commit b5e8235

Browse files
pyokagangitster
authored andcommitted
am: let --signoff override --no-signoff
After resolving a conflicting patch, a user may wish to sign off the patch to declare that the patch has been modified. As such, the user will expect that running "git am --signoff --continue" will append the signoff to the commit message. However, the --signoff option is only taken into account during the mail-parsing stage. If the --signoff option is set, then the signoff will be appended to the commit message. Since the mail-parsing stage comes before the patch application stage, the --signoff option, if provided on the command-line when resuming, will have no effect at all. We cannot move the append_signoff() call to the patch application stage as the applypatch-msg hook and interactive mode, which run before patch application, may expect the signoff to be there. Fix this by taking note if the user explictly set the --signoff option on the command-line, and append the signoff to the commit message when resuming if so. Signed-off-by: Paul Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 852a171 commit b5e8235

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

builtin/am.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ enum scissors_type {
9898
SCISSORS_TRUE /* pass --scissors to git-mailinfo */
9999
};
100100

101+
enum signoff_type {
102+
SIGNOFF_FALSE = 0,
103+
SIGNOFF_TRUE = 1,
104+
SIGNOFF_EXPLICIT /* --signoff was set on the command-line */
105+
};
106+
101107
struct am_state {
102108
/* state directory path */
103109
char *dir;
@@ -123,7 +129,7 @@ struct am_state {
123129
int interactive;
124130
int threeway;
125131
int quiet;
126-
int signoff;
132+
int signoff; /* enum signoff_type */
127133
int utf8;
128134
int keep; /* enum keep_type */
129135
int message_id;
@@ -1185,6 +1191,18 @@ static void NORETURN die_user_resolve(const struct am_state *state)
11851191
exit(128);
11861192
}
11871193

1194+
/**
1195+
* Appends signoff to the "msg" field of the am_state.
1196+
*/
1197+
static void am_append_signoff(struct am_state *state)
1198+
{
1199+
struct strbuf sb = STRBUF_INIT;
1200+
1201+
strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);
1202+
append_signoff(&sb, 0, 0);
1203+
state->msg = strbuf_detach(&sb, &state->msg_len);
1204+
}
1205+
11881206
/**
11891207
* Parses `mail` using git-mailinfo, extracting its patch and authorship info.
11901208
* state->msg will be set to the patch message. state->author_name,
@@ -2153,8 +2171,9 @@ int cmd_am(int argc, const char **argv, const char *prefix)
21532171
OPT_BOOL('3', "3way", &state.threeway,
21542172
N_("allow fall back on 3way merging if needed")),
21552173
OPT__QUIET(&state.quiet, N_("be quiet")),
2156-
OPT_BOOL('s', "signoff", &state.signoff,
2157-
N_("add a Signed-off-by line to the commit message")),
2174+
OPT_SET_INT('s', "signoff", &state.signoff,
2175+
N_("add a Signed-off-by line to the commit message"),
2176+
SIGNOFF_EXPLICIT),
21582177
OPT_BOOL('u', "utf8", &state.utf8,
21592178
N_("recode into utf8 (default)")),
21602179
OPT_SET_INT('k', "keep", &state.keep,
@@ -2267,6 +2286,9 @@ int cmd_am(int argc, const char **argv, const char *prefix)
22672286

22682287
if (resume == RESUME_FALSE)
22692288
resume = RESUME_APPLY;
2289+
2290+
if (state.signoff == SIGNOFF_EXPLICIT)
2291+
am_append_signoff(&state);
22702292
} else {
22712293
struct argv_array paths = ARGV_ARRAY_INIT;
22722294
int i;

t/t4153-am-resume-override-opts.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,26 @@ test_expect_success '--no-quiet overrides --quiet' '
6464
test_i18ncmp expected out
6565
'
6666

67+
test_expect_success '--signoff overrides --no-signoff' '
68+
rm -fr .git/rebase-apply &&
69+
git reset --hard &&
70+
git checkout first &&
71+
72+
test_must_fail git am --no-signoff side[12].eml &&
73+
test_path_is_dir .git/rebase-apply &&
74+
echo side1 >file &&
75+
git add file &&
76+
git am --signoff --continue &&
77+
78+
# Applied side1 will be signed off
79+
echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
80+
git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
81+
test_cmp expected actual &&
82+
83+
# Applied side2 will not be signed off
84+
test $(git cat-file commit HEAD | grep -c "Signed-off-by:") -eq 0
85+
'
86+
6787
test_expect_success TTY '--reject overrides --no-reject' '
6888
rm -fr .git/rebase-apply &&
6989
git reset --hard &&

0 commit comments

Comments
 (0)