commit --amend -S: strip existing gpgsig headers
Any existing commit signature was made against the contents of the old commit, including its committer date that is about to change, and will become invalid by amending it. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano committed
Jan 5, 2012 at 10:54 UTC
c871a1d17b8433d98df59b03da5538f10c4ae52c
4 files changed
+36
-8
builtin/commit.c
+2
-1
@@ -1494,7 +1494,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
1494
}
1495
1496
if (amend) {
1497
- extra = read_commit_extra_headers(current_head);
1497
+ const char *exclude_gpgsig[2] = { "gpgsig", NULL };
1498
+ extra = read_commit_extra_headers(current_head, exclude_gpgsig);
1499
} else {
1500
struct commit_extra_header **tail = &extra;
1501
append_merge_tag_headers(parents, &tail);
commit.c
+22
-4
@@ -981,14 +981,15 @@ static void add_extra_header(struct strbuf *buffer,
981
strbuf_addch(buffer, '\n');
982
}
983
984
-struct commit_extra_header *read_commit_extra_headers(struct commit *commit)
984
+struct commit_extra_header *read_commit_extra_headers(struct commit *commit,
985
+ const char **exclude)
986
{
987
struct commit_extra_header *extra = NULL;
988
unsigned long size;
989
enum object_type type;
990
char *buffer = read_sha1_file(commit->object.sha1, &type, &size);
991
if (buffer && type == OBJ_COMMIT)
991
- extra = read_commit_extra_header_lines(buffer, size);
992
+ extra = read_commit_extra_header_lines(buffer, size, exclude);
993
free(buffer);
994
return extra;
995
}
@@ -1002,7 +1003,23 @@ static inline int standard_header_field(const char *field, size_t len)
1003
(len == 8 && !memcmp(field, "encoding ", 9)));
1004
}
1005
1005
-struct commit_extra_header *read_commit_extra_header_lines(const char *buffer, size_t size)
1006
+static int excluded_header_field(const char *field, size_t len, const char **exclude)
1007
+{
1008
+ if (!exclude)
1009
+ return 0;
1010
+
1011
+ while (*exclude) {
1012
+ size_t xlen = strlen(*exclude);
1013
+ if (len == xlen &&
1014
+ !memcmp(field, *exclude, xlen) && field[xlen] == ' ')
1015
+ return 1;
1016
+ exclude++;
1017
+ }
1018
+ return 0;
1019
+}
1020
+
1021
+struct commit_extra_header *read_commit_extra_header_lines(const char *buffer, size_t size,
1022
+ const char **exclude)
1023
{
1024
struct commit_extra_header *extra = NULL, **tail = &extra, *it = NULL;
1025
const char *line, *next, *eof, *eob;
@@ -1028,7 +1045,8 @@ struct commit_extra_header *read_commit_extra_header_lines(const char *buffer, s
1045
if (next <= eof)
1046
eof = next;
1047
1031
- if (standard_header_field(line, eof - line))
1048
+ if (standard_header_field(line, eof - line) ||
1049
+ excluded_header_field(line, eof - line, exclude))
1050
continue;
1051
1052
it = xcalloc(1, sizeof(*it));
commit.h
+2
-2
@@ -200,8 +200,8 @@ extern int commit_tree_extended(const char *msg, unsigned char *tree,
200
const char *author, const char *sign_commit,
201
struct commit_extra_header *);
202
203
-extern struct commit_extra_header *read_commit_extra_headers(struct commit *);
204
-extern struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len);
203
+extern struct commit_extra_header *read_commit_extra_headers(struct commit *, const char **);
204
+extern struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **);
205
206
extern void free_commit_extra_headers(struct commit_extra_header *extra);
207
t/t7510-signed-commit.sh
+10
-1
@@ -24,7 +24,8 @@ test_expect_success GPG 'create signed commits' '
24
echo 4 >file && test_tick && git commit -a -m "fourth unsigned" &&
25
git tag fourth-unsigned &&
26
27
- test_tick && git commit --amend -S -m "fourth signed"
27
+ test_tick && git commit --amend -S -m "fourth signed" &&
28
+ git tag fourth-signed
29
'
30
31
test_expect_success GPG 'show signatures' '
@@ -68,4 +69,12 @@ test_expect_success GPG 'detect fudged signature with NUL' '
69
! grep "Good signature from" actual2
70
'
71
72
+test_expect_success GPG 'amending already signed commit' '
73
+ git checkout fourth-signed^0 &&
74
+ git commit --amend -S --no-edit &&
75
+ git show -s --show-signature HEAD >actual &&
76
+ grep "Good signature from" actual &&
77
+ ! grep "BAD signature from" actual
78
+'
79
+
80
test_done