mirror of
https://github.com/git/git.git
synced 2025-12-12 20:36:24 +01:00
Tools like `git filter-repo`[1] use `git fast-export` and `git fast-import` to rewrite repository history. When rewriting history using one such tool though, commit signatures might become invalid because the commits they sign changed due to the changes in the repository history made by the tool between the fast-export and the fast-import steps. Note that as far as signature handling goes: * Since fast-export doesn't know what changes filter-repo may make to the stream, it can't know whether the signatures will still be valid. * Since filter-repo doesn't know what history canonicalizations fast-export performed (and it performs a few), it can't know whether the signatures will still be valid. * Therefore, fast-import is the only process in the pipeline that can know whether a specified signature remains valid. Having invalid signatures in a rewritten repository could be confusing, so users rewritting history might prefer to simply discard signatures that are invalid at the fast-import step. For example a common use case is to rewrite only "recent" history. While specifying commit ranges corresponding to "recent" commits could work, users worry about getting it wrong and want to just automatically rewrite everything, expecting older commit signatures to be untouched. To let them do that, let's add a new 'strip-if-invalid' mode to the `--signed-commits=<mode>` option of `git fast-import`. It would be interesting for the `--signed-tags=<mode>` option to have this mode too, but we leave that for a future improvement. It might also be possible for `git fast-export` to have such a mode in its `--signed-commits=<mode>` and `--signed-tags=<mode>` options, but the use cases for it are much less clear, so we also leave that for possible future improvements. For now let's just die() if 'strip-if-invalid' is passed to these options where it hasn't been implemented yet. [1]: https://github.com/newren/git-filter-repo Helped-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
124 lines
3.1 KiB
C
124 lines
3.1 KiB
C
#ifndef GPG_INTERFACE_H
|
|
#define GPG_INTERFACE_H
|
|
|
|
struct strbuf;
|
|
|
|
#define GPG_VERIFY_VERBOSE 1
|
|
#define GPG_VERIFY_RAW 2
|
|
#define GPG_VERIFY_OMIT_STATUS 4
|
|
|
|
enum signature_trust_level {
|
|
TRUST_UNDEFINED,
|
|
TRUST_NEVER,
|
|
TRUST_MARGINAL,
|
|
TRUST_FULLY,
|
|
TRUST_ULTIMATE,
|
|
};
|
|
|
|
enum payload_type {
|
|
SIGNATURE_PAYLOAD_UNDEFINED,
|
|
SIGNATURE_PAYLOAD_COMMIT,
|
|
SIGNATURE_PAYLOAD_TAG,
|
|
SIGNATURE_PAYLOAD_PUSH_CERT,
|
|
};
|
|
|
|
struct signature_check {
|
|
char *payload;
|
|
size_t payload_len;
|
|
enum payload_type payload_type;
|
|
timestamp_t payload_timestamp;
|
|
char *output;
|
|
char *gpg_status;
|
|
|
|
/*
|
|
* possible "result":
|
|
* 0 (not checked)
|
|
* N (checked but no further result)
|
|
* G (good)
|
|
* B (bad)
|
|
*/
|
|
char result;
|
|
char *signer;
|
|
char *key;
|
|
char *fingerprint;
|
|
char *primary_key_fingerprint;
|
|
enum signature_trust_level trust_level;
|
|
};
|
|
|
|
void signature_check_clear(struct signature_check *sigc);
|
|
|
|
/*
|
|
* Return the format of the signature (like "openpgp", "x509", "ssh"
|
|
* or "unknown").
|
|
*/
|
|
const char *get_signature_format(const char *buf);
|
|
|
|
/*
|
|
* Is the signature format valid (like "openpgp", "x509", "ssh" or
|
|
* "unknown")
|
|
*/
|
|
int valid_signature_format(const char *format);
|
|
|
|
/*
|
|
* Look at a GPG signed tag object. If such a signature exists, store it in
|
|
* signature and the signed content in payload. Return 1 if a signature was
|
|
* found, and 0 otherwise.
|
|
*/
|
|
int parse_signature(const char *buf, size_t size, struct strbuf *payload, struct strbuf *signature);
|
|
|
|
/*
|
|
* Look at GPG signed content (e.g. a signed tag object), whose
|
|
* payload is followed by a detached signature on it. Return the
|
|
* offset where the embedded detached signature begins, or the end of
|
|
* the data when there is no such signature.
|
|
*/
|
|
size_t parse_signed_buffer(const char *buf, size_t size);
|
|
|
|
/*
|
|
* Create a detached signature for the contents of "buffer" and append
|
|
* it after "signature"; "buffer" and "signature" can be the same
|
|
* strbuf instance, which would cause the detached signature appended
|
|
* at the end. Returns 0 on success, non-zero on failure.
|
|
*/
|
|
int sign_buffer(struct strbuf *buffer, struct strbuf *signature,
|
|
const char *signing_key);
|
|
|
|
|
|
/*
|
|
* Returns corresponding string in lowercase for a given member of
|
|
* enum signature_trust_level. For example, `TRUST_ULTIMATE` will
|
|
* return "ultimate".
|
|
*/
|
|
const char *gpg_trust_level_to_str(enum signature_trust_level level);
|
|
|
|
void set_signing_key(const char *);
|
|
char *get_signing_key(void);
|
|
|
|
/*
|
|
* Returns a textual unique representation of the signing key in use
|
|
* Either a GPG KeyID or a SSH Key Fingerprint
|
|
*/
|
|
char *get_signing_key_id(void);
|
|
int check_signature(struct signature_check *sigc,
|
|
const char *signature, size_t slen);
|
|
void print_signature_buffer(const struct signature_check *sigc,
|
|
unsigned flags);
|
|
|
|
/* Modes for --signed-tags=<mode> and --signed-commits=<mode> options. */
|
|
enum sign_mode {
|
|
SIGN_ABORT,
|
|
SIGN_WARN_VERBATIM,
|
|
SIGN_VERBATIM,
|
|
SIGN_WARN_STRIP,
|
|
SIGN_STRIP,
|
|
SIGN_STRIP_IF_INVALID,
|
|
};
|
|
|
|
/*
|
|
* Return 0 if `arg` can be parsed into an `enum sign_mode`. Return -1
|
|
* otherwise.
|
|
*/
|
|
int parse_sign_mode(const char *arg, enum sign_mode *mode);
|
|
|
|
#endif
|