summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/commit.c3
-rw-r--r--commit.c26
-rw-r--r--commit.h4
-rwxr-xr-xt/t7510-signed-commit.sh11
4 files changed, 36 insertions, 8 deletions
diff --git a/builtin/commit.c b/builtin/commit.c
index fa41ec8..970a836 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);
diff --git a/commit.c b/commit.c
index 27c7226..2162a7c 100644
--- a/commit.c
+++ b/commit.c
@@ -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));
diff --git a/commit.h b/commit.h
index 6107648..123aea3 100644
--- a/commit.h
+++ b/commit.h
@@ -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 30401ce..1d3c56f 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