diff options
-rw-r--r-- | builtin/commit.c | 3 | ||||
-rw-r--r-- | commit.c | 26 | ||||
-rw-r--r-- | commit.h | 4 | ||||
-rwxr-xr-x | t/t7510-signed-commit.sh | 11 |
4 files changed, 36 insertions, 8 deletions
diff --git a/builtin/commit.c b/builtin/commit.c index fa41ec8c87..970a83662a 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1494,7 +1494,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix) } if (amend) { - extra = read_commit_extra_headers(current_head); + const char *exclude_gpgsig[2] = { "gpgsig", NULL }; + extra = read_commit_extra_headers(current_head, exclude_gpgsig); } else { struct commit_extra_header **tail = &extra; append_merge_tag_headers(parents, &tail); @@ -981,14 +981,15 @@ static void add_extra_header(struct strbuf *buffer, strbuf_addch(buffer, '\n'); } -struct commit_extra_header *read_commit_extra_headers(struct commit *commit) +struct commit_extra_header *read_commit_extra_headers(struct commit *commit, + const char **exclude) { struct commit_extra_header *extra = NULL; unsigned long size; enum object_type type; char *buffer = read_sha1_file(commit->object.sha1, &type, &size); if (buffer && type == OBJ_COMMIT) - extra = read_commit_extra_header_lines(buffer, size); + extra = read_commit_extra_header_lines(buffer, size, exclude); free(buffer); return extra; } @@ -1002,7 +1003,23 @@ static inline int standard_header_field(const char *field, size_t len) (len == 8 && !memcmp(field, "encoding ", 9))); } -struct commit_extra_header *read_commit_extra_header_lines(const char *buffer, size_t size) +static int excluded_header_field(const char *field, size_t len, const char **exclude) +{ + if (!exclude) + return 0; + + while (*exclude) { + size_t xlen = strlen(*exclude); + if (len == xlen && + !memcmp(field, *exclude, xlen) && field[xlen] == ' ') + return 1; + exclude++; + } + return 0; +} + +struct commit_extra_header *read_commit_extra_header_lines(const char *buffer, size_t size, + const char **exclude) { struct commit_extra_header *extra = NULL, **tail = &extra, *it = NULL; const char *line, *next, *eof, *eob; @@ -1028,7 +1045,8 @@ struct commit_extra_header *read_commit_extra_header_lines(const char *buffer, s if (next <= eof) eof = next; - if (standard_header_field(line, eof - line)) + if (standard_header_field(line, eof - line) || + excluded_header_field(line, eof - line, exclude)) continue; it = xcalloc(1, sizeof(*it)); @@ -200,8 +200,8 @@ extern int commit_tree_extended(const char *msg, unsigned char *tree, const char *author, const char *sign_commit, struct commit_extra_header *); -extern struct commit_extra_header *read_commit_extra_headers(struct commit *); -extern struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len); +extern struct commit_extra_header *read_commit_extra_headers(struct commit *, const char **); +extern struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **); extern void free_commit_extra_headers(struct commit_extra_header *extra); diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh index 30401ced07..1d3c56fe61 100755 --- a/t/t7510-signed-commit.sh +++ b/t/t7510-signed-commit.sh @@ -24,7 +24,8 @@ test_expect_success GPG 'create signed commits' ' echo 4 >file && test_tick && git commit -a -m "fourth unsigned" && git tag fourth-unsigned && - test_tick && git commit --amend -S -m "fourth signed" + test_tick && git commit --amend -S -m "fourth signed" && + git tag fourth-signed ' test_expect_success GPG 'show signatures' ' @@ -68,4 +69,12 @@ test_expect_success GPG 'detect fudged signature with NUL' ' ! grep "Good signature from" actual2 ' +test_expect_success GPG 'amending already signed commit' ' + git checkout fourth-signed^0 && + git commit --amend -S --no-edit && + git show -s --show-signature HEAD >actual && + grep "Good signature from" actual && + ! grep "BAD signature from" actual +' + test_done |