replace: remove signature when using --graft

It could be misleading to keep a signature in a replacement commit, so let's remove it. Note that there should probably be a way to sign the replacement commit created when using --graft, but this can be dealt with in another commit or patch series. Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Christian Couder committed Jul 19, 2014 at 17:01 UTC 0b05ab6f1bfa045f460ad5c40d87ef8c2965bf56
3 files changed +41
builtin/replace.c
+5
@@ -344,6 +344,11 @@ static int create_graft(int argc, const char **argv, int force)
344
345 replace_parents(&buf, argc - 1, &argv[1]);
346
347 + if (remove_signature(&buf)) {
348 + warning(_("the original commit '%s' has a gpg signature."), old_ref);
349 + warning(_("the signature will be removed in the replacement commit!"));
350 + }
351 +
352 if (write_sha1_file(buf.buf, buf.len, commit_type, new))
353 die(_("could not write replacement commit for: '%s'"), old_ref);
354
commit.c
+34
@@ -1178,6 +1178,40 @@ int parse_signed_commit(const struct commit *commit,
1178 return saw_signature;
1179 }
1180
1181 +int remove_signature(struct strbuf *buf)
1182 +{
1183 + const char *line = buf->buf;
1184 + const char *tail = buf->buf + buf->len;
1185 + int in_signature = 0;
1186 + const char *sig_start = NULL;
1187 + const char *sig_end = NULL;
1188 +
1189 + while (line < tail) {
1190 + const char *next = memchr(line, '\n', tail - line);
1191 + next = next ? next + 1 : tail;
1192 +
1193 + if (in_signature && line[0] == ' ')
1194 + sig_end = next;
1195 + else if (starts_with(line, gpg_sig_header) &&
1196 + line[gpg_sig_header_len] == ' ') {
1197 + sig_start = line;
1198 + sig_end = next;
1199 + in_signature = 1;
1200 + } else {
1201 + if (*line == '\n')
1202 + /* dump the whole remainder of the buffer */
1203 + next = tail;
1204 + in_signature = 0;
1205 + }
1206 + line = next;
1207 + }
1208 +
1209 + if (sig_start)
1210 + strbuf_remove(buf, sig_start - buf->buf, sig_end - sig_start);
1211 +
1212 + return sig_start != NULL;
1213 +}
1214 +
1215 static void handle_signed_tag(struct commit *parent, struct commit_extra_header ***tail)
1216 {
1217 struct merge_remote_desc *desc;
commit.h
+2
@@ -332,6 +332,8 @@ struct commit *get_merge_parent(const char *name);
332
333 extern int parse_signed_commit(const struct commit *commit,
334 struct strbuf *message, struct strbuf *signature);
335 +extern int remove_signature(struct strbuf *buf);
336 +
337 extern void print_commit_list(struct commit_list *list,
338 const char *format_cur,
339 const char *format_last);