summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/add.c2
-rw-r--r--builtin/am.c2
-rw-r--r--builtin/branch.c7
-rw-r--r--builtin/checkout.c18
-rw-r--r--builtin/clone.c2
-rw-r--r--builtin/column.c1
-rw-r--r--builtin/commit-graph.c171
-rw-r--r--builtin/commit.c3
-rw-r--r--builtin/config.c144
-rw-r--r--builtin/describe.c2
-rw-r--r--builtin/diff.c2
-rw-r--r--builtin/difftool.c2
-rw-r--r--builtin/fast-export.c11
-rw-r--r--builtin/fetch-pack.c20
-rw-r--r--builtin/fetch.c21
-rw-r--r--builtin/gc.c6
-rw-r--r--builtin/grep.c14
-rw-r--r--builtin/hash-object.c2
-rw-r--r--builtin/help.c2
-rw-r--r--builtin/index-pack.c6
-rw-r--r--builtin/init-db.c2
-rw-r--r--builtin/log.c4
-rw-r--r--builtin/ls-remote.c45
-rw-r--r--builtin/merge-tree.c2
-rw-r--r--builtin/mktag.c3
-rw-r--r--builtin/mv.c6
-rw-r--r--builtin/notes.c2
-rw-r--r--builtin/pack-objects.c6
-rw-r--r--builtin/pack-refs.c3
-rw-r--r--builtin/pull.c2
-rw-r--r--builtin/push.c44
-rw-r--r--builtin/receive-pack.c8
-rw-r--r--builtin/reflog.c2
-rw-r--r--builtin/remote.c2
-rw-r--r--builtin/replace.c4
-rw-r--r--builtin/send-pack.c20
-rw-r--r--builtin/serve.c30
-rw-r--r--builtin/submodule--helper.c25
-rw-r--r--builtin/tag.c2
-rw-r--r--builtin/upload-pack.c74
-rw-r--r--builtin/verify-tag.c2
-rw-r--r--builtin/worktree.c5
42 files changed, 625 insertions, 106 deletions
diff --git a/builtin/add.c b/builtin/add.c
index 9ef7fb02d5..c9e2619a9a 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -9,7 +9,7 @@
#include "lockfile.h"
#include "dir.h"
#include "pathspec.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
#include "cache-tree.h"
#include "run-command.h"
#include "parse-options.h"
diff --git a/builtin/am.c b/builtin/am.c
index 9c82603f70..d834f9e62b 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -6,7 +6,7 @@
#include "cache.h"
#include "config.h"
#include "builtin.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
#include "parse-options.h"
#include "dir.h"
#include "run-command.h"
diff --git a/builtin/branch.c b/builtin/branch.c
index 5bd2a0dd48..efc9ac1922 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -391,7 +391,6 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
struct ref_array array;
int maxwidth = 0;
const char *remote_prefix = "";
- struct strbuf out = STRBUF_INIT;
char *to_free = NULL;
/*
@@ -419,7 +418,10 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
ref_array_sort(sorting, &array);
for (i = 0; i < array.nr; i++) {
- format_ref_array_item(array.items[i], format, &out);
+ struct strbuf out = STRBUF_INIT;
+ struct strbuf err = STRBUF_INIT;
+ if (format_ref_array_item(array.items[i], format, &out, &err))
+ die("%s", err.buf);
if (column_active(colopts)) {
assert(!filter->verbose && "--column and --verbose are incompatible");
/* format to a string_list to let print_columns() do its job */
@@ -428,6 +430,7 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
fwrite(out.buf, 1, out.len, stdout);
putchar('\n');
}
+ strbuf_release(&err);
strbuf_release(&out);
}
diff --git a/builtin/checkout.c b/builtin/checkout.c
index b49b582071..2b3b768eff 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -484,7 +484,8 @@ static int merge_working_tree(const struct checkout_opts *opts,
resolve_undo_clear();
if (opts->force) {
- ret = reset_tree(new_branch_info->commit->tree, opts, 1, writeout_error);
+ ret = reset_tree(get_commit_tree(new_branch_info->commit),
+ opts, 1, writeout_error);
if (ret)
return ret;
} else {
@@ -570,18 +571,23 @@ static int merge_working_tree(const struct checkout_opts *opts,
o.verbosity = 0;
work = write_tree_from_memory(&o);
- ret = reset_tree(new_branch_info->commit->tree, opts, 1,
+ ret = reset_tree(get_commit_tree(new_branch_info->commit),
+ opts, 1,
writeout_error);
if (ret)
return ret;
o.ancestor = old_branch_info->name;
o.branch1 = new_branch_info->name;
o.branch2 = "local";
- ret = merge_trees(&o, new_branch_info->commit->tree, work,
- old_branch_info->commit->tree, &result);
+ ret = merge_trees(&o,
+ get_commit_tree(new_branch_info->commit),
+ work,
+ get_commit_tree(old_branch_info->commit),
+ &result);
if (ret < 0)
exit(128);
- ret = reset_tree(new_branch_info->commit->tree, opts, 0,
+ ret = reset_tree(get_commit_tree(new_branch_info->commit),
+ opts, 0,
writeout_error);
strbuf_release(&o.obuf);
if (ret)
@@ -1002,7 +1008,7 @@ static int parse_branchname_arg(int argc, const char **argv,
*source_tree = parse_tree_indirect(rev);
} else {
parse_commit_or_die(new_branch_info->commit);
- *source_tree = new_branch_info->commit->tree;
+ *source_tree = get_commit_tree(new_branch_info->commit);
}
if (!*source_tree) /* case (1): want a tree */
diff --git a/builtin/clone.c b/builtin/clone.c
index 7df5932b85..84f1473d19 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1135,7 +1135,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (transport->smart_options && !deepen && !filter_options.choice)
transport->smart_options->check_self_contained_and_connected = 1;
- refs = transport_get_remote_refs(transport);
+ refs = transport_get_remote_refs(transport, NULL);
if (refs) {
mapped_refs = wanted_peer_refs(refs, refspec);
diff --git a/builtin/column.c b/builtin/column.c
index 0c3223d64b..5228ccf37a 100644
--- a/builtin/column.c
+++ b/builtin/column.c
@@ -42,7 +42,6 @@ int cmd_column(int argc, const char **argv, const char *prefix)
git_config(column_config, NULL);
memset(&copts, 0, sizeof(copts));
- copts.width = term_columns();
copts.padding = 1;
argc = parse_options(argc, argv, "", options, builtin_column_usage, 0);
if (argc)
diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c
new file mode 100644
index 0000000000..37420ae0fd
--- /dev/null
+++ b/builtin/commit-graph.c
@@ -0,0 +1,171 @@
+#include "builtin.h"
+#include "config.h"
+#include "dir.h"
+#include "lockfile.h"
+#include "parse-options.h"
+#include "commit-graph.h"
+
+static char const * const builtin_commit_graph_usage[] = {
+ N_("git commit-graph [--object-dir <objdir>]"),
+ N_("git commit-graph read [--object-dir <objdir>]"),
+ N_("git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--stdin-commits]"),
+ NULL
+};
+
+static const char * const builtin_commit_graph_read_usage[] = {
+ N_("git commit-graph read [--object-dir <objdir>]"),
+ NULL
+};
+
+static const char * const builtin_commit_graph_write_usage[] = {
+ N_("git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--stdin-commits]"),
+ NULL
+};
+
+static struct opts_commit_graph {
+ const char *obj_dir;
+ int stdin_packs;
+ int stdin_commits;
+ int append;
+} opts;
+
+static int graph_read(int argc, const char **argv)
+{
+ struct commit_graph *graph = NULL;
+ char *graph_name;
+
+ static struct option builtin_commit_graph_read_options[] = {
+ OPT_STRING(0, "object-dir", &opts.obj_dir,
+ N_("dir"),
+ N_("The object directory to store the graph")),
+ OPT_END(),
+ };
+
+ argc = parse_options(argc, argv, NULL,
+ builtin_commit_graph_read_options,
+ builtin_commit_graph_read_usage, 0);
+
+ if (!opts.obj_dir)
+ opts.obj_dir = get_object_directory();
+
+ graph_name = get_commit_graph_filename(opts.obj_dir);
+ graph = load_commit_graph_one(graph_name);
+
+ if (!graph)
+ die("graph file %s does not exist", graph_name);
+ FREE_AND_NULL(graph_name);
+
+ printf("header: %08x %d %d %d %d\n",
+ ntohl(*(uint32_t*)graph->data),
+ *(unsigned char*)(graph->data + 4),
+ *(unsigned char*)(graph->data + 5),
+ *(unsigned char*)(graph->data + 6),
+ *(unsigned char*)(graph->data + 7));
+ printf("num_commits: %u\n", graph->num_commits);
+ printf("chunks:");
+
+ if (graph->chunk_oid_fanout)
+ printf(" oid_fanout");
+ if (graph->chunk_oid_lookup)
+ printf(" oid_lookup");
+ if (graph->chunk_commit_data)
+ printf(" commit_metadata");
+ if (graph->chunk_large_edges)
+ printf(" large_edges");
+ printf("\n");
+
+ return 0;
+}
+
+static int graph_write(int argc, const char **argv)
+{
+ const char **pack_indexes = NULL;
+ int packs_nr = 0;
+ const char **commit_hex = NULL;
+ int commits_nr = 0;
+ const char **lines = NULL;
+ int lines_nr = 0;
+ int lines_alloc = 0;
+
+ static struct option builtin_commit_graph_write_options[] = {
+ OPT_STRING(0, "object-dir", &opts.obj_dir,
+ N_("dir"),
+ N_("The object directory to store the graph")),
+ OPT_BOOL(0, "stdin-packs", &opts.stdin_packs,
+ N_("scan pack-indexes listed by stdin for commits")),
+ OPT_BOOL(0, "stdin-commits", &opts.stdin_commits,
+ N_("start walk at commits listed by stdin")),
+ OPT_BOOL(0, "append", &opts.append,
+ N_("include all commits already in the commit-graph file")),
+ OPT_END(),
+ };
+
+ argc = parse_options(argc, argv, NULL,
+ builtin_commit_graph_write_options,
+ builtin_commit_graph_write_usage, 0);
+
+ if (opts.stdin_packs && opts.stdin_commits)
+ die(_("cannot use both --stdin-commits and --stdin-packs"));
+ if (!opts.obj_dir)
+ opts.obj_dir = get_object_directory();
+
+ if (opts.stdin_packs || opts.stdin_commits) {
+ struct strbuf buf = STRBUF_INIT;
+ lines_nr = 0;
+ lines_alloc = 128;
+ ALLOC_ARRAY(lines, lines_alloc);
+
+ while (strbuf_getline(&buf, stdin) != EOF) {
+ ALLOC_GROW(lines, lines_nr + 1, lines_alloc);
+ lines[lines_nr++] = strbuf_detach(&buf, NULL);
+ }
+
+ if (opts.stdin_packs) {
+ pack_indexes = lines;
+ packs_nr = lines_nr;
+ }
+ if (opts.stdin_commits) {
+ commit_hex = lines;
+ commits_nr = lines_nr;
+ }
+ }
+
+ write_commit_graph(opts.obj_dir,
+ pack_indexes,
+ packs_nr,
+ commit_hex,
+ commits_nr,
+ opts.append);
+
+ return 0;
+}
+
+int cmd_commit_graph(int argc, const char **argv, const char *prefix)
+{
+ static struct option builtin_commit_graph_options[] = {
+ OPT_STRING(0, "object-dir", &opts.obj_dir,
+ N_("dir"),
+ N_("The object directory to store the graph")),
+ OPT_END(),
+ };
+
+ if (argc == 2 && !strcmp(argv[1], "-h"))
+ usage_with_options(builtin_commit_graph_usage,
+ builtin_commit_graph_options);
+
+ git_config(git_default_config, NULL);
+ argc = parse_options(argc, argv, prefix,
+ builtin_commit_graph_options,
+ builtin_commit_graph_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+
+ if (argc > 0) {
+ if (!strcmp(argv[0], "read"))
+ return graph_read(argc, argv);
+ if (!strcmp(argv[0], "write"))
+ return graph_write(argc, argv);
+ }
+
+ usage_with_options(builtin_commit_graph_usage,
+ builtin_commit_graph_options);
+}
diff --git a/builtin/commit.c b/builtin/commit.c
index 37fcb55ab0..5571d4a3e2 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -218,8 +218,7 @@ static int list_paths(struct string_list *list, const char *with_tree,
if (with_tree) {
char *max_prefix = common_prefix(pattern);
- overlay_tree_on_index(&the_index, with_tree,
- max_prefix ? max_prefix : prefix);
+ overlay_tree_on_index(&the_index, with_tree, max_prefix);
free(max_prefix);
}
diff --git a/builtin/config.c b/builtin/config.c
index 01169dd628..69e7270356 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -25,7 +25,8 @@ static char term = '\n';
static int use_global_config, use_system_config, use_local_config;
static struct git_config_source given_config_source;
-static int actions, types;
+static int actions, type;
+static char *default_value;
static int end_null;
static int respect_includes_opt = -1;
static struct config_options config_options;
@@ -55,11 +56,68 @@ static int show_origin;
#define PAGING_ACTIONS (ACTION_LIST | ACTION_GET_ALL | \
ACTION_GET_REGEXP | ACTION_GET_URLMATCH)
-#define TYPE_BOOL (1<<0)
-#define TYPE_INT (1<<1)
-#define TYPE_BOOL_OR_INT (1<<2)
-#define TYPE_PATH (1<<3)
-#define TYPE_EXPIRY_DATE (1<<4)
+#define TYPE_BOOL 1
+#define TYPE_INT 2
+#define TYPE_BOOL_OR_INT 3
+#define TYPE_PATH 4
+#define TYPE_EXPIRY_DATE 5
+#define TYPE_COLOR 6
+
+#define OPT_CALLBACK_VALUE(s, l, v, h, i) \
+ { OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
+ PARSE_OPT_NONEG, option_parse_type, (i) }
+
+static struct option builtin_config_options[];
+
+static int option_parse_type(const struct option *opt, const char *arg,
+ int unset)
+{
+ int new_type, *to_type;
+
+ if (unset) {
+ *((int *) opt->value) = 0;
+ return 0;
+ }
+
+ /*
+ * To support '--<type>' style flags, begin with new_type equal to
+ * opt->defval.
+ */
+ new_type = opt->defval;
+ if (!new_type) {
+ if (!strcmp(arg, "bool"))
+ new_type = TYPE_BOOL;
+ else if (!strcmp(arg, "int"))
+ new_type = TYPE_INT;
+ else if (!strcmp(arg, "bool-or-int"))
+ new_type = TYPE_BOOL_OR_INT;
+ else if (!strcmp(arg, "path"))
+ new_type = TYPE_PATH;
+ else if (!strcmp(arg, "expiry-date"))
+ new_type = TYPE_EXPIRY_DATE;
+ else if (!strcmp(arg, "color"))
+ new_type = TYPE_COLOR;
+ else
+ die(_("unrecognized --type argument, %s"), arg);
+ }
+
+ to_type = opt->value;
+ if (*to_type && *to_type != new_type) {
+ /*
+ * Complain when there is a new type not equal to the old type.
+ * This allows for combinations like '--int --type=int' and
+ * '--type=int --type=int', but disallows ones like '--type=bool
+ * --int' and '--type=bool
+ * --type=int'.
+ */
+ error("only one type at a time.");
+ usage_with_options(builtin_config_usage,
+ builtin_config_options);
+ }
+ *to_type = new_type;
+
+ return 0;
+}
static struct option builtin_config_options[] = {
OPT_GROUP(N_("Config file location")),
@@ -84,16 +142,18 @@ static struct option builtin_config_options[] = {
OPT_BIT(0, "get-color", &actions, N_("find the color configured: slot [default]"), ACTION_GET_COLOR),
OPT_BIT(0, "get-colorbool", &actions, N_("find the color setting: slot [stdout-is-tty]"), ACTION_GET_COLORBOOL),
OPT_GROUP(N_("Type")),
- OPT_BIT(0, "bool", &types, N_("value is \"true\" or \"false\""), TYPE_BOOL),
- OPT_BIT(0, "int", &types, N_("value is decimal number"), TYPE_INT),
- OPT_BIT(0, "bool-or-int", &types, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
- OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH),
- OPT_BIT(0, "expiry-date", &types, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
+ OPT_CALLBACK('t', "type", &type, "", N_("value is given this type"), option_parse_type),
+ OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
+ OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
+ OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
+ OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
+ OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
OPT_GROUP(N_("Other")),
OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")),
+ OPT_STRING(0, "default", &default_value, N_("value"), N_("with --get, use default value when missing entry")),
OPT_END(),
};
@@ -149,30 +209,35 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
if (show_keys)
strbuf_addch(buf, key_delim);
- if (types == TYPE_INT)
+ if (type == TYPE_INT)
strbuf_addf(buf, "%"PRId64,
git_config_int64(key_, value_ ? value_ : ""));
- else if (types == TYPE_BOOL)
+ else if (type == TYPE_BOOL)
strbuf_addstr(buf, git_config_bool(key_, value_) ?
"true" : "false");
- else if (types == TYPE_BOOL_OR_INT) {
+ else if (type == TYPE_BOOL_OR_INT) {
int is_bool, v;
v = git_config_bool_or_int(key_, value_, &is_bool);
if (is_bool)
strbuf_addstr(buf, v ? "true" : "false");
else
strbuf_addf(buf, "%d", v);
- } else if (types == TYPE_PATH) {
+ } else if (type == TYPE_PATH) {
const char *v;
if (git_config_pathname(&v, key_, value_) < 0)
return -1;
strbuf_addstr(buf, v);
free((char *)v);
- } else if (types == TYPE_EXPIRY_DATE) {
+ } else if (type == TYPE_EXPIRY_DATE) {
timestamp_t t;
if (git_config_expiry_date(&t, key_, value_) < 0)
return -1;
strbuf_addf(buf, "%"PRItime, t);
+ } else if (type == TYPE_COLOR) {
+ char v[COLOR_MAXLEN];
+ if (git_config_color(v, key_, value_) < 0)
+ return -1;
+ strbuf_addstr(buf, v);
} else if (value_) {
strbuf_addstr(buf, value_);
} else {
@@ -258,6 +323,16 @@ static int get_value(const char *key_, const char *regex_)
config_with_options(collect_config, &values,
&given_config_source, &config_options);
+ if (!values.nr && default_value) {
+ struct strbuf *item;
+ ALLOC_GROW(values.items, values.nr + 1, values.alloc);
+ item = &values.items[values.nr++];
+ strbuf_init(item, 0);
+ if (format_config(item, key_, default_value) < 0)
+ die(_("failed to format default config value: %s"),
+ default_value);
+ }
+
ret = !values.nr;
for (i = 0; i < values.nr; i++) {
@@ -287,7 +362,7 @@ static char *normalize_value(const char *key, const char *value)
if (!value)
return NULL;
- if (types == 0 || types == TYPE_PATH || types == TYPE_EXPIRY_DATE)
+ if (type == 0 || type == TYPE_PATH || type == TYPE_EXPIRY_DATE)
/*
* We don't do normalization for TYPE_PATH here: If
* the path is like ~/foobar/, we prefer to store
@@ -296,11 +371,11 @@ static char *normalize_value(const char *key, const char *value)
* Also don't do normalization for expiry dates.
*/
return xstrdup(value);
- if (types == TYPE_INT)
+ if (type == TYPE_INT)
return xstrfmt("%"PRId64, git_config_int64(key, value));
- if (types == TYPE_BOOL)
+ if (type == TYPE_BOOL)
return xstrdup(git_config_bool(key, value) ? "true" : "false");
- if (types == TYPE_BOOL_OR_INT) {
+ if (type == TYPE_BOOL_OR_INT) {
int is_bool, v;
v = git_config_bool_or_int(key, value, &is_bool);
if (!is_bool)
@@ -308,8 +383,22 @@ static char *normalize_value(const char *key, const char *value)
else
return xstrdup(v ? "true" : "false");
}
+ if (type == TYPE_COLOR) {
+ char v[COLOR_MAXLEN];
+ if (git_config_color(v, key, value))
+ die("cannot parse color '%s'", value);
+
+ /*
+ * The contents of `v` now contain an ANSI escape
+ * sequence, not suitable for including within a
+ * configuration file. Treat the above as a
+ * "sanity-check", and return the given value, which we
+ * know is representable as valid color code.
+ */
+ return xstrdup(value);
+ }
- die("BUG: cannot normalize type %d", types);
+ die("BUG: cannot normalize type %d", type);
}
static int get_color_found;
@@ -566,12 +655,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
key_delim = '\n';
}
- if (HAS_MULTI_BITS(types)) {
- error("only one type at a time.");
- usage_with_options(builtin_config_usage, builtin_config_options);
- }
-
- if ((actions & (ACTION_GET_COLOR|ACTION_GET_COLORBOOL)) && types) {
+ if ((actions & (ACTION_GET_COLOR|ACTION_GET_COLORBOOL)) && type) {
error("--get-color and variable type are incoherent");
usage_with_options(builtin_config_usage, builtin_config_options);
}
@@ -601,6 +685,12 @@ int cmd_config(int argc, const char **argv, const char *prefix)
usage_with_options(builtin_config_usage, builtin_config_options);
}
+ if (default_value && !(actions & ACTION_GET)) {
+ error("--default is only applicable to --get");
+ usage_with_options(builtin_config_usage,
+ builtin_config_options);
+ }
+
if (actions & PAGING_ACTIONS)
setup_auto_pager("config", 1);
diff --git a/builtin/describe.c b/builtin/describe.c
index de840f96a4..b5afc45846 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -6,7 +6,7 @@
#include "blob.h"
#include "refs.h"
#include "builtin.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
#include "parse-options.h"
#include "revision.h"
#include "diff.h"
diff --git a/builtin/diff.c b/builtin/diff.c
index 16bfb22f73..bfefff3a84 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -398,7 +398,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
if (!obj)
die(_("invalid object '%s' given."), name);
if (obj->type == OBJ_COMMIT)
- obj = &((struct commit *)obj)->tree->object;
+ obj = &get_commit_tree(((struct commit *)obj))->object;
if (obj->type == OBJ_TREE) {
obj->flags |= flags;
diff --git a/builtin/difftool.c b/builtin/difftool.c
index ee8dce019e..aad0e073ee 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -15,7 +15,7 @@
#include "config.h"
#include "builtin.h"
#include "run-command.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
#include "parse-options.h"
#include "argv-array.h"
#include "strbuf.h"
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index a15898d641..ea776e602a 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -578,11 +578,11 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
get_object_mark(&commit->parents->item->object) != 0 &&
!full_tree) {
parse_commit_or_die(commit->parents->item);
- diff_tree_oid(&commit->parents->item->tree->object.oid,
- &commit->tree->object.oid, "", &rev->diffopt);
+ diff_tree_oid(get_commit_tree_oid(commit->parents->item),
+ get_commit_tree_oid(commit), "", &rev->diffopt);
}
else
- diff_root_tree_oid(&commit->tree->object.oid,
+ diff_root_tree_oid(get_commit_tree_oid(commit),
"", &rev->diffopt);
/* Export the referenced blobs, and remember the marks. */
@@ -651,8 +651,11 @@ static void handle_tail(struct object_array *commits, struct rev_info *revs,
struct commit *commit;
while (commits->nr) {
commit = (struct commit *)object_array_pop(commits);
- if (has_unshown_parent(commit))
+ if (has_unshown_parent(commit)) {
+ /* Queue again, to be handled later */
+ add_object_array(&commit->object, NULL, commits);
return;
+ }
handle_commit(commit, revs, paths_of_changed_objects);
}
}
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index a7bc1366ab..1a1bc63566 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -4,6 +4,7 @@
#include "remote.h"
#include "connect.h"
#include "sha1-array.h"
+#include "protocol.h"
static const char fetch_pack_usage[] =
"git fetch-pack [--all] [--stdin] [--quiet | -q] [--keep | -k] [--thin] "
@@ -52,6 +53,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
struct fetch_pack_args args;
struct oid_array shallow = OID_ARRAY_INIT;
struct string_list deepen_not = STRING_LIST_INIT_DUP;
+ struct packet_reader reader;
fetch_if_missing = 0;
@@ -211,10 +213,24 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
if (!conn)
return args.diag_url ? 0 : 1;
}
- get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL, &shallow);
+
+ packet_reader_init(&reader, fd[0], NULL, 0,
+ PACKET_READ_CHOMP_NEWLINE |
+ PACKET_READ_GENTLE_ON_EOF);
+
+ switch (discover_version(&reader)) {
+ case protocol_v2:
+ die("support for protocol v2 not implemented yet");
+ case protocol_v1:
+ case protocol_v0:
+ get_remote_heads(&reader, &ref, 0, NULL, &shallow);
+ break;
+ case protocol_unknown_version:
+ BUG("unknown protocol version");
+ }
ref = fetch_pack(&args, fd, conn, ref, dest, sought, nr_sought,
- &shallow, pack_lockfile_ptr);
+ &shallow, pack_lockfile_ptr, protocol_v0);
if (pack_lockfile) {
printf("lock %s\n", pack_lockfile);
fflush(stdout);
diff --git a/builtin/fetch.c b/builtin/fetch.c
index dcdfc66f09..7ee83ac0f8 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -264,7 +264,7 @@ static void find_non_local_tags(struct transport *transport,
struct string_list_item *item = NULL;
for_each_ref(add_existing, &existing_refs);
- for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) {
+ for (ref = transport_get_remote_refs(transport, NULL); ref; ref = ref->next) {
if (!starts_with(ref->name, "refs/tags/"))
continue;
@@ -346,11 +346,28 @@ static struct ref *get_ref_map(struct transport *transport,
struct ref *rm;
struct ref *ref_map = NULL;
struct ref **tail = &ref_map;
+ struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
/* opportunistically-updated references: */
struct ref *orefs = NULL, **oref_tail = &orefs;
- const struct ref *remote_refs = transport_get_remote_refs(transport);
+ const struct ref *remote_refs;
+
+ for (i = 0; i < refspec_count; i++) {
+ if (!refspecs[i].exact_sha1) {
+ const char *glob = strchr(refspecs[i].src, '*');
+ if (glob)
+ argv_array_pushf(&ref_prefixes, "%.*s",
+ (int)(glob - refspecs[i].src),
+ refspecs[i].src);
+ else
+ expand_ref_prefix(&ref_prefixes, refspecs[i].src);
+ }
+ }
+
+ remote_refs = transport_get_remote_refs(transport, &ref_prefixes);
+
+ argv_array_clear(&ref_prefixes);
if (refspec_count) {
struct refspec *fetch_refspec;
diff --git a/builtin/gc.c b/builtin/gc.c
index 3c7c93e961..c4777b2449 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -494,6 +494,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
pid_t pid;
int daemonized = 0;
int keep_base_pack = -1;
+ timestamp_t dummy;
struct option builtin_gc_options[] = {
OPT__QUIET(&quiet, N_("suppress progress reporting")),
@@ -524,7 +525,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
/* default expiry time, overwritten in gc_config */
gc_config();
if (parse_expiry_date(gc_log_expire, &gc_log_expire_time))
- die(_("Failed to parse gc.logexpiry value %s"), gc_log_expire);
+ die(_("failed to parse gc.logexpiry value %s"), gc_log_expire);
if (pack_refs < 0)
pack_refs = !is_bare_repository();
@@ -534,6 +535,9 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
if (argc > 0)
usage_with_options(builtin_gc_usage, builtin_gc_options);
+ if (prune_expire && parse_expiry_date(prune_expire, &dummy))
+ die(_("failed to parse prune expiry value %s"), prune_expire);
+
if (aggressive) {
argv_array_push(&repack, "-f");
if (aggressive_depth > 0)
diff --git a/builtin/grep.c b/builtin/grep.c
index 5f32d2ce84..6e7bc76785 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -602,8 +602,7 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
}
static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
- struct object *obj, const char *name, const char *path,
- struct repository *repo)
+ struct object *obj, const char *name, const char *path)
{
if (obj->type == OBJ_BLOB)
return grep_oid(opt, &obj->oid, name, 0, path);
@@ -630,7 +629,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
}
init_tree_desc(&tree, data, size);
hit = grep_tree(opt, pathspec, &tree, &base, base.len,
- obj->type == OBJ_COMMIT, repo);
+ obj->type == OBJ_COMMIT, the_repository);
strbuf_release(&base);
free(data);
return hit;
@@ -639,7 +638,6 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
}
static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
- struct repository *repo,
const struct object_array *list)
{
unsigned int i;
@@ -652,11 +650,11 @@ static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
/* load the gitmodules file for this rev */
if (recurse_submodules) {
- submodule_free();
+ submodule_free(the_repository);
gitmodules_config_oid(&real_obj->oid);
}
- if (grep_object(opt, pathspec, real_obj, list->objects[i].name, list->objects[i].path,
- repo)) {
+ if (grep_object(opt, pathspec, real_obj, list->objects[i].name,
+ list->objects[i].path)) {
hit = 1;
if (opt->status_only)
break;
@@ -1108,7 +1106,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
if (cached)
die(_("both --cached and trees are given."));
- hit = grep_objects(&opt, &pathspec, the_repository, &list);
+ hit = grep_objects(&opt, &pathspec, &list);
}
if (num_threads)
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index 526da5c185..a9a3a198c3 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -9,7 +9,7 @@
#include "blob.h"
#include "quote.h"
#include "parse-options.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
/*
* This is to create corrupt objects for debugging and as such it
diff --git a/builtin/help.c b/builtin/help.c
index 598867cfea..2d51071429 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -4,7 +4,7 @@
#include "cache.h"
#include "config.h"
#include "builtin.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
#include "parse-options.h"
#include "run-command.h"
#include "column.h"
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index d81473e722..a2cd29d8f4 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -9,7 +9,7 @@
#include "tree.h"
#include "progress.h"
#include "fsck.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
#include "streaming.h"
#include "thread-utils.h"
#include "packfile.h"
@@ -1271,7 +1271,7 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha
nr_objects - nr_objects_initial);
stop_progress_msg(&progress, msg.buf);
strbuf_release(&msg);
- hashclose(f, tail_hash, 0);
+ finalize_hashfile(f, tail_hash, 0);
hashcpy(read_hash, pack_hash);
fixup_pack_header_footer(output_fd, pack_hash,
curr_pack, nr_objects,
@@ -1593,7 +1593,7 @@ static void read_idx_option(struct pack_idx_option *opts, const char *pack_name)
/*
* Get rid of the idx file as we do not need it anymore.
* NEEDSWORK: extract this bit from free_pack_by_name() in
- * sha1_file.c, perhaps? It shouldn't matter very much as we
+ * sha1-file.c, perhaps? It shouldn't matter very much as we
* know we haven't installed this pack (hence we never have
* read anything from it).
*/
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 68ff4ad75a..2542c5244e 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -7,7 +7,7 @@
#include "config.h"
#include "refs.h"
#include "builtin.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
#include "parse-options.h"
#ifndef DEFAULT_GIT_TEMPLATE_DIR
diff --git a/builtin/log.c b/builtin/log.c
index 71f68a3e4f..75f7ff0441 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -1067,8 +1067,8 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
diff_setup_done(&opts);
- diff_tree_oid(&origin->tree->object.oid,
- &head->tree->object.oid,
+ diff_tree_oid(get_commit_tree_oid(origin),
+ get_commit_tree_oid(head),
"", &opts);
diffcore_std(&opts);
diff_flush(&opts);
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index 540d56429f..ca3f04a839 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -1,7 +1,9 @@
#include "builtin.h"
#include "cache.h"
#include "transport.h"
+#include "ref-filter.h"
#include "remote.h"
+#include "refs.h"
static const char * const ls_remote_usage[] = {
N_("git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
@@ -43,10 +45,14 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
int show_symref_target = 0;
const char *uploadpack = NULL;
const char **pattern = NULL;
+ struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
+ int i;
struct remote *remote;
struct transport *transport;
const struct ref *ref;
+ struct ref_array ref_array;
+ static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
struct option options[] = {
OPT__QUIET(&quiet, N_("do not print remote URL")),
@@ -60,6 +66,8 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
OPT_BIT(0, "refs", &flags, N_("do not show peeled tags"), REF_NORMAL),
OPT_BOOL(0, "get-url", &get_url,
N_("take url.<base>.insteadOf into account")),
+ OPT_CALLBACK(0 , "sort", sorting_tail, N_("key"),
+ N_("field name to sort on"), &parse_opt_ref_sorting),
OPT_SET_INT_F(0, "exit-code", &status,
N_("exit with exit code 2 if no matching refs are found"),
2, PARSE_OPT_NOCOMPLETE),
@@ -68,6 +76,8 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
OPT_END()
};
+ memset(&ref_array, 0, sizeof(ref_array));
+
argc = parse_options(argc, argv, prefix, options, ls_remote_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
dest = argv[0];
@@ -75,8 +85,17 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
if (argc > 1) {
int i;
pattern = xcalloc(argc, sizeof(const char *));
- for (i = 1; i < argc; i++)
+ for (i = 1; i < argc; i++) {
+ const char *glob;
pattern[i - 1] = xstrfmt("*/%s", argv[i]);
+
+ glob = strchr(argv[i], '*');
+ if (glob)
+ argv_array_pushf(&ref_prefixes, "%.*s",
+ (int)(glob - argv[i]), argv[i]);
+ else
+ expand_ref_prefix(&ref_prefixes, argv[i]);
+ }
}
remote = remote_get(dest);
@@ -90,6 +109,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
if (get_url) {
printf("%s\n", *remote->url);
+ UNLEAK(sorting);
return 0;
}
@@ -97,21 +117,36 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
if (uploadpack != NULL)
transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
- ref = transport_get_remote_refs(transport);
- if (transport_disconnect(transport))
+ ref = transport_get_remote_refs(transport, &ref_prefixes);
+ if (transport_disconnect(transport)) {
+ UNLEAK(sorting);
return 1;
+ }
if (!dest && !quiet)
fprintf(stderr, "From %s\n", *remote->url);
for ( ; ref; ref = ref->next) {
+ struct ref_array_item *item;
if (!check_ref_type(ref, flags))
continue;
if (!tail_match(pattern, ref->name))
continue;
+ item = ref_array_push(&ref_array, ref->name, &ref->old_oid);
+ item->symref = xstrdup_or_null(ref->symref);
+ }
+
+ if (sorting)
+ ref_array_sort(sorting, &ref_array);
+
+ for (i = 0; i < ref_array.nr; i++) {
+ const struct ref_array_item *ref = ref_array.items[i];
if (show_symref_target && ref->symref)
- printf("ref: %s\t%s\n", ref->symref, ref->name);
- printf("%s\t%s\n", oid_to_hex(&ref->old_oid), ref->name);
+ printf("ref: %s\t%s\n", ref->symref, ref->refname);
+ printf("%s\t%s\n", oid_to_hex(&ref->objectname), ref->refname);
status = 0; /* we found something */
}
+
+ UNLEAK(sorting);
+ UNLEAK(ref_array);
return status;
}
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index 32736e0b10..bf01e05808 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -2,7 +2,7 @@
#include "tree-walk.h"
#include "xdiff-interface.h"
#include "blob.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
#include "merge-blobs.h"
static const char merge_tree_usage[] = "git merge-tree <base-tree> <branch1> <branch2>";
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 9f5a50a8fd..82a6e86077 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -1,5 +1,6 @@
#include "builtin.h"
#include "tag.h"
+#include "replace-object.h"
/*
* A signature file has a very simple fixed format: four lines
@@ -24,7 +25,7 @@ static int verify_object(const struct object_id *oid, const char *expected_type)
enum object_type type;
unsigned long size;
void *buffer = read_object_file(oid, &type, &size);
- const struct object_id *repl = lookup_replace_object(oid);
+ const struct object_id *repl = lookup_replace_object(the_repository, oid);
if (buffer) {
if (type == type_from_string(expected_type))
diff --git a/builtin/mv.c b/builtin/mv.c
index 6d141f7a53..7a63667d64 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -276,10 +276,12 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
die_errno(_("renaming '%s' failed"), src);
}
if (submodule_gitfile[i]) {
- if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR)
- connect_work_tree_and_git_dir(dst, submodule_gitfile[i]);
if (!update_path_in_gitmodules(src, dst))
gitmodules_modified = 1;
+ if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR)
+ connect_work_tree_and_git_dir(dst,
+ submodule_gitfile[i],
+ 1);
}
if (mode == WORKING_DIRECTORY)
diff --git a/builtin/notes.c b/builtin/notes.c
index 921e08d5bf..e5bf80eef1 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -14,7 +14,7 @@
#include "blob.h"
#include "pretty.h"
#include "refs.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
#include "run-command.h"
#include "parse-options.h"
#include "string-list.h"
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 6a1346c41f..0bfd33ea27 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -839,11 +839,11 @@ static void write_pack_file(void)
* If so, rewrite it like in fast-import
*/
if (pack_to_stdout) {
- hashclose(f, oid.hash, CSUM_CLOSE);
+ finalize_hashfile(f, oid.hash, CSUM_HASH_IN_STREAM | CSUM_CLOSE);
} else if (nr_written == nr_remaining) {
- hashclose(f, oid.hash, CSUM_FSYNC);
+ finalize_hashfile(f, oid.hash, CSUM_HASH_IN_STREAM | CSUM_FSYNC | CSUM_CLOSE);
} else {
- int fd = hashclose(f, oid.hash, 0);
+ int fd = finalize_hashfile(f, oid.hash, 0);
fixup_pack_header_footer(fd, oid.hash, pack_tmp_name,
nr_written, oid.hash, offset);
close(fd);
diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c
index b106a392a4..f3353564f9 100644
--- a/builtin/pack-refs.c
+++ b/builtin/pack-refs.c
@@ -1,6 +1,7 @@
#include "builtin.h"
#include "parse-options.h"
#include "refs.h"
+#include "repository.h"
static char const * const pack_refs_usage[] = {
N_("git pack-refs [<options>]"),
@@ -17,5 +18,5 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix)
};
if (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0))
usage_with_options(pack_refs_usage, opts);
- return refs_pack_refs(get_main_ref_store(), flags);
+ return refs_pack_refs(get_main_ref_store(the_repository), flags);
}
diff --git a/builtin/pull.c b/builtin/pull.c
index e32d6cd5b4..71aac5005e 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -9,7 +9,7 @@
#include "config.h"
#include "builtin.h"
#include "parse-options.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
#include "run-command.h"
#include "sha1-array.h"
#include "remote.h"
diff --git a/builtin/push.c b/builtin/push.c
index 013c20d616..ac3705370e 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -12,12 +12,40 @@
#include "submodule.h"
#include "submodule-config.h"
#include "send-pack.h"
+#include "color.h"
static const char * const push_usage[] = {
N_("git push [<options>] [<repository> [<refspec>...]]"),
NULL,
};
+static int push_use_color = -1;
+static char push_colors[][COLOR_MAXLEN] = {
+ GIT_COLOR_RESET,
+ GIT_COLOR_RED, /* ERROR */
+};
+
+enum color_push {
+ PUSH_COLOR_RESET = 0,
+ PUSH_COLOR_ERROR = 1
+};
+
+static int parse_push_color_slot(const char *slot)
+{
+ if (!strcasecmp(slot, "reset"))
+ return PUSH_COLOR_RESET;
+ if (!strcasecmp(slot, "error"))
+ return PUSH_COLOR_ERROR;
+ return -1;
+}
+
+static const char *push_get_color(enum color_push ix)
+{
+ if (want_color_stderr(push_use_color))
+ return push_colors[ix];
+ return "";
+}
+
static int thin = 1;
static int deleterefs;
static const char *receivepack;
@@ -337,8 +365,11 @@ static int push_with_options(struct transport *transport, int flags)
fprintf(stderr, _("Pushing to %s\n"), transport->url);
err = transport_push(transport, refspec_nr, refspec, flags,
&reject_reasons);
- if (err != 0)
+ if (err != 0) {
+ fprintf(stderr, "%s", push_get_color(PUSH_COLOR_ERROR));
error(_("failed to push some refs to '%s'"), transport->url);
+ fprintf(stderr, "%s", push_get_color(PUSH_COLOR_RESET));
+ }
err |= transport_disconnect(transport);
if (!err)
@@ -467,6 +498,7 @@ static void set_push_cert_flags(int *flags, int v)
static int git_push_config(const char *k, const char *v, void *cb)
{
+ const char *slot_name;
int *flags = cb;
int status;
@@ -514,6 +546,16 @@ static int git_push_config(const char *k, const char *v, void *cb)
else
string_list_append(&push_options_config, v);
return 0;
+ } else if (!strcmp(k, "color.push")) {
+ push_use_color = git_config_colorbool(k, v);
+ return 0;
+ } else if (skip_prefix(k, "color.push.", &slot_name)) {
+ int slot = parse_push_color_slot(slot_name);
+ if (slot < 0)
+ return 0;
+ if (!v)
+ return config_error_nonbool(k);
+ return color_parse(v, push_colors[slot]);
}
return git_default_config(k, v, NULL);
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index c4272fbc96..0dd163280d 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -7,7 +7,7 @@
#include "pkt-line.h"
#include "sideband.h"
#include "run-command.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
#include "commit.h"
#include "object.h"
#include "remote.h"
@@ -1965,6 +1965,12 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
unpack_limit = receive_unpack_limit;
switch (determine_protocol_version_server()) {
+ case protocol_v2:
+ /*
+ * push support for protocol v2 has not been implemented yet,
+ * so ignore the request to use v2 and fallback to using v0.
+ */
+ break;
case protocol_v1:
/*
* v1 is just the original protocol with a version string,
diff --git a/builtin/reflog.c b/builtin/reflog.c
index a89bd1dd25..a48984d37e 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -154,7 +154,7 @@ static int commit_is_complete(struct commit *commit)
for (i = 0; i < found.nr; i++) {
struct commit *c =
(struct commit *)found.objects[i].item;
- if (!tree_is_complete(&c->tree->object.oid)) {
+ if (!tree_is_complete(get_commit_tree_oid(c))) {
is_incomplete = 1;
c->object.flags |= INCOMPLETE;
}
diff --git a/builtin/remote.c b/builtin/remote.c
index 805ffc05cd..8708e584e9 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -862,7 +862,7 @@ static int get_remote_ref_states(const char *name,
if (query) {
transport = transport_get(states->remote, states->remote->url_nr > 0 ?
states->remote->url[0] : NULL);
- remote_refs = transport_get_remote_refs(transport);
+ remote_refs = transport_get_remote_refs(transport, NULL);
transport_disconnect(transport);
states->queried = 1;
diff --git a/builtin/replace.c b/builtin/replace.c
index 935647be6b..237ea656cf 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -14,6 +14,8 @@
#include "refs.h"
#include "parse-options.h"
#include "run-command.h"
+#include "object-store.h"
+#include "repository.h"
#include "tag.h"
static const char * const git_replace_usage[] = {
@@ -83,7 +85,7 @@ static int list_replace_refs(const char *pattern, const char *format)
"valid formats are 'short', 'medium' and 'long'\n",
format);
- for_each_replace_ref(show_reference, (void *)&data);
+ for_each_replace_ref(the_repository, show_reference, (void *)&data);
return 0;
}
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index fc4f0bb5fb..b5427f75e3 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -14,6 +14,7 @@
#include "sha1-array.h"
#include "gpg-interface.h"
#include "gettext.h"
+#include "protocol.h"
static const char * const send_pack_usage[] = {
N_("git send-pack [--all | --mirror] [--dry-run] [--force] "
@@ -154,6 +155,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
int progress = -1;
int from_stdin = 0;
struct push_cas_option cas = {0};
+ struct packet_reader reader;
struct option options[] = {
OPT__VERBOSITY(&verbose),
@@ -256,8 +258,22 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
args.verbose ? CONNECT_VERBOSE : 0);
}
- get_remote_heads(fd[0], NULL, 0, &remote_refs, REF_NORMAL,
- &extra_have, &shallow);
+ packet_reader_init(&reader, fd[0], NULL, 0,
+ PACKET_READ_CHOMP_NEWLINE |
+ PACKET_READ_GENTLE_ON_EOF);
+
+ switch (discover_version(&reader)) {
+ case protocol_v2:
+ die("support for protocol v2 not implemented yet");
+ break;
+ case protocol_v1:
+ case protocol_v0:
+ get_remote_heads(&reader, &remote_refs, REF_NORMAL,
+ &extra_have, &shallow);
+ break;
+ case protocol_unknown_version:
+ BUG("unknown protocol version");
+ }
transport_verify_remote_names(nr_refspecs, refspecs);
diff --git a/builtin/serve.c b/builtin/serve.c
new file mode 100644
index 0000000000..d3fd240bb3
--- /dev/null
+++ b/builtin/serve.c
@@ -0,0 +1,30 @@
+#include "cache.h"
+#include "builtin.h"
+#include "parse-options.h"
+#include "serve.h"
+
+static char const * const serve_usage[] = {
+ N_("git serve [<options>]"),
+ NULL
+};
+
+int cmd_serve(int argc, const char **argv, const char *prefix)
+{
+ struct serve_options opts = SERVE_OPTIONS_INIT;
+
+ struct option options[] = {
+ OPT_BOOL(0, "stateless-rpc", &opts.stateless_rpc,
+ N_("quit after a single request/response exchange")),
+ OPT_BOOL(0, "advertise-capabilities", &opts.advertise_capabilities,
+ N_("exit immediately after advertising capabilities")),
+ OPT_END()
+ };
+
+ /* ignore all unknown cmdline switches for now */
+ argc = parse_options(argc, argv, prefix, options, serve_usage,
+ PARSE_OPT_KEEP_DASHDASH |
+ PARSE_OPT_KEEP_UNKNOWN);
+ serve(&opts);
+
+ return 0;
+}
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index a404df3ea4..c2403a915f 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -455,7 +455,7 @@ static void init_submodule(const char *path, const char *prefix,
displaypath = get_submodule_displaypath(path, prefix);
- sub = submodule_from_path(&null_oid, path);
+ sub = submodule_from_path(the_repository, &null_oid, path);
if (!sub)
die(_("No url found for submodule path '%s' in .gitmodules"),
@@ -596,8 +596,12 @@ static void print_status(unsigned int flags, char state, const char *path,
printf("%c%s %s", state, oid_to_hex(oid), displaypath);
- if (state == ' ' || state == '+')
- printf(" (%s)", compute_rev_name(path, oid_to_hex(oid)));
+ if (state == ' ' || state == '+') {
+ const char *name = compute_rev_name(path, oid_to_hex(oid));
+
+ if (name)
+ printf(" (%s)", name);
+ }
printf("\n");
}
@@ -622,7 +626,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
struct rev_info rev;
int diff_files_result;
- if (!submodule_from_path(&null_oid, path))
+ if (!submodule_from_path(the_repository, &null_oid, path))
die(_("no submodule mapping found in .gitmodules for path '%s'"),
path);
@@ -746,7 +750,7 @@ static int module_name(int argc, const char **argv, const char *prefix)
if (argc != 2)
usage(_("git submodule--helper name <path>"));
- sub = submodule_from_path(&null_oid, argv[1]);
+ sub = submodule_from_path(the_repository, &null_oid, argv[1]);
if (!sub)
die(_("no submodule mapping found in .gitmodules for path '%s'"),
@@ -777,7 +781,7 @@ static void sync_submodule(const char *path, const char *prefix,
if (!is_submodule_active(the_repository, path))
return;
- sub = submodule_from_path(&null_oid, path);
+ sub = submodule_from_path(the_repository, &null_oid, path);
if (sub && sub->url) {
if (starts_with_dot_dot_slash(sub->url) ||
@@ -930,7 +934,7 @@ static void deinit_submodule(const char *path, const char *prefix,
struct strbuf sb_config = STRBUF_INIT;
char *sub_git_dir = xstrfmt("%s/.git", path);
- sub = submodule_from_path(&null_oid, path);
+ sub = submodule_from_path(the_repository, &null_oid, path);
if (!sub || !sub->name)
goto cleanup;
@@ -1264,8 +1268,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)
strbuf_reset(&sb);
}
- /* Connect module worktree and git dir */
- connect_work_tree_and_git_dir(path, sm_gitdir);
+ connect_work_tree_and_git_dir(path, sm_gitdir, 0);
p = git_pathdup_submodule(path, "config");
if (!p)
@@ -1372,7 +1375,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
goto cleanup;
}
- sub = submodule_from_path(&null_oid, ce->name);
+ sub = submodule_from_path(the_repository, &null_oid, ce->name);
if (suc->recursive_prefix)
displaypath = relative_path(suc->recursive_prefix,
@@ -1655,7 +1658,7 @@ static const char *remote_submodule_branch(const char *path)
const char *branch = NULL;
char *key;
- sub = submodule_from_path(&null_oid, path);
+ sub = submodule_from_path(the_repository, &null_oid, path);
if (!sub)
return NULL;
diff --git a/builtin/tag.c b/builtin/tag.c
index 8cff6d0b72..46a5c6a1da 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -118,7 +118,7 @@ static int verify_tag(const char *name, const char *ref,
return -1;
if (format->format)
- pretty_print_ref(name, oid->hash, format);
+ pretty_print_ref(name, oid, format);
return 0;
}
diff --git a/builtin/upload-pack.c b/builtin/upload-pack.c
new file mode 100644
index 0000000000..decde5a3b1
--- /dev/null
+++ b/builtin/upload-pack.c
@@ -0,0 +1,74 @@
+#include "cache.h"
+#include "builtin.h"
+#include "exec-cmd.h"
+#include "pkt-line.h"
+#include "parse-options.h"
+#include "protocol.h"
+#include "upload-pack.h"
+#include "serve.h"
+
+static const char * const upload_pack_usage[] = {
+ N_("git upload-pack [<options>] <dir>"),
+ NULL
+};
+
+int cmd_upload_pack(int argc, const char **argv, const char *prefix)
+{
+ const char *dir;
+ int strict = 0;
+ struct upload_pack_options opts = { 0 };
+ struct serve_options serve_opts = SERVE_OPTIONS_INIT;
+ struct option options[] = {
+ OPT_BOOL(0, "stateless-rpc", &opts.stateless_rpc,
+ N_("quit after a single request/response exchange")),
+ OPT_BOOL(0, "advertise-refs", &opts.advertise_refs,
+ N_("exit immediately after initial ref advertisement")),
+ OPT_BOOL(0, "strict", &strict,
+ N_("do not try <directory>/.git/ if <directory> is no Git directory")),
+ OPT_INTEGER(0, "timeout", &opts.timeout,
+ N_("interrupt transfer after <n> seconds of inactivity")),
+ OPT_END()
+ };
+
+ packet_trace_identity("upload-pack");
+ check_replace_refs = 0;
+
+ argc = parse_options(argc, argv, NULL, options, upload_pack_usage, 0);
+
+ if (argc != 1)
+ usage_with_options(upload_pack_usage, options);
+
+ if (opts.timeout)
+ opts.daemon_mode = 1;
+
+ setup_path();
+
+ dir = argv[0];
+
+ if (!enter_repo(dir, strict))
+ die("'%s' does not appear to be a git repository", dir);
+
+ switch (determine_protocol_version_server()) {
+ case protocol_v2:
+ serve_opts.advertise_capabilities = opts.advertise_refs;
+ serve_opts.stateless_rpc = opts.stateless_rpc;
+ serve(&serve_opts);
+ break;
+ case protocol_v1:
+ /*
+ * v1 is just the original protocol with a version string,
+ * so just fall through after writing the version string.
+ */
+ if (opts.advertise_refs || !opts.stateless_rpc)
+ packet_write_fmt(1, "version 1\n");
+
+ /* fallthrough */
+ case protocol_v0:
+ upload_pack(&opts);
+ break;
+ case protocol_unknown_version:
+ BUG("unknown protocol version");
+ }
+
+ return 0;
+}
diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c
index ad7b79fa5c..6fa04b751a 100644
--- a/builtin/verify-tag.c
+++ b/builtin/verify-tag.c
@@ -72,7 +72,7 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)
}
if (format.format)
- pretty_print_ref(name, oid.hash, &format);
+ pretty_print_ref(name, &oid, &format);
}
return had_error;
}
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 40a438ed6c..30647b30c5 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -783,8 +783,9 @@ static int remove_worktree(int ac, const char **av, const char *prefix)
{
int force = 0;
struct option options[] = {
- OPT_BOOL(0, "force", &force,
- N_("force removing even if the worktree is dirty")),
+ OPT__FORCE(&force,
+ N_("force removing even if the worktree is dirty"),
+ PARSE_OPT_NOCOMPLETE),
OPT_END()
};
struct worktree **worktrees, *wt;