summaryrefslogtreecommitdiff
path: root/builtin/fast-import.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/fast-import.c')
-rw-r--r--builtin/fast-import.c106
1 files changed, 96 insertions, 10 deletions
diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index b1d5549815..8714edfc65 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -188,6 +188,9 @@ static int global_argc;
static const char **global_argv;
static const char *global_prefix;
+static enum sign_mode signed_tag_mode = SIGN_VERBATIM;
+static enum sign_mode signed_commit_mode = SIGN_VERBATIM;
+
/* Memory pools */
static struct mem_pool fi_mem_pool = {
.block_alloc = 2*1024*1024 - sizeof(struct mp_block),
@@ -2754,6 +2757,15 @@ static void parse_one_signature(struct signature_data *sig, const char *v)
parse_data(&sig->data, 0, NULL);
}
+static void discard_one_signature(void)
+{
+ struct strbuf data = STRBUF_INIT;
+
+ read_next_command();
+ parse_data(&data, 0, NULL);
+ strbuf_release(&data);
+}
+
static void add_gpgsig_to_commit(struct strbuf *commit_data,
const char *header,
struct signature_data *sig)
@@ -2787,6 +2799,22 @@ static void store_signature(struct signature_data *stored_sig,
}
}
+static void import_one_signature(struct signature_data *sig_sha1,
+ struct signature_data *sig_sha256,
+ const char *v)
+{
+ struct signature_data sig = { NULL, NULL, STRBUF_INIT };
+
+ parse_one_signature(&sig, v);
+
+ if (!strcmp(sig.hash_algo, "sha1"))
+ store_signature(sig_sha1, &sig, "SHA-1");
+ else if (!strcmp(sig.hash_algo, "sha256"))
+ store_signature(sig_sha256, &sig, "SHA-256");
+ else
+ die(_("parse_one_signature() returned unknown hash algo"));
+}
+
static void parse_new_commit(const char *arg)
{
static struct strbuf msg = STRBUF_INIT;
@@ -2819,19 +2847,32 @@ static void parse_new_commit(const char *arg)
if (!committer)
die("Expected committer but didn't get one");
- /* Process signatures (up to 2: one "sha1" and one "sha256") */
while (skip_prefix(command_buf.buf, "gpgsig ", &v)) {
- struct signature_data sig = { NULL, NULL, STRBUF_INIT };
-
- parse_one_signature(&sig, v);
+ switch (signed_commit_mode) {
+
+ /* First, modes that don't need the signature to be parsed */
+ case SIGN_ABORT:
+ die("encountered signed commit; use "
+ "--signed-commits=<mode> to handle it");
+ case SIGN_WARN_STRIP:
+ warning(_("stripping a commit signature"));
+ /* fallthru */
+ case SIGN_STRIP:
+ discard_one_signature();
+ break;
- if (!strcmp(sig.hash_algo, "sha1"))
- store_signature(&sig_sha1, &sig, "SHA-1");
- else if (!strcmp(sig.hash_algo, "sha256"))
- store_signature(&sig_sha256, &sig, "SHA-256");
- else
- BUG("parse_one_signature() returned unknown hash algo");
+ /* Second, modes that parse the signature */
+ case SIGN_WARN_VERBATIM:
+ warning(_("importing a commit signature verbatim"));
+ /* fallthru */
+ case SIGN_VERBATIM:
+ import_one_signature(&sig_sha1, &sig_sha256, v);
+ break;
+ /* Third, BUG */
+ default:
+ BUG("invalid signed_commit_mode value %d", signed_commit_mode);
+ }
read_next_command();
}
@@ -2923,6 +2964,43 @@ static void parse_new_commit(const char *arg)
b->last_commit = object_count_by_type[OBJ_COMMIT];
}
+static void handle_tag_signature(struct strbuf *msg, const char *name)
+{
+ size_t sig_offset = parse_signed_buffer(msg->buf, msg->len);
+
+ /* If there is no signature, there is nothing to do. */
+ if (sig_offset >= msg->len)
+ return;
+
+ switch (signed_tag_mode) {
+
+ /* First, modes that don't change anything */
+ case SIGN_ABORT:
+ die(_("encountered signed tag; use "
+ "--signed-tags=<mode> to handle it"));
+ case SIGN_WARN_VERBATIM:
+ warning(_("importing a tag signature verbatim for tag '%s'"), name);
+ /* fallthru */
+ case SIGN_VERBATIM:
+ /* Nothing to do, the signature will be put into the imported tag. */
+ break;
+
+ /* Second, modes that remove the signature */
+ case SIGN_WARN_STRIP:
+ warning(_("stripping a tag signature for tag '%s'"), name);
+ /* fallthru */
+ case SIGN_STRIP:
+ /* Truncate the buffer to remove the signature */
+ strbuf_setlen(msg, sig_offset);
+ break;
+
+ /* Third, BUG */
+ default:
+ BUG("invalid signed_tag_mode value %d from tag '%s'",
+ signed_tag_mode, name);
+ }
+}
+
static void parse_new_tag(const char *arg)
{
static struct strbuf msg = STRBUF_INIT;
@@ -2986,6 +3064,8 @@ static void parse_new_tag(const char *arg)
/* tag payload/message */
parse_data(&msg, 0, NULL);
+ handle_tag_signature(&msg, t->name);
+
/* build the tag object */
strbuf_reset(&new_data);
@@ -3503,6 +3583,12 @@ static int parse_one_option(const char *option)
option_active_branches(option);
} else if (skip_prefix(option, "export-pack-edges=", &option)) {
option_export_pack_edges(option);
+ } else if (skip_prefix(option, "signed-commits=", &option)) {
+ if (parse_sign_mode(option, &signed_commit_mode))
+ usagef(_("unknown --signed-commits mode '%s'"), option);
+ } else if (skip_prefix(option, "signed-tags=", &option)) {
+ if (parse_sign_mode(option, &signed_tag_mode))
+ usagef(_("unknown --signed-tags mode '%s'"), option);
} else if (!strcmp(option, "quiet")) {
show_stats = 0;
quiet = 1;