|
|
|
|
@ -30,6 +30,7 @@
|
|
|
|
|
#include "khash.h"
|
|
|
|
|
#include "date.h"
|
|
|
|
|
#include "gpg-interface.h"
|
|
|
|
|
#include "parse-options.h"
|
|
|
|
|
|
|
|
|
|
#define PACK_ID_BITS 16
|
|
|
|
|
#define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
|
|
|
|
|
@ -184,10 +185,6 @@ static int failure;
|
|
|
|
|
static FILE *pack_edges;
|
|
|
|
|
static unsigned int show_stats = 1;
|
|
|
|
|
static unsigned int quiet;
|
|
|
|
|
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;
|
|
|
|
|
static const char *signed_commit_keyid;
|
|
|
|
|
@ -261,9 +258,7 @@ static struct recent_command *rc_free;
|
|
|
|
|
static unsigned int cmd_save = 100;
|
|
|
|
|
static uintmax_t next_mark;
|
|
|
|
|
static struct strbuf new_data = STRBUF_INIT;
|
|
|
|
|
static int seen_data_command;
|
|
|
|
|
static int require_explicit_termination;
|
|
|
|
|
static int allow_unsafe_features;
|
|
|
|
|
|
|
|
|
|
/* Signal handling */
|
|
|
|
|
static volatile sig_atomic_t checkpoint_requested;
|
|
|
|
|
@ -276,10 +271,31 @@ static kh_oid_map_t *sub_oid_map;
|
|
|
|
|
/* Where to write output of cat-blob commands */
|
|
|
|
|
static int cat_blob_fd = STDOUT_FILENO;
|
|
|
|
|
|
|
|
|
|
static void parse_argv(void);
|
|
|
|
|
static void parse_get_mark(const char *p);
|
|
|
|
|
static void parse_cat_blob(const char *p);
|
|
|
|
|
static void parse_ls(const char *p, struct branch *b);
|
|
|
|
|
/* Command state */
|
|
|
|
|
struct fast_import_state {
|
|
|
|
|
int argc;
|
|
|
|
|
const char **argv;
|
|
|
|
|
const char *prefix;
|
|
|
|
|
int seen_data_command;
|
|
|
|
|
int allow_unsafe_features;
|
|
|
|
|
struct option *option;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void fast_import_state_init(struct fast_import_state *state,
|
|
|
|
|
int argc, const char **argv,
|
|
|
|
|
const char *prefix, struct option *option)
|
|
|
|
|
{
|
|
|
|
|
memset(state, 0, sizeof(*state));
|
|
|
|
|
state->argc = argc;
|
|
|
|
|
state->argv = argv;
|
|
|
|
|
state->prefix = prefix;
|
|
|
|
|
state->option = option;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_argv(struct fast_import_state *state);
|
|
|
|
|
static void parse_get_mark(struct fast_import_state *state, const char *p);
|
|
|
|
|
static void parse_cat_blob(struct fast_import_state *state, const char *p);
|
|
|
|
|
static void parse_ls(struct fast_import_state *state, const char *p, struct branch *b);
|
|
|
|
|
|
|
|
|
|
static void for_each_mark(struct mark_set *m, uintmax_t base, each_mark_fn_t callback, void *p)
|
|
|
|
|
{
|
|
|
|
|
@ -1847,7 +1863,7 @@ done:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int read_next_command(void)
|
|
|
|
|
static int read_next_command(struct fast_import_state *state)
|
|
|
|
|
{
|
|
|
|
|
static int stdin_eof = 0;
|
|
|
|
|
|
|
|
|
|
@ -1866,10 +1882,10 @@ static int read_next_command(void)
|
|
|
|
|
if (stdin_eof)
|
|
|
|
|
return EOF;
|
|
|
|
|
|
|
|
|
|
if (!seen_data_command
|
|
|
|
|
if (!state->seen_data_command
|
|
|
|
|
&& !starts_with(command_buf.buf, "feature ")
|
|
|
|
|
&& !starts_with(command_buf.buf, "option ")) {
|
|
|
|
|
parse_argv();
|
|
|
|
|
parse_argv(state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rc = rc_free;
|
|
|
|
|
@ -1901,22 +1917,22 @@ static void skip_optional_lf(void)
|
|
|
|
|
ungetc(term_char, stdin);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_mark(void)
|
|
|
|
|
static void parse_mark(struct fast_import_state *state)
|
|
|
|
|
{
|
|
|
|
|
const char *v;
|
|
|
|
|
if (skip_prefix(command_buf.buf, "mark :", &v)) {
|
|
|
|
|
next_mark = strtoumax(v, NULL, 10);
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
next_mark = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_original_identifier(void)
|
|
|
|
|
static void parse_original_identifier(struct fast_import_state *state)
|
|
|
|
|
{
|
|
|
|
|
const char *v;
|
|
|
|
|
if (skip_prefix(command_buf.buf, "original-oid ", &v))
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int parse_data(struct strbuf *sb, uintmax_t limit, uintmax_t *len_res)
|
|
|
|
|
@ -2070,11 +2086,11 @@ static void parse_and_store_blob(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_new_blob(void)
|
|
|
|
|
static void parse_new_blob(struct fast_import_state *state)
|
|
|
|
|
{
|
|
|
|
|
read_next_command();
|
|
|
|
|
parse_mark();
|
|
|
|
|
parse_original_identifier();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
parse_mark(state);
|
|
|
|
|
parse_original_identifier(state);
|
|
|
|
|
parse_and_store_blob(&last_blob, NULL, next_mark);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -2370,7 +2386,7 @@ static void parse_path_space(struct strbuf *sb, const char *p,
|
|
|
|
|
(*endp)++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void file_change_m(const char *p, struct branch *b)
|
|
|
|
|
static void file_change_m(struct fast_import_state *state, const char *p, struct branch *b)
|
|
|
|
|
{
|
|
|
|
|
static struct strbuf path = STRBUF_INIT;
|
|
|
|
|
struct object_entry *oe;
|
|
|
|
|
@ -2437,10 +2453,10 @@ static void file_change_m(const char *p, struct branch *b)
|
|
|
|
|
if (S_ISDIR(mode))
|
|
|
|
|
die(_("directories cannot be specified 'inline': %s"),
|
|
|
|
|
command_buf.buf);
|
|
|
|
|
while (read_next_command() != EOF) {
|
|
|
|
|
while (read_next_command(state) != EOF) {
|
|
|
|
|
const char *v;
|
|
|
|
|
if (skip_prefix(command_buf.buf, "cat-blob ", &v))
|
|
|
|
|
parse_cat_blob(v);
|
|
|
|
|
parse_cat_blob(state, v);
|
|
|
|
|
else {
|
|
|
|
|
parse_and_store_blob(&last_blob, &oid, 0);
|
|
|
|
|
break;
|
|
|
|
|
@ -2514,7 +2530,7 @@ static void file_change_cr(const char *p, struct branch *b, int rename)
|
|
|
|
|
leaf.tree);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void note_change_n(const char *p, struct branch *b, unsigned char *old_fanout)
|
|
|
|
|
static void note_change_n(struct fast_import_state *state, const char *p, struct branch *b, unsigned char *old_fanout)
|
|
|
|
|
{
|
|
|
|
|
struct object_entry *oe;
|
|
|
|
|
struct branch *s;
|
|
|
|
|
@ -2579,7 +2595,7 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa
|
|
|
|
|
die(_("invalid ref name or SHA1 expression: %s"), p);
|
|
|
|
|
|
|
|
|
|
if (inline_data) {
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
parse_and_store_blob(&last_blob, &oid, 0);
|
|
|
|
|
} else if (oe) {
|
|
|
|
|
if (oe->type != OBJ_BLOB)
|
|
|
|
|
@ -2646,7 +2662,7 @@ static void parse_from_existing(struct branch *b)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int parse_objectish(struct branch *b, const char *objectish)
|
|
|
|
|
static int parse_objectish(struct fast_import_state *state, struct branch *b, const char *objectish)
|
|
|
|
|
{
|
|
|
|
|
struct branch *s;
|
|
|
|
|
struct object_id oid;
|
|
|
|
|
@ -2689,31 +2705,31 @@ static int parse_objectish(struct branch *b, const char *objectish)
|
|
|
|
|
b->branch_tree.tree = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int parse_from(struct branch *b)
|
|
|
|
|
static int parse_from(struct fast_import_state *state, struct branch *b)
|
|
|
|
|
{
|
|
|
|
|
const char *from;
|
|
|
|
|
|
|
|
|
|
if (!skip_prefix(command_buf.buf, "from ", &from))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
return parse_objectish(b, from);
|
|
|
|
|
return parse_objectish(state, b, from);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int parse_objectish_with_prefix(struct branch *b, const char *prefix)
|
|
|
|
|
static int parse_objectish_with_prefix(struct fast_import_state *state, struct branch *b, const char *prefix)
|
|
|
|
|
{
|
|
|
|
|
const char *base;
|
|
|
|
|
|
|
|
|
|
if (!skip_prefix(command_buf.buf, prefix, &base))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
return parse_objectish(b, base);
|
|
|
|
|
return parse_objectish(state, b, base);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct hash_list *parse_merge(unsigned int *count)
|
|
|
|
|
static struct hash_list *parse_merge(struct fast_import_state *state, unsigned int *count)
|
|
|
|
|
{
|
|
|
|
|
struct hash_list *list = NULL, **tail = &list, *n;
|
|
|
|
|
const char *from;
|
|
|
|
|
@ -2747,7 +2763,7 @@ static struct hash_list *parse_merge(unsigned int *count)
|
|
|
|
|
tail = &n->next;
|
|
|
|
|
|
|
|
|
|
(*count)++;
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
}
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
@ -2758,7 +2774,7 @@ struct signature_data {
|
|
|
|
|
struct strbuf data; /* The actual signature data */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void parse_one_signature(struct signature_data *sig, const char *v)
|
|
|
|
|
static void parse_one_signature(struct fast_import_state *state, struct signature_data *sig, const char *v)
|
|
|
|
|
{
|
|
|
|
|
char *args = xstrdup(v); /* Will be freed when sig->hash_algo is freed */
|
|
|
|
|
char *space = strchr(args, ' ');
|
|
|
|
|
@ -2783,15 +2799,15 @@ static void parse_one_signature(struct signature_data *sig, const char *v)
|
|
|
|
|
warning(_("'unknown' signature format in gpgsig"));
|
|
|
|
|
|
|
|
|
|
/* Read signature data */
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
parse_data(&sig->data, 0, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void discard_one_signature(void)
|
|
|
|
|
static void discard_one_signature(struct fast_import_state *state)
|
|
|
|
|
{
|
|
|
|
|
struct strbuf data = STRBUF_INIT;
|
|
|
|
|
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
parse_data(&data, 0, NULL);
|
|
|
|
|
strbuf_release(&data);
|
|
|
|
|
}
|
|
|
|
|
@ -2829,13 +2845,14 @@ static void store_signature(struct signature_data *stored_sig,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void import_one_signature(struct signature_data *sig_sha1,
|
|
|
|
|
static void import_one_signature(struct fast_import_state *state,
|
|
|
|
|
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);
|
|
|
|
|
parse_one_signature(state, &sig, v);
|
|
|
|
|
|
|
|
|
|
if (!strcmp(sig.hash_algo, "sha1"))
|
|
|
|
|
store_signature(sig_sha1, &sig, "SHA-1");
|
|
|
|
|
@ -2949,7 +2966,7 @@ static void handle_signature_if_invalid(struct strbuf *new_data,
|
|
|
|
|
strbuf_release(&tmp_buf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_new_commit(const char *arg)
|
|
|
|
|
static void parse_new_commit(struct fast_import_state *state, const char *arg)
|
|
|
|
|
{
|
|
|
|
|
static struct strbuf msg = STRBUF_INIT;
|
|
|
|
|
struct signature_data sig_sha1 = { NULL, NULL, STRBUF_INIT };
|
|
|
|
|
@ -2967,16 +2984,16 @@ static void parse_new_commit(const char *arg)
|
|
|
|
|
if (!b)
|
|
|
|
|
b = new_branch(arg);
|
|
|
|
|
|
|
|
|
|
read_next_command();
|
|
|
|
|
parse_mark();
|
|
|
|
|
parse_original_identifier();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
parse_mark(state);
|
|
|
|
|
parse_original_identifier(state);
|
|
|
|
|
if (skip_prefix(command_buf.buf, "author ", &v)) {
|
|
|
|
|
author = parse_ident(v);
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
}
|
|
|
|
|
if (skip_prefix(command_buf.buf, "committer ", &v)) {
|
|
|
|
|
committer = parse_ident(v);
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
}
|
|
|
|
|
if (!committer)
|
|
|
|
|
die(_("expected committer but didn't get one"));
|
|
|
|
|
@ -2992,7 +3009,7 @@ static void parse_new_commit(const char *arg)
|
|
|
|
|
warning(_("stripping a commit signature"));
|
|
|
|
|
/* fallthru */
|
|
|
|
|
case SIGN_STRIP:
|
|
|
|
|
discard_one_signature();
|
|
|
|
|
discard_one_signature(state);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* Second, modes that parse the signature */
|
|
|
|
|
@ -3003,24 +3020,24 @@ static void parse_new_commit(const char *arg)
|
|
|
|
|
case SIGN_STRIP_IF_INVALID:
|
|
|
|
|
case SIGN_SIGN_IF_INVALID:
|
|
|
|
|
case SIGN_ABORT_IF_INVALID:
|
|
|
|
|
import_one_signature(&sig_sha1, &sig_sha256, v);
|
|
|
|
|
import_one_signature(state, &sig_sha1, &sig_sha256, v);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* Third, BUG */
|
|
|
|
|
default:
|
|
|
|
|
BUG("invalid signed_commit_mode value %d", signed_commit_mode);
|
|
|
|
|
}
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (skip_prefix(command_buf.buf, "encoding ", &v)) {
|
|
|
|
|
encoding = xstrdup(v);
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
}
|
|
|
|
|
parse_data(&msg, 0, NULL);
|
|
|
|
|
read_next_command();
|
|
|
|
|
parse_from(b);
|
|
|
|
|
merge_list = parse_merge(&merge_count);
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
parse_from(state, b);
|
|
|
|
|
merge_list = parse_merge(state, &merge_count);
|
|
|
|
|
|
|
|
|
|
/* ensure the branch is active/loaded */
|
|
|
|
|
if (!b->branch_tree.tree || !max_active_branches) {
|
|
|
|
|
@ -3033,7 +3050,7 @@ static void parse_new_commit(const char *arg)
|
|
|
|
|
/* file_change* */
|
|
|
|
|
while (command_buf.len > 0) {
|
|
|
|
|
if (skip_prefix(command_buf.buf, "M ", &v))
|
|
|
|
|
file_change_m(v, b);
|
|
|
|
|
file_change_m(state, v, b);
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "D ", &v))
|
|
|
|
|
file_change_d(v, b);
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "R ", &v))
|
|
|
|
|
@ -3041,18 +3058,18 @@ static void parse_new_commit(const char *arg)
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "C ", &v))
|
|
|
|
|
file_change_cr(v, b, 0);
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "N ", &v))
|
|
|
|
|
note_change_n(v, b, &prev_fanout);
|
|
|
|
|
note_change_n(state, v, b, &prev_fanout);
|
|
|
|
|
else if (!strcmp("deleteall", command_buf.buf))
|
|
|
|
|
file_change_deleteall(b);
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "ls ", &v))
|
|
|
|
|
parse_ls(v, b);
|
|
|
|
|
parse_ls(state, v, b);
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "cat-blob ", &v))
|
|
|
|
|
parse_cat_blob(v);
|
|
|
|
|
parse_cat_blob(state, v);
|
|
|
|
|
else {
|
|
|
|
|
unread_command_buf = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (read_next_command() == EOF)
|
|
|
|
|
if (read_next_command(state) == EOF)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -3190,7 +3207,7 @@ static void handle_tag_signature(struct strbuf *buf, struct strbuf *msg, const c
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_new_tag(const char *arg)
|
|
|
|
|
static void parse_new_tag(struct fast_import_state *state, const char *arg)
|
|
|
|
|
{
|
|
|
|
|
static struct strbuf msg = STRBUF_INIT;
|
|
|
|
|
const char *from;
|
|
|
|
|
@ -3209,8 +3226,8 @@ static void parse_new_tag(const char *arg)
|
|
|
|
|
else
|
|
|
|
|
first_tag = t;
|
|
|
|
|
last_tag = t;
|
|
|
|
|
read_next_command();
|
|
|
|
|
parse_mark();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
parse_mark(state);
|
|
|
|
|
|
|
|
|
|
/* from ... */
|
|
|
|
|
if (!skip_prefix(command_buf.buf, "from ", &from))
|
|
|
|
|
@ -3238,15 +3255,15 @@ static void parse_new_tag(const char *arg)
|
|
|
|
|
type = oe->type;
|
|
|
|
|
} else
|
|
|
|
|
die(_("invalid ref name or SHA1 expression: %s"), from);
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
|
|
|
|
|
/* original-oid ... */
|
|
|
|
|
parse_original_identifier();
|
|
|
|
|
parse_original_identifier(state);
|
|
|
|
|
|
|
|
|
|
/* tagger ... */
|
|
|
|
|
if (skip_prefix(command_buf.buf, "tagger ", &v)) {
|
|
|
|
|
tagger = parse_ident(v);
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
} else
|
|
|
|
|
tagger = NULL;
|
|
|
|
|
|
|
|
|
|
@ -3277,7 +3294,7 @@ static void parse_new_tag(const char *arg)
|
|
|
|
|
t->pack_id = pack_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_reset_branch(const char *arg)
|
|
|
|
|
static void parse_reset_branch(struct fast_import_state *state, const char *arg)
|
|
|
|
|
{
|
|
|
|
|
struct branch *b;
|
|
|
|
|
const char *tag_name;
|
|
|
|
|
@ -3294,8 +3311,8 @@ static void parse_reset_branch(const char *arg)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
b = new_branch(arg);
|
|
|
|
|
read_next_command();
|
|
|
|
|
parse_from(b);
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
parse_from(state, b);
|
|
|
|
|
if (b->delete && skip_prefix(b->name, "refs/tags/", &tag_name)) {
|
|
|
|
|
/*
|
|
|
|
|
* Elsewhere, we call dump_branches() before dump_tags(),
|
|
|
|
|
@ -3392,7 +3409,7 @@ static void cat_blob(struct object_entry *oe, struct object_id *oid)
|
|
|
|
|
free(buf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_get_mark(const char *p)
|
|
|
|
|
static void parse_get_mark(struct fast_import_state *state UNUSED, const char *p)
|
|
|
|
|
{
|
|
|
|
|
struct object_entry *oe;
|
|
|
|
|
char output[GIT_MAX_HEXSZ + 2];
|
|
|
|
|
@ -3409,7 +3426,7 @@ static void parse_get_mark(const char *p)
|
|
|
|
|
cat_blob_write(output, the_hash_algo->hexsz + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_cat_blob(const char *p)
|
|
|
|
|
static void parse_cat_blob(struct fast_import_state *state UNUSED, const char *p)
|
|
|
|
|
{
|
|
|
|
|
struct object_entry *oe;
|
|
|
|
|
struct object_id oid;
|
|
|
|
|
@ -3574,7 +3591,7 @@ static void print_ls(int mode, const unsigned char *hash, const char *path)
|
|
|
|
|
cat_blob_write(line.buf, line.len);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_ls(const char *p, struct branch *b)
|
|
|
|
|
static void parse_ls(struct fast_import_state *state UNUSED, const char *p, struct branch *b)
|
|
|
|
|
{
|
|
|
|
|
static struct strbuf path = STRBUF_INIT;
|
|
|
|
|
struct tree_entry *root = NULL;
|
|
|
|
|
@ -3621,13 +3638,13 @@ static void checkpoint(void)
|
|
|
|
|
dump_marks();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_checkpoint(void)
|
|
|
|
|
static void parse_checkpoint(struct fast_import_state *state UNUSED)
|
|
|
|
|
{
|
|
|
|
|
checkpoint_requested = 1;
|
|
|
|
|
skip_optional_lf();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_progress(void)
|
|
|
|
|
static void parse_progress(struct fast_import_state *state UNUSED)
|
|
|
|
|
{
|
|
|
|
|
fwrite(command_buf.buf, 1, command_buf.len, stdout);
|
|
|
|
|
fputc('\n', stdout);
|
|
|
|
|
@ -3635,36 +3652,36 @@ static void parse_progress(void)
|
|
|
|
|
skip_optional_lf();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_alias(void)
|
|
|
|
|
static void parse_alias(struct fast_import_state *state)
|
|
|
|
|
{
|
|
|
|
|
struct object_entry *e;
|
|
|
|
|
struct branch b;
|
|
|
|
|
|
|
|
|
|
skip_optional_lf();
|
|
|
|
|
read_next_command();
|
|
|
|
|
read_next_command(state);
|
|
|
|
|
|
|
|
|
|
/* mark ... */
|
|
|
|
|
parse_mark();
|
|
|
|
|
parse_mark(state);
|
|
|
|
|
if (!next_mark)
|
|
|
|
|
die(_("expected 'mark' command, got %s"), command_buf.buf);
|
|
|
|
|
|
|
|
|
|
/* to ... */
|
|
|
|
|
memset(&b, 0, sizeof(b));
|
|
|
|
|
if (!parse_objectish_with_prefix(&b, "to "))
|
|
|
|
|
if (!parse_objectish_with_prefix(state, &b, "to "))
|
|
|
|
|
die(_("expected 'to' command, got %s"), command_buf.buf);
|
|
|
|
|
e = find_object(&b.oid);
|
|
|
|
|
assert(e);
|
|
|
|
|
insert_mark(&marks, next_mark, e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char* make_fast_import_path(const char *path)
|
|
|
|
|
static char* make_fast_import_path(struct fast_import_state *state, const char *path)
|
|
|
|
|
{
|
|
|
|
|
if (!relative_marks_paths || is_absolute_path(path))
|
|
|
|
|
return prefix_filename(global_prefix, path);
|
|
|
|
|
return prefix_filename(state->prefix, path);
|
|
|
|
|
return repo_git_path(the_repository, "info/fast-import/%s", path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void option_import_marks(const char *marks,
|
|
|
|
|
static void option_import_marks(struct fast_import_state *state, const char *marks,
|
|
|
|
|
int from_stream, int ignore_missing)
|
|
|
|
|
{
|
|
|
|
|
if (import_marks_file) {
|
|
|
|
|
@ -3677,7 +3694,7 @@ static void option_import_marks(const char *marks,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(import_marks_file);
|
|
|
|
|
import_marks_file = make_fast_import_path(marks);
|
|
|
|
|
import_marks_file = make_fast_import_path(state, marks);
|
|
|
|
|
import_marks_file_from_stream = from_stream;
|
|
|
|
|
import_marks_file_ignore_missing = ignore_missing;
|
|
|
|
|
}
|
|
|
|
|
@ -3717,13 +3734,13 @@ static void option_active_branches(const char *branches)
|
|
|
|
|
max_active_branches = ulong_arg("--active-branches", branches);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void option_export_marks(const char *marks)
|
|
|
|
|
static void option_export_marks(struct fast_import_state *state, const char *marks)
|
|
|
|
|
{
|
|
|
|
|
free(export_marks_file);
|
|
|
|
|
export_marks_file = make_fast_import_path(marks);
|
|
|
|
|
export_marks_file = make_fast_import_path(state, marks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void option_cat_blob_fd(const char *fd)
|
|
|
|
|
static void option_cat_blob_fd(struct fast_import_state *state UNUSED, const char *fd)
|
|
|
|
|
{
|
|
|
|
|
unsigned long n = ulong_arg("--cat-blob-fd", fd);
|
|
|
|
|
if (n > (unsigned long) INT_MAX)
|
|
|
|
|
@ -3731,16 +3748,16 @@ static void option_cat_blob_fd(const char *fd)
|
|
|
|
|
cat_blob_fd = (int) n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void option_export_pack_edges(const char *edges)
|
|
|
|
|
static void option_export_pack_edges(struct fast_import_state *state, const char *edges)
|
|
|
|
|
{
|
|
|
|
|
char *fn = prefix_filename(global_prefix, edges);
|
|
|
|
|
char *fn = prefix_filename(state->prefix, edges);
|
|
|
|
|
if (pack_edges)
|
|
|
|
|
fclose(pack_edges);
|
|
|
|
|
pack_edges = xfopen(fn, "a");
|
|
|
|
|
free(fn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void option_rewrite_submodules(const char *arg, struct string_list *list)
|
|
|
|
|
static void option_rewrite_submodules(struct fast_import_state *state, const char *arg, struct string_list *list)
|
|
|
|
|
{
|
|
|
|
|
struct mark_set *ms;
|
|
|
|
|
FILE *fp;
|
|
|
|
|
@ -3752,7 +3769,7 @@ static void option_rewrite_submodules(const char *arg, struct string_list *list)
|
|
|
|
|
f++;
|
|
|
|
|
CALLOC_ARRAY(ms, 1);
|
|
|
|
|
|
|
|
|
|
f = prefix_filename(global_prefix, f);
|
|
|
|
|
f = prefix_filename(state->prefix, f);
|
|
|
|
|
fp = fopen(f, "r");
|
|
|
|
|
if (!fp)
|
|
|
|
|
die_errno(_("cannot read '%s'"), f);
|
|
|
|
|
@ -3765,7 +3782,7 @@ static void option_rewrite_submodules(const char *arg, struct string_list *list)
|
|
|
|
|
free(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int parse_one_option(const char *option)
|
|
|
|
|
static int parse_one_option(struct fast_import_state *state, const char *option)
|
|
|
|
|
{
|
|
|
|
|
if (skip_prefix(option, "max-pack-size=", &option)) {
|
|
|
|
|
unsigned long v;
|
|
|
|
|
@ -3789,7 +3806,7 @@ static int parse_one_option(const char *option)
|
|
|
|
|
} else if (skip_prefix(option, "active-branches=", &option)) {
|
|
|
|
|
option_active_branches(option);
|
|
|
|
|
} else if (skip_prefix(option, "export-pack-edges=", &option)) {
|
|
|
|
|
option_export_pack_edges(option);
|
|
|
|
|
option_export_pack_edges(state, option);
|
|
|
|
|
} else if (skip_prefix(option, "signed-commits=", &option)) {
|
|
|
|
|
if (parse_sign_mode(option, &signed_commit_mode, &signed_commit_keyid))
|
|
|
|
|
usagef(_("unknown --signed-commits mode '%s'"), option);
|
|
|
|
|
@ -3810,34 +3827,34 @@ static int parse_one_option(const char *option)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void check_unsafe_feature(const char *feature, int from_stream)
|
|
|
|
|
static void check_unsafe_feature(struct fast_import_state *state, const char *feature, int from_stream)
|
|
|
|
|
{
|
|
|
|
|
if (from_stream && !allow_unsafe_features)
|
|
|
|
|
if (from_stream && !state->allow_unsafe_features)
|
|
|
|
|
die(_("feature '%s' forbidden in input without --allow-unsafe-features"),
|
|
|
|
|
feature);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int parse_one_feature(const char *feature, int from_stream)
|
|
|
|
|
static int parse_one_feature(struct fast_import_state *state, const char *feature, int from_stream)
|
|
|
|
|
{
|
|
|
|
|
const char *arg;
|
|
|
|
|
|
|
|
|
|
if (skip_prefix(feature, "date-format=", &arg)) {
|
|
|
|
|
option_date_format(arg);
|
|
|
|
|
} else if (skip_prefix(feature, "import-marks=", &arg)) {
|
|
|
|
|
check_unsafe_feature("import-marks", from_stream);
|
|
|
|
|
option_import_marks(arg, from_stream, 0);
|
|
|
|
|
check_unsafe_feature(state, "import-marks", from_stream);
|
|
|
|
|
option_import_marks(state, arg, from_stream, 0);
|
|
|
|
|
} else if (skip_prefix(feature, "import-marks-if-exists=", &arg)) {
|
|
|
|
|
check_unsafe_feature("import-marks-if-exists", from_stream);
|
|
|
|
|
option_import_marks(arg, from_stream, 1);
|
|
|
|
|
check_unsafe_feature(state, "import-marks-if-exists", from_stream);
|
|
|
|
|
option_import_marks(state, arg, from_stream, 1);
|
|
|
|
|
} else if (skip_prefix(feature, "export-marks=", &arg)) {
|
|
|
|
|
check_unsafe_feature(feature, from_stream);
|
|
|
|
|
option_export_marks(arg);
|
|
|
|
|
check_unsafe_feature(state, feature, from_stream);
|
|
|
|
|
option_export_marks(state, arg);
|
|
|
|
|
} else if (!strcmp(feature, "alias")) {
|
|
|
|
|
; /* Don't die - this feature is supported */
|
|
|
|
|
} else if (skip_prefix(feature, "rewrite-submodules-to=", &arg)) {
|
|
|
|
|
option_rewrite_submodules(arg, &sub_marks_to);
|
|
|
|
|
option_rewrite_submodules(state, arg, &sub_marks_to);
|
|
|
|
|
} else if (skip_prefix(feature, "rewrite-submodules-from=", &arg)) {
|
|
|
|
|
option_rewrite_submodules(arg, &sub_marks_from);
|
|
|
|
|
option_rewrite_submodules(state, arg, &sub_marks_from);
|
|
|
|
|
} else if (!strcmp(feature, "get-mark")) {
|
|
|
|
|
; /* Don't die - this feature is supported */
|
|
|
|
|
} else if (!strcmp(feature, "cat-blob")) {
|
|
|
|
|
@ -3859,23 +3876,23 @@ static int parse_one_feature(const char *feature, int from_stream)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_feature(const char *feature)
|
|
|
|
|
static void parse_feature(struct fast_import_state *state, const char *feature)
|
|
|
|
|
{
|
|
|
|
|
if (seen_data_command)
|
|
|
|
|
if (state->seen_data_command)
|
|
|
|
|
die(_("got feature command '%s' after data command"), feature);
|
|
|
|
|
|
|
|
|
|
if (parse_one_feature(feature, 1))
|
|
|
|
|
if (parse_one_feature(state, feature, 1))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
die(_("this version of fast-import does not support feature %s."), feature);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parse_option(const char *option)
|
|
|
|
|
static void parse_option(struct fast_import_state *state, const char *option)
|
|
|
|
|
{
|
|
|
|
|
if (seen_data_command)
|
|
|
|
|
if (state->seen_data_command)
|
|
|
|
|
die(_("got option command '%s' after data command"), option);
|
|
|
|
|
|
|
|
|
|
if (parse_one_option(option))
|
|
|
|
|
if (parse_one_option(state, option))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
die(_("this version of fast-import does not support option: %s"), option);
|
|
|
|
|
@ -3908,15 +3925,17 @@ static void git_pack_config(void)
|
|
|
|
|
repo_config(the_repository, git_default_config, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char fast_import_usage[] =
|
|
|
|
|
"git fast-import [--date-format=<f>] [--max-pack-size=<n>] [--big-file-threshold=<n>] [--depth=<n>] [--active-branches=<n>] [--export-marks=<marks.file>]";
|
|
|
|
|
static const char *const fast_import_usage[] = {
|
|
|
|
|
N_("git fast-import [<options>]"),
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void parse_argv(void)
|
|
|
|
|
static void parse_argv(struct fast_import_state *state)
|
|
|
|
|
{
|
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
|
|
for (i = 1; i < global_argc; i++) {
|
|
|
|
|
const char *a = global_argv[i];
|
|
|
|
|
for (i = 1; i < state->argc; i++) {
|
|
|
|
|
const char *a = state->argv[i];
|
|
|
|
|
|
|
|
|
|
if (*a != '-' || !strcmp(a, "--"))
|
|
|
|
|
break;
|
|
|
|
|
@ -3924,23 +3943,23 @@ static void parse_argv(void)
|
|
|
|
|
if (!skip_prefix(a, "--", &a))
|
|
|
|
|
die(_("unknown option %s"), a);
|
|
|
|
|
|
|
|
|
|
if (parse_one_option(a))
|
|
|
|
|
if (parse_one_option(state, a))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (parse_one_feature(a, 0))
|
|
|
|
|
if (parse_one_feature(state, a, 0))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (skip_prefix(a, "cat-blob-fd=", &a)) {
|
|
|
|
|
option_cat_blob_fd(a);
|
|
|
|
|
option_cat_blob_fd(state, a);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
die(_("unknown option --%s"), a);
|
|
|
|
|
}
|
|
|
|
|
if (i != global_argc)
|
|
|
|
|
usage(fast_import_usage);
|
|
|
|
|
if (i != state->argc)
|
|
|
|
|
usage_with_options(fast_import_usage, state->option);
|
|
|
|
|
|
|
|
|
|
seen_data_command = 1;
|
|
|
|
|
state->seen_data_command = 1;
|
|
|
|
|
if (import_marks_file)
|
|
|
|
|
read_marks();
|
|
|
|
|
build_mark_map(&sub_marks_from, &sub_marks_to);
|
|
|
|
|
@ -3951,9 +3970,80 @@ int cmd_fast_import(int argc,
|
|
|
|
|
const char *prefix,
|
|
|
|
|
struct repository *repo)
|
|
|
|
|
{
|
|
|
|
|
unsigned int i;
|
|
|
|
|
struct fast_import_state state;
|
|
|
|
|
|
|
|
|
|
show_usage_if_asked(argc, argv, fast_import_usage);
|
|
|
|
|
unsigned long pack_size_limit, big_file_threshold, depth, active_branches;
|
|
|
|
|
char *edges, *signed_commits, *signed_tags, *date_format, *import_marks;
|
|
|
|
|
char *import_marks_if_exists, *export_marks, *submodules_from, *submodules_to;
|
|
|
|
|
int opt_quiet, opt_show_stats, opt_relative_marks, opt_force, opt_done;
|
|
|
|
|
int opt_allow_unsafe;
|
|
|
|
|
int cat_blob;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* NEEDSWORK: For now this is used only to render
|
|
|
|
|
* `-h`/`--help-all` usage messages. The actual parsing is
|
|
|
|
|
* done by parse_one_option()/parse_one_feature().
|
|
|
|
|
*/
|
|
|
|
|
struct option fast_import_options[] = {
|
|
|
|
|
OPT_GROUP(N_("Common")),
|
|
|
|
|
OPT_STRING_F(0, "date-format", &date_format, N_("fmt"),
|
|
|
|
|
N_("format of the commit/tag dates"), PARSE_OPT_NONEG),
|
|
|
|
|
OPT_BOOL_F(0, "stats", &opt_show_stats,
|
|
|
|
|
N_("display some basic statistics (objects, packfiles and memory)"),
|
|
|
|
|
PARSE_OPT_NONEG),
|
|
|
|
|
OPT_BOOL_F(0, "quiet", &opt_quiet,
|
|
|
|
|
N_("disable the output shown by --stats"), PARSE_OPT_NONEG),
|
|
|
|
|
OPT_BOOL_F(0, "force", &opt_force,
|
|
|
|
|
N_("force updating modified existing branches"), PARSE_OPT_NONEG),
|
|
|
|
|
OPT_BOOL_F(0, "done", &opt_done,
|
|
|
|
|
N_("require a terminating 'done' command"), PARSE_OPT_NONEG),
|
|
|
|
|
OPT_UNSIGNED(0, "max-pack-size", &pack_size_limit,
|
|
|
|
|
N_("maximum size of each output pack file")),
|
|
|
|
|
OPT_UNSIGNED(0, "big-file-threshold", &big_file_threshold,
|
|
|
|
|
N_("maximum size of a blob that will be deltified")),
|
|
|
|
|
OPT_UNSIGNED(0, "depth", &depth,
|
|
|
|
|
N_("maximum delta depth")),
|
|
|
|
|
OPT_UNSIGNED(0, "active-branches", &active_branches,
|
|
|
|
|
N_("maximum number of branches to maintain active")),
|
|
|
|
|
OPT_GROUP(N_("Marks")),
|
|
|
|
|
OPT_STRING_F(0, "import-marks", &import_marks, N_("file"),
|
|
|
|
|
N_("import marks from <file>"), PARSE_OPT_NONEG),
|
|
|
|
|
OPT_STRING_F(0, "import-marks-if-exists", &import_marks_if_exists, N_("file"),
|
|
|
|
|
N_("import marks from <file> if it exists"), PARSE_OPT_NONEG),
|
|
|
|
|
OPT_STRING_F(0, "export-marks", &export_marks, N_("file"),
|
|
|
|
|
N_("dump marks to <file>"), PARSE_OPT_NONEG),
|
|
|
|
|
OPT_BOOL(0, "relative-marks", &opt_relative_marks,
|
|
|
|
|
N_("are --(import|export)-marks= paths relative to '.git/info/fast-import'?")),
|
|
|
|
|
OPT_GROUP(N_("Submodule rewrite")),
|
|
|
|
|
OPT_STRING_F(0, "rewrite-submodules-from", &submodules_from, N_("name:filename"),
|
|
|
|
|
N_("rewrite object IDs for submodule <name> from <filename>"),
|
|
|
|
|
PARSE_OPT_NONEG),
|
|
|
|
|
OPT_STRING_F(0, "rewrite-submodules-to", &submodules_to, N_("name:filename"),
|
|
|
|
|
N_("rewrite object IDs for submodule <name> to <filename>"),
|
|
|
|
|
PARSE_OPT_NONEG),
|
|
|
|
|
OPT_GROUP(N_("Signing")),
|
|
|
|
|
OPT_STRING_F(0, "signed-commits", &signed_commits, N_("mode"),
|
|
|
|
|
N_("how to handle signed commits"),
|
|
|
|
|
PARSE_OPT_NONEG),
|
|
|
|
|
OPT_STRING_F(0, "signed-tags", &signed_tags, N_("mode"),
|
|
|
|
|
N_("how to handle signed tags"),
|
|
|
|
|
PARSE_OPT_NONEG),
|
|
|
|
|
OPT_HIDDEN_GROUP(N_("Advanced")),
|
|
|
|
|
OPT_BOOL_F(0, "allow-unsafe-features", &opt_allow_unsafe,
|
|
|
|
|
N_("allow unsafe mark commands from the stream"),
|
|
|
|
|
PARSE_OPT_HIDDEN | PARSE_OPT_NONEG),
|
|
|
|
|
OPT_STRING_F(0, "export-pack-edges", &edges, N_("file"),
|
|
|
|
|
N_("dump edge commits to <file>"),
|
|
|
|
|
PARSE_OPT_HIDDEN | PARSE_OPT_NONEG),
|
|
|
|
|
OPT_INTEGER_F(0, "cat-blob-fd", &cat_blob,
|
|
|
|
|
N_("write some responses to <fd> instead of stdout"),
|
|
|
|
|
PARSE_OPT_HIDDEN | PARSE_OPT_NONEG),
|
|
|
|
|
OPT_END()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
show_usage_with_options_if_asked(argc, argv, fast_import_usage, fast_import_options);
|
|
|
|
|
|
|
|
|
|
fast_import_state_init(&state, argc, argv, prefix, fast_import_options);
|
|
|
|
|
|
|
|
|
|
reset_pack_idx_option(&pack_idx_opts);
|
|
|
|
|
git_pack_config();
|
|
|
|
|
@ -3973,54 +4063,50 @@ int cmd_fast_import(int argc,
|
|
|
|
|
* line to override stream data). But we must do an early parse of any
|
|
|
|
|
* command-line options that impact how we interpret the feature lines.
|
|
|
|
|
*/
|
|
|
|
|
for (i = 1; i < argc; i++) {
|
|
|
|
|
for (int i = 1; i < argc; i++) {
|
|
|
|
|
const char *arg = argv[i];
|
|
|
|
|
if (*arg != '-' || !strcmp(arg, "--"))
|
|
|
|
|
break;
|
|
|
|
|
if (!strcmp(arg, "--allow-unsafe-features"))
|
|
|
|
|
allow_unsafe_features = 1;
|
|
|
|
|
state.allow_unsafe_features = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
global_argc = argc;
|
|
|
|
|
global_argv = argv;
|
|
|
|
|
global_prefix = prefix;
|
|
|
|
|
|
|
|
|
|
rc_free = mem_pool_alloc(&fi_mem_pool, cmd_save * sizeof(*rc_free));
|
|
|
|
|
for (i = 0; i < (cmd_save - 1); i++)
|
|
|
|
|
for (unsigned int i = 0; i < (cmd_save - 1); i++)
|
|
|
|
|
rc_free[i].next = &rc_free[i + 1];
|
|
|
|
|
rc_free[cmd_save - 1].next = NULL;
|
|
|
|
|
|
|
|
|
|
start_packfile();
|
|
|
|
|
set_die_routine(die_nicely);
|
|
|
|
|
set_checkpoint_signal();
|
|
|
|
|
while (read_next_command() != EOF) {
|
|
|
|
|
while (read_next_command(&state) != EOF) {
|
|
|
|
|
const char *v;
|
|
|
|
|
if (!strcmp("blob", command_buf.buf))
|
|
|
|
|
parse_new_blob();
|
|
|
|
|
parse_new_blob(&state);
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "commit ", &v))
|
|
|
|
|
parse_new_commit(v);
|
|
|
|
|
parse_new_commit(&state, v);
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "tag ", &v))
|
|
|
|
|
parse_new_tag(v);
|
|
|
|
|
parse_new_tag(&state, v);
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "reset ", &v))
|
|
|
|
|
parse_reset_branch(v);
|
|
|
|
|
parse_reset_branch(&state, v);
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "ls ", &v))
|
|
|
|
|
parse_ls(v, NULL);
|
|
|
|
|
parse_ls(&state, v, NULL);
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "cat-blob ", &v))
|
|
|
|
|
parse_cat_blob(v);
|
|
|
|
|
parse_cat_blob(&state, v);
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "get-mark ", &v))
|
|
|
|
|
parse_get_mark(v);
|
|
|
|
|
parse_get_mark(&state, v);
|
|
|
|
|
else if (!strcmp("checkpoint", command_buf.buf))
|
|
|
|
|
parse_checkpoint();
|
|
|
|
|
parse_checkpoint(&state);
|
|
|
|
|
else if (!strcmp("done", command_buf.buf))
|
|
|
|
|
break;
|
|
|
|
|
else if (!strcmp("alias", command_buf.buf))
|
|
|
|
|
parse_alias();
|
|
|
|
|
parse_alias(&state);
|
|
|
|
|
else if (starts_with(command_buf.buf, "progress "))
|
|
|
|
|
parse_progress();
|
|
|
|
|
parse_progress(&state);
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "feature ", &v))
|
|
|
|
|
parse_feature(v);
|
|
|
|
|
parse_feature(&state, v);
|
|
|
|
|
else if (skip_prefix(command_buf.buf, "option git ", &v))
|
|
|
|
|
parse_option(v);
|
|
|
|
|
parse_option(&state, v);
|
|
|
|
|
else if (starts_with(command_buf.buf, "option "))
|
|
|
|
|
/* ignore non-git options*/;
|
|
|
|
|
else
|
|
|
|
|
@ -4031,8 +4117,8 @@ int cmd_fast_import(int argc,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* argv hasn't been parsed yet, do so */
|
|
|
|
|
if (!seen_data_command)
|
|
|
|
|
parse_argv();
|
|
|
|
|
if (!state.seen_data_command)
|
|
|
|
|
parse_argv(&state);
|
|
|
|
|
|
|
|
|
|
if (require_explicit_termination && feof(stdin))
|
|
|
|
|
die(_("stream ends early"));
|
|
|
|
|
@ -4049,9 +4135,9 @@ int cmd_fast_import(int argc,
|
|
|
|
|
|
|
|
|
|
if (show_stats) {
|
|
|
|
|
uintmax_t total_count = 0, duplicate_count = 0;
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(object_count_by_type); i++)
|
|
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(object_count_by_type); i++)
|
|
|
|
|
total_count += object_count_by_type[i];
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(duplicate_count_by_type); i++)
|
|
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(duplicate_count_by_type); i++)
|
|
|
|
|
duplicate_count += duplicate_count_by_type[i];
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "%s statistics:\n", argv[0]);
|
|
|
|
|
|