aboutsummaryrefslogtreecommitdiffstats
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/branch.c32
-rw-r--r--builtin/check-ref-format.c2
-rw-r--r--builtin/clone.c23
-rw-r--r--builtin/credential.c2
-rw-r--r--builtin/describe.c2
-rw-r--r--builtin/diff.c6
-rw-r--r--builtin/difftool.c16
-rw-r--r--builtin/fast-export.c79
-rw-r--r--builtin/fast-import.c10
-rw-r--r--builtin/fetch-pack.c6
-rw-r--r--builtin/fetch.c274
-rw-r--r--builtin/for-each-ref.c33
-rw-r--r--builtin/for-each-repo.c14
-rw-r--r--builtin/fsck.c36
-rw-r--r--builtin/fsmonitor--daemon.c2
-rw-r--r--builtin/gc.c27
-rw-r--r--builtin/get-tar-commit-id.c6
-rw-r--r--builtin/index-pack.c5
-rw-r--r--builtin/log.c23
-rw-r--r--builtin/ls-files.c5
-rw-r--r--builtin/ls-remote.c1
-rw-r--r--builtin/mailsplit.c2
-rw-r--r--builtin/merge-index.c2
-rw-r--r--builtin/merge-ours.c2
-rw-r--r--builtin/merge-recursive.c2
-rw-r--r--builtin/mktag.c2
-rw-r--r--builtin/pack-objects.c16
-rw-r--r--builtin/pack-redundant.c3
-rw-r--r--builtin/rebase.c126
-rw-r--r--builtin/receive-pack.c17
-rw-r--r--builtin/reflog.c1
-rw-r--r--builtin/remote-ext.c2
-rw-r--r--builtin/remote-fd.c2
-rw-r--r--builtin/repack.c64
-rw-r--r--builtin/revert.c29
-rw-r--r--builtin/send-pack.c3
-rw-r--r--builtin/sparse-checkout.c137
-rw-r--r--builtin/stash.c2
-rw-r--r--builtin/submodule--helper.c9
-rw-r--r--builtin/tag.c7
-rw-r--r--builtin/unpack-file.c2
-rw-r--r--builtin/unpack-objects.c2
-rw-r--r--builtin/upload-archive.c2
-rw-r--r--builtin/var.c2
-rw-r--r--builtin/worktree.c3
-rw-r--r--builtin/write-tree.c4
46 files changed, 681 insertions, 366 deletions
diff --git a/builtin/branch.c b/builtin/branch.c
index 1fb11d55e6..501c47657c 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -46,6 +46,7 @@ static const char *head;
static struct object_id head_oid;
static int recurse_submodules = 0;
static int submodule_propagate_branches = 0;
+static int omit_empty = 0;
static int branch_use_color = -1;
static char branch_colors[][COLOR_MAXLEN] = {
@@ -222,10 +223,11 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
struct string_list_item *item;
int branch_name_pos;
+ const char *fmt_remotes = "refs/remotes/%s";
switch (kinds) {
case FILTER_REFS_REMOTES:
- fmt = "refs/remotes/%s";
+ fmt = fmt_remotes;
/* For subsequent UI messages */
remote_branch = 1;
allowed_interpret = INTERPRET_BRANCH_REMOTE;
@@ -269,9 +271,25 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
| RESOLVE_REF_ALLOW_BAD_NAME,
&oid, &flags);
if (!target) {
- error(remote_branch
- ? _("remote-tracking branch '%s' not found.")
- : _("branch '%s' not found."), bname.buf);
+ if (remote_branch) {
+ error(_("remote-tracking branch '%s' not found."), bname.buf);
+ } else {
+ char *virtual_name = mkpathdup(fmt_remotes, bname.buf);
+ char *virtual_target = resolve_refdup(virtual_name,
+ RESOLVE_REF_READING
+ | RESOLVE_REF_NO_RECURSE
+ | RESOLVE_REF_ALLOW_BAD_NAME,
+ &oid, &flags);
+ FREE_AND_NULL(virtual_name);
+
+ if (virtual_target)
+ error(_("branch '%s' not found.\n"
+ "Did you forget --remote?"),
+ bname.buf);
+ else
+ error(_("branch '%s' not found."), bname.buf);
+ FREE_AND_NULL(virtual_target);
+ }
ret = 1;
continue;
}
@@ -454,6 +472,7 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
if (verify_ref_format(format))
die(_("unable to parse format string"));
+ filter_ahead_behind(the_repository, format, &array);
ref_array_sort(sorting, &array);
for (i = 0; i < array.nr; i++) {
@@ -467,7 +486,8 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
string_list_append(output, out.buf);
} else {
fwrite(out.buf, 1, out.len, stdout);
- putchar('\n');
+ if (out.len || !omit_empty)
+ putchar('\n');
}
}
@@ -676,6 +696,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
OPT_BIT('D', NULL, &delete, N_("delete branch (even if not merged)"), 2),
OPT_BIT('m', "move", &rename, N_("move/rename a branch and its reflog"), 1),
OPT_BIT('M', NULL, &rename, N_("move/rename a branch, even if target exists"), 2),
+ OPT_BOOL(0, "omit-empty", &omit_empty,
+ N_("do not output a newline after empty formatted refs")),
OPT_BIT('c', "copy", &copy, N_("copy a branch and its reflog"), 1),
OPT_BIT('C', NULL, &copy, N_("copy a branch, even if target exists"), 2),
OPT_BOOL('l', "list", &list, N_("list branch names")),
diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c
index b026346742..57f0505070 100644
--- a/builtin/check-ref-format.c
+++ b/builtin/check-ref-format.c
@@ -61,6 +61,8 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
char *to_free = NULL;
int ret = 1;
+ BUG_ON_NON_EMPTY_PREFIX(prefix);
+
if (argc == 2 && !strcmp(argv[1], "-h"))
usage(builtin_check_ref_format_usage);
diff --git a/builtin/clone.c b/builtin/clone.c
index fa300f483e..15f9912b4c 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -336,8 +336,18 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
iter = dir_iterator_begin(src->buf, DIR_ITERATOR_PEDANTIC);
- if (!iter)
+ if (!iter) {
+ if (errno == ENOTDIR) {
+ int saved_errno = errno;
+ struct stat st;
+
+ if (!lstat(src->buf, &st) && S_ISLNK(st.st_mode))
+ die(_("'%s' is a symlink, refusing to clone with --local"),
+ src->buf);
+ errno = saved_errno;
+ }
die_errno(_("failed to start iterator over '%s'"), src->buf);
+ }
strbuf_addch(src, '/');
src_len = src->len;
@@ -919,6 +929,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
int err = 0, complete_refs_before_fetch = 1;
int submodule_progress;
int filter_submodules = 0;
+ int hash_algo;
struct transport_ls_refs_options transport_ls_refs_options =
TRANSPORT_LS_REFS_OPTIONS_INIT;
@@ -1307,15 +1318,15 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
}
}
- if (mapped_refs) {
- int hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));
-
/*
* Now that we know what algorithm the remote side is using,
* let's set ours to the same thing.
*/
- initialize_repository_version(hash_algo, 1);
- repo_set_hash_algo(the_repository, hash_algo);
+ hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));
+ initialize_repository_version(hash_algo, 1);
+ repo_set_hash_algo(the_repository, hash_algo);
+
+ if (mapped_refs) {
/*
* transport_get_remote_refs() may return refs with null sha-1
* in mapped_refs (see struct transport->get_refs_list
diff --git a/builtin/credential.c b/builtin/credential.c
index d7b304fa08..7010752987 100644
--- a/builtin/credential.c
+++ b/builtin/credential.c
@@ -6,7 +6,7 @@
static const char usage_msg[] =
"git credential (fill|approve|reject)";
-int cmd_credential(int argc, const char **argv, const char *prefix)
+int cmd_credential(int argc, const char **argv, const char *prefix UNUSED)
{
const char *op;
struct credential c = CREDENTIAL_INIT;
diff --git a/builtin/describe.c b/builtin/describe.c
index d360b1d12a..55b4baaa22 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -659,6 +659,8 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
int fd, result;
setup_work_tree();
+ prepare_repo_settings(the_repository);
+ the_repository->settings.command_requires_full_index = 0;
repo_read_index(the_repository);
refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED,
NULL, NULL, NULL);
diff --git a/builtin/diff.c b/builtin/diff.c
index 457dee1445..7b64659fe7 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -77,7 +77,7 @@ static void stuff_change(struct diff_options *opt,
}
static int builtin_diff_b_f(struct rev_info *revs,
- int argc, const char **argv,
+ int argc, const char **argv UNUSED,
struct object_array_entry **blob)
{
/* Blob vs file in the working tree*/
@@ -112,7 +112,7 @@ static int builtin_diff_b_f(struct rev_info *revs,
}
static int builtin_diff_blobs(struct rev_info *revs,
- int argc, const char **argv,
+ int argc, const char **argv UNUSED,
struct object_array_entry **blob)
{
const unsigned mode = canon_mode(S_IFREG | 0644);
@@ -212,7 +212,7 @@ static int builtin_diff_tree(struct rev_info *revs,
}
static int builtin_diff_combined(struct rev_info *revs,
- int argc, const char **argv,
+ int argc, const char **argv UNUSED,
struct object_array_entry *ent,
int ents, int first_non_parent)
{
diff --git a/builtin/difftool.c b/builtin/difftool.c
index 409507983f..0049342f5c 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -693,7 +693,7 @@ static int run_file_diff(int prompt, const char *prefix,
int cmd_difftool(int argc, const char **argv, const char *prefix)
{
- int use_gui_tool = 0, dir_diff = 0, prompt = -1, symlinks = 0,
+ int use_gui_tool = -1, dir_diff = 0, prompt = -1, symlinks = 0,
tool_help = 0, no_index = 0;
static char *difftool_cmd = NULL, *extcmd = NULL;
struct option builtin_difftool_options[] = {
@@ -743,13 +743,21 @@ int cmd_difftool(int argc, const char **argv, const char *prefix)
} else if (dir_diff)
die(_("options '%s' and '%s' cannot be used together"), "--dir-diff", "--no-index");
- die_for_incompatible_opt3(use_gui_tool, "--gui",
+ die_for_incompatible_opt3(use_gui_tool == 1, "--gui",
!!difftool_cmd, "--tool",
!!extcmd, "--extcmd");
- if (use_gui_tool)
+ /*
+ * Explicitly specified GUI option is forwarded to git-mergetool--lib.sh;
+ * empty or unset means "use the difftool.guiDefault config or default to
+ * false".
+ */
+ if (use_gui_tool == 1)
setenv("GIT_MERGETOOL_GUI", "true", 1);
- else if (difftool_cmd) {
+ else if (use_gui_tool == 0)
+ setenv("GIT_MERGETOOL_GUI", "false", 1);
+
+ if (difftool_cmd) {
if (*difftool_cmd)
setenv("GIT_DIFF_TOOL", difftool_cmd, 1);
else
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index c7835ea079..9a95f6a1a8 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -112,7 +112,7 @@ static struct decoration idnums;
static uint32_t last_idnum;
struct anonymized_entry {
struct hashmap_entry hash;
- const char *anon;
+ char *anon;
const char orig[FLEX_ARRAY];
};
@@ -141,43 +141,56 @@ static int anonymized_entry_cmp(const void *cmp_data UNUSED,
return strcmp(a->orig, b->orig);
}
+static struct anonymized_entry *add_anonymized_entry(struct hashmap *map,
+ unsigned hash,
+ const char *orig, size_t len,
+ char *anon)
+{
+ struct anonymized_entry *ret, *old;
+
+ if (!map->cmpfn)
+ hashmap_init(map, anonymized_entry_cmp, NULL, 0);
+
+ FLEX_ALLOC_MEM(ret, orig, orig, len);
+ hashmap_entry_init(&ret->hash, hash);
+ ret->anon = anon;
+ old = hashmap_put_entry(map, ret, hash);
+
+ if (old) {
+ free(old->anon);
+ free(old);
+ }
+
+ return ret;
+}
+
/*
* Basically keep a cache of X->Y so that we can repeatedly replace
* the same anonymized string with another. The actual generation
* is farmed out to the generate function.
*/
static const char *anonymize_str(struct hashmap *map,
- char *(*generate)(void *),
- const char *orig, size_t len,
- void *data)
+ char *(*generate)(void),
+ const char *orig, size_t len)
{
struct anonymized_entry_key key;
struct anonymized_entry *ret;
- if (!map->cmpfn)
- hashmap_init(map, anonymized_entry_cmp, NULL, 0);
-
hashmap_entry_init(&key.hash, memhash(orig, len));
key.orig = orig;
key.orig_len = len;
/* First check if it's a token the user configured manually... */
- if (anonymized_seeds.cmpfn)
- ret = hashmap_get_entry(&anonymized_seeds, &key, hash, &key);
- else
- ret = NULL;
+ ret = hashmap_get_entry(&anonymized_seeds, &key, hash, &key);
/* ...otherwise check if we've already seen it in this context... */
if (!ret)
ret = hashmap_get_entry(map, &key, hash, &key);
/* ...and finally generate a new mapping if necessary */
- if (!ret) {
- FLEX_ALLOC_MEM(ret, orig, orig, len);
- hashmap_entry_init(&ret->hash, key.hash.hash);
- ret->anon = generate(data);
- hashmap_put(map, &ret->hash);
- }
+ if (!ret)
+ ret = add_anonymized_entry(map, key.hash.hash,
+ orig, len, generate());
return ret->anon;
}
@@ -190,12 +203,12 @@ static const char *anonymize_str(struct hashmap *map,
*/
static void anonymize_path(struct strbuf *out, const char *path,
struct hashmap *map,
- char *(*generate)(void *))
+ char *(*generate)(void))
{
while (*path) {
const char *end_of_component = strchrnul(path, '/');
size_t len = end_of_component - path;
- const char *c = anonymize_str(map, generate, path, len, NULL);
+ const char *c = anonymize_str(map, generate, path, len);
strbuf_addstr(out, c);
path = end_of_component;
if (*path)
@@ -370,7 +383,7 @@ static void print_path_1(const char *path)
printf("%s", path);
}
-static char *anonymize_path_component(void *data)
+static char *anonymize_path_component(void)
{
static int counter;
struct strbuf out = STRBUF_INIT;
@@ -392,7 +405,7 @@ static void print_path(const char *path)
}
}
-static char *generate_fake_oid(void *data)
+static char *generate_fake_oid(void)
{
static uint32_t counter = 1; /* avoid null oid */
const unsigned hashsz = the_hash_algo->rawsz;
@@ -408,7 +421,7 @@ static const char *anonymize_oid(const char *oid_hex)
{
static struct hashmap objs;
size_t len = strlen(oid_hex);
- return anonymize_str(&objs, generate_fake_oid, oid_hex, len, NULL);
+ return anonymize_str(&objs, generate_fake_oid, oid_hex, len);
}
static void show_filemodify(struct diff_queue_struct *q,
@@ -505,7 +518,7 @@ static const char *find_encoding(const char *begin, const char *end)
return bol;
}
-static char *anonymize_ref_component(void *data)
+static char *anonymize_ref_component(void)
{
static int counter;
struct strbuf out = STRBUF_INIT;
@@ -545,13 +558,13 @@ static const char *anonymize_refname(const char *refname)
* We do not even bother to cache commit messages, as they are unlikely
* to be repeated verbatim, and it is not that interesting when they are.
*/
-static char *anonymize_commit_message(const char *old)
+static char *anonymize_commit_message(void)
{
static int counter;
return xstrfmt("subject %d\n\nbody\n", counter++);
}
-static char *anonymize_ident(void *data)
+static char *anonymize_ident(void)
{
static int counter;
struct strbuf out = STRBUF_INIT;
@@ -594,7 +607,7 @@ static void anonymize_ident_line(const char **beg, const char **end)
len = split.mail_end - split.name_begin;
ident = anonymize_str(&idents, anonymize_ident,
- split.name_begin, len, NULL);
+ split.name_begin, len);
strbuf_addstr(out, ident);
strbuf_addch(out, ' ');
strbuf_add(out, split.date_begin, split.tz_end - split.date_begin);
@@ -672,7 +685,7 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
mark_next_object(&commit->object);
if (anonymize) {
- reencoded = anonymize_commit_message(message);
+ reencoded = anonymize_commit_message();
} else if (encoding) {
switch(reencode_mode) {
case REENCODE_YES:
@@ -735,7 +748,7 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
show_progress();
}
-static char *anonymize_tag(void *data)
+static char *anonymize_tag(void)
{
static int counter;
struct strbuf out = STRBUF_INIT;
@@ -798,7 +811,7 @@ static void handle_tag(const char *name, struct tag *tag)
if (message) {
static struct hashmap tags;
message = anonymize_str(&tags, anonymize_tag,
- message, message_size, NULL);
+ message, message_size);
message_size = strlen(message);
}
}
@@ -1130,11 +1143,6 @@ static void handle_deletes(void)
}
}
-static char *anonymize_seed(void *data)
-{
- return xstrdup(data);
-}
-
static int parse_opt_anonymize_map(const struct option *opt,
const char *arg, int unset)
{
@@ -1156,7 +1164,8 @@ static int parse_opt_anonymize_map(const struct option *opt,
if (!keylen || !*value)
return error(_("--anonymize-map token cannot be empty"));
- anonymize_str(map, anonymize_seed, arg, keylen, (void *)value);
+ add_anonymized_entry(map, memhash(arg, keylen), arg, keylen,
+ xstrdup(value));
return 0;
}
diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 9f90f5b9e4..bbd9b2b3e7 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -182,6 +182,7 @@ static FILE *pack_edges;
static unsigned int show_stats = 1;
static int global_argc;
static const char **global_argv;
+static const char *global_prefix;
/* Memory pools */
static struct mem_pool fi_mem_pool = {
@@ -3253,7 +3254,7 @@ static void parse_alias(void)
static char* make_fast_import_path(const char *path)
{
if (!relative_marks_paths || is_absolute_path(path))
- return xstrdup(path);
+ return prefix_filename(global_prefix, path);
return git_pathdup("info/fast-import/%s", path);
}
@@ -3324,9 +3325,11 @@ static void option_cat_blob_fd(const char *fd)
static void option_export_pack_edges(const char *edges)
{
+ char *fn = prefix_filename(global_prefix, edges);
if (pack_edges)
fclose(pack_edges);
- pack_edges = xfopen(edges, "a");
+ pack_edges = xfopen(fn, "a");
+ free(fn);
}
static void option_rewrite_submodules(const char *arg, struct string_list *list)
@@ -3341,11 +3344,13 @@ static void option_rewrite_submodules(const char *arg, struct string_list *list)
f++;
CALLOC_ARRAY(ms, 1);
+ f = prefix_filename(global_prefix, f);
fp = fopen(f, "r");
if (!fp)
die_errno("cannot read '%s'", f);
read_mark_file(&ms, fp, insert_oid_entry);
fclose(fp);
+ free(f);
string_list_insert(list, s)->util = ms;
}
@@ -3559,6 +3564,7 @@ int cmd_fast_import(int argc, const char **argv, const char *prefix)
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++)
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 664ac1ec0e..3ba0fe5a39 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -44,7 +44,7 @@ static void add_sought_entry(struct ref ***sought, int *nr, int *alloc,
(*sought)[*nr - 1] = ref;
}
-int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
+int cmd_fetch_pack(int argc, const char **argv, const char *prefix UNUSED)
{
int i, ret;
struct ref *ref = NULL;
@@ -215,8 +215,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
int flags = args.verbose ? CONNECT_VERBOSE : 0;
if (args.diag_url)
flags |= CONNECT_DIAG_URL;
- conn = git_connect(fd, dest, args.uploadpack,
- flags);
+ conn = git_connect(fd, dest, "git-upload-pack",
+ args.uploadpack, flags);
if (!conn)
return args.diag_url ? 0 : 1;
}
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 4fee2a6237..4d7c289752 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -57,6 +57,16 @@ enum {
TAGS_SET = 2
};
+struct display_state {
+ struct strbuf buf;
+
+ int refcol_width;
+ int compact_format;
+
+ char *url;
+ int url_len, shown_url;
+};
+
static int fetch_prune_config = -1; /* unspecified */
static int fetch_show_forced_updates = 1;
static uint64_t forced_updates_ms = 0;
@@ -89,7 +99,6 @@ static const char *submodule_prefix = "";
static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
static int recurse_submodules_cli = RECURSE_SUBMODULES_DEFAULT;
static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;
-static int shown_url = 0;
static struct refspec refmap = REFSPEC_INIT_FETCH;
static struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT;
static struct string_list server_options = STRING_LIST_INIT_DUP;
@@ -751,16 +760,13 @@ out:
return ret;
}
-static int refcol_width = 10;
-static int compact_format;
-
-static void adjust_refcol_width(const struct ref *ref)
+static int refcol_width(const struct ref *ref, int compact_format)
{
int max, rlen, llen, len;
/* uptodate lines are only shown on high verbosity level */
if (verbosity <= 0 && oideq(&ref->peer_ref->old_oid, &ref->old_oid))
- return;
+ return 0;
max = term_columns();
rlen = utf8_strwidth(prettify_refname(ref->name));
@@ -779,48 +785,78 @@ static void adjust_refcol_width(const struct ref *ref)
}
len = 21 /* flag and summary */ + rlen + 4 /* -> */ + llen;
if (len >= max)
- return;
+ return 0;
- /*
- * Not precise calculation for compact mode because '*' can
- * appear on the left hand side of '->' and shrink the column
- * back.
- */
- if (refcol_width < rlen)
- refcol_width = rlen;
+ return rlen;
}
-static void prepare_format_display(struct ref *ref_map)
+static void display_state_init(struct display_state *display_state, struct ref *ref_map,
+ const char *raw_url)
{
struct ref *rm;
const char *format = "full";
+ int i;
+
+ memset(display_state, 0, sizeof(*display_state));
+
+ strbuf_init(&display_state->buf, 0);
+
+ if (raw_url)
+ display_state->url = transport_anonymize_url(raw_url);
+ else
+ display_state->url = xstrdup("foreign");
+
+ display_state->url_len = strlen(display_state->url);
+ for (i = display_state->url_len - 1; display_state->url[i] == '/' && 0 <= i; i--)
+ ;
+ display_state->url_len = i + 1;
+ if (4 < i && !strncmp(".git", display_state->url + i - 3, 4))
+ display_state->url_len = i - 3;
if (verbosity < 0)
return;
git_config_get_string_tmp("fetch.output", &format);
if (!strcasecmp(format, "full"))
- compact_format = 0;
+ display_state->compact_format = 0;
else if (!strcasecmp(format, "compact"))
- compact_format = 1;
+ display_state->compact_format = 1;
else
die(_("invalid value for '%s': '%s'"),
"fetch.output", format);
+ display_state->refcol_width = 10;
for (rm = ref_map; rm; rm = rm->next) {
+ int width;
+
if (rm->status == REF_STATUS_REJECT_SHALLOW ||
!rm->peer_ref ||
!strcmp(rm->name, "HEAD"))
continue;
- adjust_refcol_width(rm);
+ width = refcol_width(rm, display_state->compact_format);
+
+ /*
+ * Not precise calculation for compact mode because '*' can
+ * appear on the left hand side of '->' and shrink the column
+ * back.
+ */
+ if (display_state->refcol_width < width)
+ display_state->refcol_width = width;
}
}
-static void print_remote_to_local(struct strbuf *display,
+static void display_state_release(struct display_state *display_state)
+{
+ strbuf_release(&display_state->buf);
+ free(display_state->url);
+}
+
+static void print_remote_to_local(struct display_state *display_state,
const char *remote, const char *local)
{
- strbuf_addf(display, "%-*s -> %s", refcol_width, remote, local);
+ strbuf_addf(&display_state->buf, "%-*s -> %s",
+ display_state->refcol_width, remote, local);
}
static int find_and_replace(struct strbuf *haystack,
@@ -850,14 +886,14 @@ static int find_and_replace(struct strbuf *haystack,
return 1;
}
-static void print_compact(struct strbuf *display,
+static void print_compact(struct display_state *display_state,
const char *remote, const char *local)
{
struct strbuf r = STRBUF_INIT;
struct strbuf l = STRBUF_INIT;
if (!strcmp(remote, local)) {
- strbuf_addf(display, "%-*s -> *", refcol_width, remote);
+ strbuf_addf(&display_state->buf, "%-*s -> *", display_state->refcol_width, remote);
return;
}
@@ -866,40 +902,51 @@ static void print_compact(struct strbuf *display,
if (!find_and_replace(&r, local, "*"))
find_and_replace(&l, remote, "*");
- print_remote_to_local(display, r.buf, l.buf);
+ print_remote_to_local(display_state, r.buf, l.buf);
strbuf_release(&r);
strbuf_release(&l);
}
-static void format_display(struct strbuf *display, char code,
- const char *summary, const char *error,
- const char *remote, const char *local,
- int summary_width)
+static void display_ref_update(struct display_state *display_state, char code,
+ const char *summary, const char *error,
+ const char *remote, const char *local,
+ int summary_width)
{
int width;
if (verbosity < 0)
return;
+ strbuf_reset(&display_state->buf);
+
+ if (!display_state->shown_url) {
+ strbuf_addf(&display_state->buf, _("From %.*s\n"),
+ display_state->url_len, display_state->url);
+ display_state->shown_url = 1;
+ }
+
width = (summary_width + strlen(summary) - gettext_width(summary));
- strbuf_addf(display, "%c %-*s ", code, width, summary);
- if (!compact_format)
- print_remote_to_local(display, remote, local);
+ strbuf_addf(&display_state->buf, " %c %-*s ", code, width, summary);
+ if (!display_state->compact_format)
+ print_remote_to_local(display_state, remote, prettify_refname(local));
else
- print_compact(display, remote, local);
+ print_compact(display_state, remote, prettify_refname(local));
if (error)
- strbuf_addf(display, " (%s)", error);
+ strbuf_addf(&display_state->buf, " (%s)", error);
+ strbuf_addch(&display_state->buf, '\n');
+
+ fputs(display_state->buf.buf, stderr);
}
static int update_local_ref(struct ref *ref,
struct ref_transaction *transaction,
+ struct display_state *display_state,
const char *remote, const struct ref *remote_ref,
- struct strbuf *display, int summary_width)
+ int summary_width)
{
struct commit *current = NULL, *updated;
- const char *pretty_ref = prettify_refname(ref->name);
int fast_forward = 0;
if (!repo_has_object_file(the_repository, &ref->new_oid))
@@ -907,8 +954,8 @@ static int update_local_ref(struct ref *ref,
if (oideq(&ref->old_oid, &ref->new_oid)) {
if (verbosity > 0)
- format_display(display, '=', _("[up to date]"), NULL,
- remote, pretty_ref, summary_width);
+ display_ref_update(display_state, '=', _("[up to date]"), NULL,
+ remote, ref->name, summary_width);
return 0;
}
@@ -919,9 +966,9 @@ static int update_local_ref(struct ref *ref,
* If this is the head, and it's not okay to update
* the head, and the old value of the head isn't empty...
*/
- format_display(display, '!', _("[rejected]"),
- _("can't fetch into checked-out branch"),
- remote, pretty_ref, summary_width);
+ display_ref_update(display_state, '!', _("[rejected]"),
+ _("can't fetch into checked-out branch"),
+ remote, ref->name, summary_width);
return 1;
}
@@ -930,13 +977,14 @@ static int update_local_ref(struct ref *ref,
if (force || ref->force) {
int r;
r = s_update_ref("updating tag", ref, transaction, 0);
- format_display(display, r ? '!' : 't', _("[tag update]"),
- r ? _("unable to update local ref") : NULL,
- remote, pretty_ref, summary_width);
+ display_ref_update(display_state, r ? '!' : 't', _("[tag update]"),
+ r ? _("unable to update local ref") : NULL,
+ remote, ref->name, summary_width);
return r;
} else {
- format_display(display, '!', _("[rejected]"), _("would clobber existing tag"),
- remote, pretty_ref, summary_width);
+ display_ref_update(display_state, '!', _("[rejected]"),
+ _("would clobber existing tag"),
+ remote, ref->name, summary_width);
return 1;
}
}
@@ -967,9 +1015,9 @@ static int update_local_ref(struct ref *ref,
}
r = s_update_ref(msg, ref, transaction, 0);
- format_display(display, r ? '!' : '*', what,
- r ? _("unable to update local ref") : NULL,
- remote, pretty_ref, summary_width);
+ display_ref_update(display_state, r ? '!' : '*', what,
+ r ? _("unable to update local ref") : NULL,
+ remote, ref->name, summary_width);
return r;
}
@@ -990,9 +1038,9 @@ static int update_local_ref(struct ref *ref,
strbuf_addstr(&quickref, "..");
strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
r = s_update_ref("fast-forward", ref, transaction, 1);
- format_display(display, r ? '!' : ' ', quickref.buf,
- r ? _("unable to update local ref") : NULL,
- remote, pretty_ref, summary_width);
+ display_ref_update(display_state, r ? '!' : ' ', quickref.buf,
+ r ? _("unable to update local ref") : NULL,
+ remote, ref->name, summary_width);
strbuf_release(&quickref);
return r;
} else if (force || ref->force) {
@@ -1002,14 +1050,14 @@ static int update_local_ref(struct ref *ref,
strbuf_addstr(&quickref, "...");
strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
r = s_update_ref("forced-update", ref, transaction, 1);
- format_display(display, r ? '!' : '+', quickref.buf,
- r ? _("unable to update local ref") : _("forced update"),
- remote, pretty_ref, summary_width);
+ display_ref_update(display_state, r ? '!' : '+', quickref.buf,
+ r ? _("unable to update local ref") : _("forced update"),
+ remote, ref->name, summary_width);
strbuf_release(&quickref);
return r;
} else {
- format_display(display, '!', _("[rejected]"), _("non-fast-forward"),
- remote, pretty_ref, summary_width);
+ display_ref_update(display_state, '!', _("[rejected]"), _("non-fast-forward"),
+ remote, ref->name, summary_width);
return 1;
}
}
@@ -1119,40 +1167,34 @@ N_("it took %.2f seconds to check forced updates; you can use\n"
"'--no-show-forced-updates' or run 'git config fetch.showForcedUpdates false'\n"
"to avoid this check\n");
-static int store_updated_refs(const char *raw_url, const char *remote_name,
+static int store_updated_refs(struct display_state *display_state,
+ const char *remote_name,
int connectivity_checked,
struct ref_transaction *transaction, struct ref *ref_map,
struct fetch_head *fetch_head)
{
- int url_len, i, rc = 0;
+ int rc = 0;
struct strbuf note = STRBUF_INIT;
const char *what, *kind;
struct ref *rm;
- char *url;
int want_status;
int summary_width = 0;
if (verbosity >= 0)
summary_width = transport_summary_width(ref_map);
- if (raw_url)
- url = transport_anonymize_url(raw_url);
- else
- url = xstrdup("foreign");
-
if (!connectivity_checked) {
struct check_connected_options opt = CHECK_CONNECTED_INIT;
opt.exclude_hidden_refs_section = "fetch";
rm = ref_map;
if (check_connected(iterate_ref_map, &rm, &opt)) {
- rc = error(_("%s did not send all necessary objects\n"), url);
+ rc = error(_("%s did not send all necessary objects\n"),
+ display_state->url);
goto abort;
}
}
- prepare_format_display(ref_map);
-
/*
* We do a pass for each fetch_head_status type in their enum order, so
* merged entries are written before not-for-merge. That lets readers
@@ -1232,13 +1274,6 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
what = rm->name;
}
- url_len = strlen(url);
- for (i = url_len - 1; url[i] == '/' && 0 <= i; i--)
- ;
- url_len = i + 1;
- if (4 < i && !strncmp(".git", url + i - 3, 4))
- url_len = i - 3;
-
strbuf_reset(&note);
if (*what) {
if (*kind)
@@ -1248,12 +1283,12 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
append_fetch_head(fetch_head, &rm->old_oid,
rm->fetch_head_status,
- note.buf, url, url_len);
+ note.buf, display_state->url,
+ display_state->url_len);
- strbuf_reset(&note);
if (ref) {
- rc |= update_local_ref(ref, transaction, what,
- rm, &note, summary_width);
+ rc |= update_local_ref(ref, transaction, display_state, what,
+ rm, summary_width);
free(ref);
} else if (write_fetch_head || dry_run) {
/*
@@ -1261,18 +1296,10 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
* would be written to FETCH_HEAD, if --dry-run
* is set).
*/
- format_display(&note, '*',
- *kind ? kind : "branch", NULL,
- *what ? what : "HEAD",
- "FETCH_HEAD", summary_width);
- }
- if (note.len) {
- if (!shown_url) {
- fprintf(stderr, _("From %.*s\n"),
- url_len, url);
- shown_url = 1;
- }
- fprintf(stderr, " %s\n", note.buf);
+ display_ref_update(display_state, '*',
+ *kind ? kind : "branch", NULL,
+ *what ? what : "HEAD",
+ "FETCH_HEAD", summary_width);
}
}
}
@@ -1293,7 +1320,6 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
abort:
strbuf_release(&note);
- free(url);
return rc;
}
@@ -1341,7 +1367,8 @@ static int check_exist_and_connected(struct ref *ref_map)
return check_connected(iterate_ref_map, &rm, &opt);
}
-static int fetch_and_consume_refs(struct transport *transport,
+static int fetch_and_consume_refs(struct display_state *display_state,
+ struct transport *transport,
struct ref_transaction *transaction,
struct ref *ref_map,
struct fetch_head *fetch_head)
@@ -1365,7 +1392,7 @@ static int fetch_and_consume_refs(struct transport *transport,
}
trace2_region_enter("fetch", "consume_refs", the_repository);
- ret = store_updated_refs(transport->url, transport->remote->name,
+ ret = store_updated_refs(display_state, transport->remote->name,
connectivity_checked, transaction, ref_map,
fetch_head);
trace2_region_leave("fetch", "consume_refs", the_repository);
@@ -1375,32 +1402,18 @@ out:
return ret;
}
-static int prune_refs(struct refspec *rs,
+static int prune_refs(struct display_state *display_state,
+ struct refspec *rs,
struct ref_transaction *transaction,
- struct ref *ref_map,
- const char *raw_url)
+ struct ref *ref_map)
{
- int url_len, i, result = 0;
+ int result = 0;
struct ref *ref, *stale_refs = get_stale_heads(rs, ref_map);
struct strbuf err = STRBUF_INIT;
- char *url;
const char *dangling_msg = dry_run
? _(" (%s will become dangling)")
: _(" (%s has become dangling)");
- if (raw_url)
- url = transport_anonymize_url(raw_url);
- else
- url = xstrdup("foreign");
-
- url_len = strlen(url);
- for (i = url_len - 1; url[i] == '/' && 0 <= i; i--)
- ;
-
- url_len = i + 1;
- if (4 < i && !strncmp(".git", url + i - 3, 4))
- url_len = i - 3;
-
if (!dry_run) {
if (transaction) {
for (ref = stale_refs; ref; ref = ref->next) {
@@ -1424,23 +1437,15 @@ static int prune_refs(struct refspec *rs,
int summary_width = transport_summary_width(stale_refs);
for (ref = stale_refs; ref; ref = ref->next) {
- struct strbuf sb = STRBUF_INIT;
- if (!shown_url) {
- fprintf(stderr, _("From %.*s\n"), url_len, url);
- shown_url = 1;
- }
- format_display(&sb, '-', _("[deleted]"), NULL,
- _("(none)"), prettify_refname(ref->name),
- summary_width);
- fprintf(stderr, " %s\n",sb.buf);
- strbuf_release(&sb);
+ display_ref_update(display_state, '-', _("[deleted]"), NULL,
+ _("(none)"), ref->name,
+ summary_width);
warn_dangling_symref(stderr, dangling_msg, ref->name);
}
}
cleanup:
strbuf_release(&err);
- free(url);
free_refs(stale_refs);
return result;
}
@@ -1555,7 +1560,8 @@ static struct transport *prepare_transport(struct remote *remote, int deepen)
return transport;
}
-static int backfill_tags(struct transport *transport,
+static int backfill_tags(struct display_state *display_state,
+ struct transport *transport,
struct ref_transaction *transaction,
struct ref *ref_map,
struct fetch_head *fetch_head)
@@ -1579,7 +1585,7 @@ static int backfill_tags(struct transport *transport,
transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, NULL);
transport_set_option(transport, TRANS_OPT_DEPTH, "0");
transport_set_option(transport, TRANS_OPT_DEEPEN_RELATIVE, NULL);
- retcode = fetch_and_consume_refs(transport, transaction, ref_map, fetch_head);
+ retcode = fetch_and_consume_refs(display_state, transport, transaction, ref_map, fetch_head);
if (gsecondary) {
transport_disconnect(gsecondary);
@@ -1594,6 +1600,7 @@ static int do_fetch(struct transport *transport,
{
struct ref_transaction *transaction = NULL;
struct ref *ref_map = NULL;
+ struct display_state display_state = { 0 };
int autotags = (transport->remote->fetch_tags == 1);
int retcode = 0;
const struct ref *remote_refs;
@@ -1675,6 +1682,8 @@ static int do_fetch(struct transport *transport,
if (retcode)
goto cleanup;
+ display_state_init(&display_state, ref_map, transport->url);
+
if (atomic_fetch) {
transaction = ref_transaction_begin(&err);
if (!transaction) {
@@ -1692,17 +1701,16 @@ static int do_fetch(struct transport *transport,
* don't care whether --tags was specified.
*/
if (rs->nr) {
- retcode = prune_refs(rs, transaction, ref_map, transport->url);
+ retcode = prune_refs(&display_state, rs, transaction, ref_map);
} else {
- retcode = prune_refs(&transport->remote->fetch,
- transaction, ref_map,
- transport->url);
+ retcode = prune_refs(&display_state, &transport->remote->fetch,
+ transaction, ref_map);
}
if (retcode != 0)
retcode = 1;
}
- if (fetch_and_consume_refs(transport, transaction, ref_map, &fetch_head)) {
+ if (fetch_and_consume_refs(&display_state, transport, transaction, ref_map, &fetch_head)) {
retcode = 1;
goto cleanup;
}
@@ -1724,7 +1732,7 @@ static int do_fetch(struct transport *transport,
* when `--atomic` is passed: in that case we'll abort
* the transaction and don't commit anything.
*/
- if (backfill_tags(transport, transaction, tags_ref_map,
+ if (backfill_tags(&display_state, transport, transaction, tags_ref_map,
&fetch_head))
retcode = 1;
}
@@ -1807,6 +1815,7 @@ cleanup:
error("%s", err.buf);
}
+ display_state_release(&display_state);
close_fetch_head(&fetch_head);
strbuf_release(&err);
free_refs(ref_map);
@@ -1965,7 +1974,12 @@ static int fetch_multiple(struct string_list *list, int max_children)
return errcode;
}
- strvec_pushl(&argv, "fetch", "--append", "--no-auto-gc",
+ /*
+ * Cancel out the fetch.bundleURI config when running subprocesses,
+ * to avoid fetching from the same bundle list multiple times.
+ */
+ strvec_pushl(&argv, "-c", "fetch.bundleURI=",
+ "fetch", "--append", "--no-auto-gc",
"--no-write-commit-graph", NULL);
add_options_to_argv(&argv);
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index 7a8ff5902c..695fc8f4a5 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -6,6 +6,8 @@
#include "object.h"
#include "parse-options.h"
#include "ref-filter.h"
+#include "strvec.h"
+#include "commit-reach.h"
static char const * const for_each_ref_usage[] = {
N_("git for-each-ref [<options>] [<pattern>]"),
@@ -20,12 +22,14 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
int i;
struct ref_sorting *sorting;
struct string_list sorting_options = STRING_LIST_INIT_DUP;
- int maxcount = 0, icase = 0;
+ int maxcount = 0, icase = 0, omit_empty = 0;
struct ref_array array;
struct ref_filter filter;
struct ref_format format = REF_FORMAT_INIT;
struct strbuf output = STRBUF_INIT;
struct strbuf err = STRBUF_INIT;
+ int from_stdin = 0;
+ struct strvec vec = STRVEC_INIT;
struct option opts[] = {
OPT_BIT('s', "shell", &format.quote_style,
@@ -36,6 +40,8 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
N_("quote placeholders suitably for python"), QUOTE_PYTHON),
OPT_BIT(0 , "tcl", &format.quote_style,
N_("quote placeholders suitably for Tcl"), QUOTE_TCL),
+ OPT_BOOL(0, "omit-empty", &omit_empty,
+ N_("do not output a newline after empty formatted refs")),
OPT_GROUP(""),
OPT_INTEGER( 0 , "count", &maxcount, N_("show only <n> matched refs")),
@@ -50,6 +56,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
OPT_CONTAINS(&filter.with_commit, N_("print only refs which contain the commit")),
OPT_NO_CONTAINS(&filter.no_commit, N_("print only refs which don't contain the commit")),
OPT_BOOL(0, "ignore-case", &icase, N_("sorting and filtering are case insensitive")),
+ OPT_BOOL(0, "stdin", &from_stdin, N_("read reference patterns from stdin")),
OPT_END(),
};
@@ -76,9 +83,27 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase);
filter.ignore_case = icase;
- filter.name_patterns = argv;
+ if (from_stdin) {
+ struct strbuf line = STRBUF_INIT;
+
+ if (argv[0])
+ die(_("unknown arguments supplied with --stdin"));
+
+ while (strbuf_getline(&line, stdin) != EOF)
+ strvec_push(&vec, line.buf);
+
+ strbuf_release(&line);
+
+ /* vec.v is NULL-terminated, just like 'argv'. */
+ filter.name_patterns = vec.v;
+ } else {
+ filter.name_patterns = argv;
+ }
+
filter.match_as_path = 1;
filter_refs(&array, &filter, FILTER_REFS_ALL);
+ filter_ahead_behind(the_repository, &format, &array);
+
ref_array_sort(sorting, &array);
if (!maxcount || array.nr < maxcount)
@@ -89,7 +114,8 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
if (format_ref_array_item(array.items[i], &format, &output, &err))
die("%s", err.buf);
fwrite(output.buf, 1, output.len, stdout);
- putchar('\n');
+ if (output.len || !omit_empty)
+ putchar('\n');
}
strbuf_release(&err);
@@ -98,5 +124,6 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
free_commit_list(filter.with_commit);
free_commit_list(filter.no_commit);
ref_sorting_release(sorting);
+ strvec_clear(&vec);
return 0;
}
diff --git a/builtin/for-each-repo.c b/builtin/for-each-repo.c
index c28b0b3543..37daf7bec1 100644
--- a/builtin/for-each-repo.c
+++ b/builtin/for-each-repo.c
@@ -35,6 +35,7 @@ int cmd_for_each_repo(int argc, const char **argv, const char *prefix)
static const char *config_key = NULL;
int i, result = 0;
const struct string_list *values;
+ int err;
const struct option options[] = {
OPT_STRING(0, "config", &config_key, N_("config"),
@@ -48,14 +49,11 @@ int cmd_for_each_repo(int argc, const char **argv, const char *prefix)
if (!config_key)
die(_("missing --config=<config>"));
- values = repo_config_get_value_multi(the_repository,
- config_key);
-
- /*
- * Do nothing on an empty list, which is equivalent to the case
- * where the config variable does not exist at all.
- */
- if (!values)
+ err = repo_config_get_string_multi(the_repository, config_key, &values);
+ if (err < 0)
+ usage_msg_optf(_("got bad config --config=%s"),
+ for_each_repo_usage, options, config_key);
+ else if (err)
return 0;
for (i = 0; !result && i < values->nr; i++)
diff --git a/builtin/fsck.c b/builtin/fsck.c
index 35a6de3cdb..2cd461b84c 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -26,6 +26,7 @@
#include "resolve-undo.h"
#include "run-command.h"
#include "worktree.h"
+#include "pack-revindex.h"
#define REACHABLE 0x0001
#define SEEN 0x0002
@@ -55,6 +56,7 @@ static int name_objects;
#define ERROR_REFS 010
#define ERROR_COMMIT_GRAPH 020
#define ERROR_MULTI_PACK_INDEX 040
+#define ERROR_PACK_REV_INDEX 0100
static const char *describe_object(const struct object_id *oid)
{
@@ -858,6 +860,38 @@ static int mark_packed_for_connectivity(const struct object_id *oid,
return 0;
}
+static int check_pack_rev_indexes(struct repository *r, int show_progress)
+{
+ struct progress *progress = NULL;
+ uint32_t pack_count = 0;
+ int res = 0;
+
+ if (show_progress) {
+ for (struct packed_git *p = get_all_packs(the_repository); p; p = p->next)
+ pack_count++;
+ progress = start_delayed_progress("Verifying reverse pack-indexes", pack_count);
+ pack_count = 0;
+ }
+
+ for (struct packed_git *p = get_all_packs(the_repository); p; p = p->next) {
+ int load_error = load_pack_revindex_from_disk(p);
+
+ if (load_error < 0) {
+ error(_("unable to load rev-index for pack '%s'"), p->pack_name);
+ res = ERROR_PACK_REV_INDEX;
+ } else if (!load_error &&
+ !load_pack_revindex(the_repository, p) &&
+ verify_pack_revindex(p)) {
+ error(_("invalid rev-index for pack '%s'"), p->pack_name);
+ res = ERROR_PACK_REV_INDEX;
+ }
+ display_progress(progress, ++pack_count);
+ }
+ stop_progress(&progress);
+
+ return res;
+}
+
static char const * const fsck_usage[] = {
N_("git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n"
" [--[no-]full] [--strict] [--verbose] [--lost-found]\n"
@@ -1021,6 +1055,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
free_worktrees(worktrees);
}
+ errors_found |= check_pack_rev_indexes(the_repository, show_progress);
+
check_connectivity();
if (the_repository->settings.core_commit_graph) {
diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c
index df876b41d6..f6dd9a784c 100644
--- a/builtin/fsmonitor--daemon.c
+++ b/builtin/fsmonitor--daemon.c
@@ -1579,7 +1579,7 @@ int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix)
}
#else
-int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix)
+int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix UNUSED)
{
struct option options[] = {
OPT_END()
diff --git a/builtin/gc.c b/builtin/gc.c
index d11712b144..f3942188a6 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -51,7 +51,7 @@ static const char * const builtin_gc_usage[] = {
static int pack_refs = 1;
static int prune_reflogs = 1;
-static int cruft_packs = -1;
+static int cruft_packs = 1;
static int aggressive_depth = 50;
static int aggressive_window = 250;
static int gc_auto_threshold = 6700;
@@ -222,7 +222,7 @@ static struct packed_git *find_base_packs(struct string_list *packs,
struct packed_git *p, *base = NULL;
for (p = get_all_packs(the_repository); p; p = p->next) {
- if (!p->pack_local)
+ if (!p->pack_local || p->is_cruft)
continue;
if (limit) {
if (p->pack_size >= limit)
@@ -611,10 +611,6 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
if (prune_expire && parse_expiry_date(prune_expire, &dummy))
die(_("failed to parse prune expiry value %s"), prune_expire);
- prepare_repo_settings(the_repository);
- if (cruft_packs < 0)
- cruft_packs = the_repository->settings.gc_cruft_packs;
-
if (aggressive) {
strvec_push(&repack, "-f");
if (aggressive_depth > 0)
@@ -1502,7 +1498,6 @@ static int maintenance_register(int argc, const char **argv, const char *prefix)
};
int found = 0;
const char *key = "maintenance.repo";
- char *config_value;
char *maintpath = get_maintpath();
struct string_list_item *item;
const struct string_list *list;
@@ -1517,13 +1512,10 @@ static int maintenance_register(int argc, const char **argv, const char *prefix)
git_config_set("maintenance.auto", "false");
/* Set maintenance strategy, if unset */
- if (!git_config_get_string("maintenance.strategy", &config_value))
- free(config_value);
- else
+ if (git_config_get("maintenance.strategy"))
git_config_set("maintenance.strategy", "incremental");
- list = git_config_get_value_multi(key);
- if (list) {
+ if (!git_config_get_string_multi(key, &list)) {
for_each_string_list_item(item, list) {
if (!strcmp(maintpath, item->string)) {
found = 1;
@@ -1589,11 +1581,10 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi
if (config_file) {
git_configset_init(&cs);
git_configset_add_file(&cs, config_file);
- list = git_configset_get_value_multi(&cs, key);
- } else {
- list = git_config_get_value_multi(key);
}
- if (list) {
+ if (!(config_file
+ ? git_configset_get_string_multi(&cs, key, &list)
+ : git_config_get_string_multi(key, &list))) {
for_each_string_list_item(item, list) {
if (!strcmp(maintpath, item->string)) {
found = 1;
@@ -1695,11 +1686,11 @@ static int get_schedule_cmd(const char **cmd, int *is_available)
if (is_available)
*is_available = 0;
- string_list_split_in_place(&list, testing, ',', -1);
+ string_list_split_in_place(&list, testing, ",", -1);
for_each_string_list_item(item, &list) {
struct string_list pair = STRING_LIST_INIT_NODUP;
- if (string_list_split_in_place(&pair, item->string, ':', 2) != 2)
+ if (string_list_split_in_place(&pair, item->string, ":", 2) != 2)
continue;
if (!strcmp(*cmd, pair.items[0].string)) {
diff --git a/builtin/get-tar-commit-id.c b/builtin/get-tar-commit-id.c
index 6745796998..564cfcac4f 100644
--- a/builtin/get-tar-commit-id.c
+++ b/builtin/get-tar-commit-id.c
@@ -15,7 +15,7 @@ static const char builtin_get_tar_commit_id_usage[] =
#define RECORDSIZE (512)
#define HEADERSIZE (2 * RECORDSIZE)
-int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
+int cmd_get_tar_commit_id(int argc, const char **argv UNUSED, const char *prefix)
{
char buffer[HEADERSIZE];
struct ustar_header *header = (struct ustar_header *)buffer;
@@ -25,6 +25,8 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
long len;
char *end;
+ BUG_ON_NON_EMPTY_PREFIX(prefix);
+
if (argc != 1)
usage(builtin_get_tar_commit_id_usage);
@@ -33,7 +35,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
die_errno("git get-tar-commit-id: read error");
if (n != HEADERSIZE)
die_errno("git get-tar-commit-id: EOF before reading tar header");
- if (header->typeflag[0] != 'g')
+ if (header->typeflag[0] != TYPEFLAG_GLOBAL_HEADER)
return 1;
len = strtol(content, &end, 10);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 0f59cf8aa0..bb67e16655 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1756,12 +1756,13 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
fsck_options.walk = mark_link;
reset_pack_idx_option(&opts);
+ opts.flags |= WRITE_REV;
git_config(git_index_pack_config, &opts);
if (prefix && chdir(prefix))
die(_("Cannot come back to cwd"));
- if (git_env_bool(GIT_TEST_WRITE_REV_INDEX, 0))
- rev_index = 1;
+ if (git_env_bool(GIT_TEST_NO_WRITE_REV_INDEX, 0))
+ rev_index = 0;
else
rev_index = !!(opts.flags & (WRITE_REV_VERIFY | WRITE_REV));
diff --git a/builtin/log.c b/builtin/log.c
index 137b84b31e..676de107d6 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -67,6 +67,7 @@ static int stdout_mboxrd;
static const char *fmt_patch_subject_prefix = "PATCH";
static int fmt_patch_name_max = FORMAT_PATCH_NAME_MAX_DEFAULT;
static const char *fmt_pretty;
+static int format_no_prefix;
static const char * const builtin_log_usage[] = {
N_("git log [<options>] [<revision-range>] [[--] <path>...]"),
@@ -193,10 +194,10 @@ static void set_default_decoration_filter(struct decoration_filter *decoration_f
int i;
char *value = NULL;
struct string_list *include = decoration_filter->include_ref_pattern;
- const struct string_list *config_exclude =
- git_config_get_value_multi("log.excludeDecoration");
+ const struct string_list *config_exclude;
- if (config_exclude) {
+ if (!git_config_get_string_multi("log.excludeDecoration",
+ &config_exclude)) {
struct string_list_item *item;
for_each_string_list_item(item, config_exclude)
string_list_append(decoration_filter->exclude_ref_config_pattern,
@@ -1093,6 +1094,19 @@ static int git_format_config(const char *var, const char *value, void *cb)
stdout_mboxrd = git_config_bool(var, value);
return 0;
}
+ if (!strcmp(var, "format.noprefix")) {
+ format_no_prefix = 1;
+ return 0;
+ }
+
+ /*
+ * ignore some porcelain config which would otherwise be parsed by
+ * git_diff_ui_config(), via git_log_config(); we can't just avoid
+ * diff_ui_config completely, because we do care about some ui options
+ * like color.
+ */
+ if (!strcmp(var, "diff.noprefix"))
+ return 0;
return git_log_config(var, value, cb);
}
@@ -2008,6 +2022,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
s_r_opt.def = "HEAD";
s_r_opt.revarg_opt = REVARG_COMMITTISH;
+ if (format_no_prefix)
+ diff_set_noprefix(&rev.diffopt);
+
if (default_attach) {
rev.mime_boundary = default_attach;
rev.no_inline = 1;
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index ce083cb8ef..625f48f0d6 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -93,12 +93,15 @@ static void write_name(const char *name)
static void write_name_to_buf(struct strbuf *sb, const char *name)
{
- const char *rel = relative_path(name, prefix_len ? prefix : NULL, sb);
+ struct strbuf buf = STRBUF_INIT;
+ const char *rel = relative_path(name, prefix_len ? prefix : NULL, &buf);
if (line_terminator)
quote_c_style(rel, sb, NULL, 0);
else
strbuf_addstr(sb, rel);
+
+ strbuf_release(&buf);
}
static const char *get_tag(const struct cache_entry *ce, const char *tag)
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index 7972febf72..cb6cb77e08 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -7,6 +7,7 @@
#include "ref-filter.h"
#include "remote.h"
#include "refs.h"
+#include "parse-options.h"
static const char * const ls_remote_usage[] = {
N_("git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c
index b08069ce60..0b6193a091 100644
--- a/builtin/mailsplit.c
+++ b/builtin/mailsplit.c
@@ -278,6 +278,8 @@ int cmd_mailsplit(int argc, const char **argv, const char *prefix)
const char **argp;
static const char *stdin_only[] = { "-", NULL };
+ BUG_ON_NON_EMPTY_PREFIX(prefix);
+
for (argp = argv+1; *argp; argp++) {
const char *arg = *argp;
diff --git a/builtin/merge-index.c b/builtin/merge-index.c
index f044382ed8..ab16e70f23 100644
--- a/builtin/merge-index.c
+++ b/builtin/merge-index.c
@@ -72,7 +72,7 @@ static void merge_all(void)
}
}
-int cmd_merge_index(int argc, const char **argv, const char *prefix)
+int cmd_merge_index(int argc, const char **argv, const char *prefix UNUSED)
{
int i, force_file = 0;
diff --git a/builtin/merge-ours.c b/builtin/merge-ours.c
index 284eb48609..c2e519301e 100644
--- a/builtin/merge-ours.c
+++ b/builtin/merge-ours.c
@@ -14,7 +14,7 @@
static const char builtin_merge_ours_usage[] =
"git merge-ours <base>... -- HEAD <remote>...";
-int cmd_merge_ours(int argc, const char **argv, const char *prefix)
+int cmd_merge_ours(int argc, const char **argv, const char *prefix UNUSED)
{
if (argc == 2 && !strcmp(argv[1], "-h"))
usage(builtin_merge_ours_usage);
diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c
index 90da9d0774..b9e980384a 100644
--- a/builtin/merge-recursive.c
+++ b/builtin/merge-recursive.c
@@ -25,7 +25,7 @@ static char *better_branch_name(const char *branch)
return xstrdup(name ? name : branch);
}
-int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
+int cmd_merge_recursive(int argc, const char **argv, const char *prefix UNUSED)
{
const struct object_id *bases[21];
unsigned bases_count = 0;
diff --git a/builtin/mktag.c b/builtin/mktag.c
index f33d267fcb..44fa56eff3 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -84,7 +84,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
int tagged_type;
struct object_id result;
- argc = parse_options(argc, argv, NULL,
+ argc = parse_options(argc, argv, prefix,
builtin_mktag_options,
builtin_mktag_usage, 0);
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 68c914a8e1..a5b466839b 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -42,6 +42,7 @@
#include "shallow.h"
#include "promisor-remote.h"
#include "pack-mtimes.h"
+#include "parse-options.h"
#include "wrapper.h"
/*
@@ -3359,16 +3360,16 @@ static void read_packs_list_from_stdin(void)
}
string_list_sort(&include_packs);
+ string_list_remove_duplicates(&include_packs, 0);
string_list_sort(&exclude_packs);
+ string_list_remove_duplicates(&exclude_packs, 0);
for (p = get_all_packs(the_repository); p; p = p->next) {
const char *pack_name = pack_basename(p);
- item = string_list_lookup(&include_packs, pack_name);
- if (!item)
- item = string_list_lookup(&exclude_packs, pack_name);
-
- if (item)
+ if ((item = string_list_lookup(&include_packs, pack_name)))
+ item->util = p;
+ if ((item = string_list_lookup(&exclude_packs, pack_name)))
item->util = p;
}
@@ -4293,9 +4294,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
}
reset_pack_idx_option(&pack_idx_opts);
+ pack_idx_opts.flags |= WRITE_REV;
git_config(git_pack_config, NULL);
- if (git_env_bool(GIT_TEST_WRITE_REV_INDEX, 0))
- pack_idx_opts.flags |= WRITE_REV;
+ if (git_env_bool(GIT_TEST_NO_WRITE_REV_INDEX, 0))
+ pack_idx_opts.flags &= ~WRITE_REV;
progress = isatty(2);
argc = parse_options(argc, argv, prefix, pack_objects_options,
diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c
index 3451971b56..43e9d12dfd 100644
--- a/builtin/pack-redundant.c
+++ b/builtin/pack-redundant.c
@@ -559,7 +559,7 @@ static void load_all(void)
}
}
-int cmd_pack_redundant(int argc, const char **argv, const char *prefix)
+int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED)
{
int i;
int i_still_use_this = 0;
@@ -605,6 +605,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix)
"option, '--i-still-use-this', on the command line\n"
"and let us know you still use it by sending an e-mail\n"
"to <git@vger.kernel.org>. Thanks.\n"), stderr);
+ die(_("refusing to run without --i-still-use-this"));
}
if (load_all_packs)
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 34fea4d822..ace1d5e8d1 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -124,13 +124,15 @@ struct rebase_options {
struct string_list exec;
int allow_empty_message;
int rebase_merges, rebase_cousins;
- char *strategy, *strategy_opts;
+ char *strategy;
+ struct string_list strategy_opts;
struct strbuf git_format_patch_opt;
int reschedule_failed_exec;
int reapply_cherry_picks;
int fork_point;
int update_refs;
int config_autosquash;
+ int config_rebase_merges;
int config_update_refs;
};
@@ -148,8 +150,11 @@ struct rebase_options {
.allow_empty_message = 1, \
.autosquash = -1, \
.config_autosquash = -1, \
+ .rebase_merges = -1, \
+ .config_rebase_merges = -1, \
.update_refs = -1, \
.config_update_refs = -1, \
+ .strategy_opts = STRING_LIST_INIT_NODUP,\
}
static struct replay_opts get_replay_opts(const struct rebase_options *opts)
@@ -183,8 +188,8 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)
replay.default_strategy = NULL;
}
- if (opts->strategy_opts)
- parse_strategy_opts(&replay, opts->strategy_opts);
+ for (size_t i = 0; i < opts->strategy_opts.nr; i++)
+ strvec_push(&replay.xopts, opts->strategy_opts.items[i].string);
if (opts->squash_onto) {
oidcpy(&replay.squash_onto, opts->squash_onto);
@@ -492,24 +497,6 @@ static int read_basic_state(struct rebase_options *opts)
opts->gpg_sign_opt = xstrdup(buf.buf);
}
- if (file_exists(state_dir_path("strategy", opts))) {
- strbuf_reset(&buf);
- if (!read_oneliner(&buf, state_dir_path("strategy", opts),
- READ_ONELINER_WARN_MISSING))
- return -1;
- free(opts->strategy);
- opts->strategy = xstrdup(buf.buf);
- }
-
- if (file_exists(state_dir_path("strategy_opts", opts))) {
- strbuf_reset(&buf);
- if (!read_oneliner(&buf, state_dir_path("strategy_opts", opts),
- READ_ONELINER_WARN_MISSING))
- return -1;
- free(opts->strategy_opts);
- opts->strategy_opts = xstrdup(buf.buf);
- }
-
strbuf_release(&buf);
return 0;
@@ -527,12 +514,6 @@ static int rebase_write_basic_state(struct rebase_options *opts)
write_file(state_dir_path("quiet", opts), "%s", "");
if (opts->flags & REBASE_VERBOSE)
write_file(state_dir_path("verbose", opts), "%s", "");
- if (opts->strategy)
- write_file(state_dir_path("strategy", opts), "%s",
- opts->strategy);
- if (opts->strategy_opts)
- write_file(state_dir_path("strategy_opts", opts), "%s",
- opts->strategy_opts);
if (opts->allow_rerere_autoupdate > 0)
write_file(state_dir_path("allow_rerere_autoupdate", opts),
"-%s-rerere-autoupdate",
@@ -670,7 +651,7 @@ static int run_am(struct rebase_options *opts)
format_patch.git_cmd = 1;
strvec_pushl(&format_patch.args, "format-patch", "-k", "--stdout",
"--full-index", "--cherry-pick", "--right-only",
- "--src-prefix=a/", "--dst-prefix=b/", "--no-renames",
+ "--default-prefix", "--no-renames",
"--no-cover-letter", "--pretty=mboxrd", "--topo-order",
"--no-base", NULL);
if (opts->git_format_patch_opt.len)
@@ -781,6 +762,16 @@ static int run_specific_rebase(struct rebase_options *opts)
return status ? -1 : 0;
}
+static void parse_rebase_merges_value(struct rebase_options *options, const char *value)
+{
+ if (!strcmp("no-rebase-cousins", value))
+ options->rebase_cousins = 0;
+ else if (!strcmp("rebase-cousins", value))
+ options->rebase_cousins = 1;
+ else
+ die(_("Unknown rebase-merges mode: %s"), value);
+}
+
static int rebase_config(const char *var, const char *value, void *data)
{
struct rebase_options *opts = data;
@@ -810,6 +801,17 @@ static int rebase_config(const char *var, const char *value, void *data)
return 0;
}
+ if (!strcmp(var, "rebase.rebasemerges")) {
+ opts->config_rebase_merges = git_parse_maybe_bool(value);
+ if (opts->config_rebase_merges < 0) {
+ opts->config_rebase_merges = 1;
+ parse_rebase_merges_value(opts, value);
+ } else {
+ opts->rebase_cousins = 0;
+ }
+ return 0;
+ }
+
if (!strcmp(var, "rebase.updaterefs")) {
opts->config_update_refs = git_config_bool(var, value);
return 0;
@@ -991,6 +993,28 @@ static int parse_opt_empty(const struct option *opt, const char *arg, int unset)
return 0;
}
+static int parse_opt_rebase_merges(const struct option *opt, const char *arg, int unset)
+{
+ struct rebase_options *options = opt->value;
+
+ options->rebase_merges = !unset;
+ options->rebase_cousins = 0;
+
+ if (arg) {
+ if (!*arg) {
+ warning(_("--rebase-merges with an empty string "
+ "argument is deprecated and will stop "
+ "working in a future version of Git. Use "
+ "--rebase-merges without an argument "
+ "instead, which does the same thing."));
+ return 0;
+ }
+ parse_rebase_merges_value(options, arg);
+ }
+
+ return 0;
+}
+
static void NORETURN error_on_missing_default_upstream(void)
{
struct branch *current_branch = branch_get(NULL);
@@ -1046,8 +1070,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
struct object_id branch_base;
int ignore_whitespace = 0;
const char *gpg_sign = NULL;
- const char *rebase_merges = NULL;
- struct string_list strategy_options = STRING_LIST_INIT_NODUP;
struct object_id squash_onto;
char *squash_onto_name = NULL;
char *keep_base_onto_name = NULL;
@@ -1148,15 +1170,14 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
&options.allow_empty_message,
N_("allow rebasing commits with empty messages"),
PARSE_OPT_HIDDEN),
- {OPTION_STRING, 'r', "rebase-merges", &rebase_merges,
- N_("mode"),
+ OPT_CALLBACK_F('r', "rebase-merges", &options, N_("mode"),
N_("try to rebase merges instead of skipping them"),
- PARSE_OPT_OPTARG, NULL, (intptr_t)""},
+ PARSE_OPT_OPTARG, parse_opt_rebase_merges),
OPT_BOOL(0, "fork-point", &options.fork_point,
N_("use 'merge-base --fork-point' to refine upstream")),
OPT_STRING('s', "strategy", &options.strategy,
N_("strategy"), N_("use the given merge strategy")),
- OPT_STRING_LIST('X', "strategy-option", &strategy_options,
+ OPT_STRING_LIST('X', "strategy-option", &options.strategy_opts,
N_("option"),
N_("pass the argument through to the merge "
"strategy")),
@@ -1447,17 +1468,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
if (options.exec.nr)
imply_merge(&options, "--exec");
- if (rebase_merges) {
- if (!*rebase_merges)
- ; /* default mode; do nothing */
- else if (!strcmp("rebase-cousins", rebase_merges))
- options.rebase_cousins = 1;
- else if (strcmp("no-rebase-cousins", rebase_merges))
- die(_("Unknown mode: %s"), rebase_merges);
- options.rebase_merges = 1;
- imply_merge(&options, "--rebase-merges");
- }
-
if (options.type == REBASE_APPLY) {
if (ignore_whitespace)
strvec_push(&options.git_am_opts,
@@ -1470,23 +1480,13 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
} else {
/* REBASE_MERGE */
if (ignore_whitespace) {
- string_list_append(&strategy_options,
+ string_list_append(&options.strategy_opts,
"ignore-space-change");
}
}
- if (strategy_options.nr) {
- int i;
-
- if (!options.strategy)
- options.strategy = "ort";
-
- strbuf_reset(&buf);
- for (i = 0; i < strategy_options.nr; i++)
- strbuf_addf(&buf, " --%s",
- strategy_options.items[i].string);
- options.strategy_opts = xstrdup(buf.buf);
- }
+ if (options.strategy_opts.nr && !options.strategy)
+ options.strategy = "ort";
if (options.strategy) {
options.strategy = xstrdup(options.strategy);
@@ -1525,6 +1525,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
"cannot be used together"));
else if (options.autosquash == -1 && options.config_autosquash == 1)
die(_("apply options are incompatible with rebase.autoSquash. Consider adding --no-autosquash"));
+ else if (options.rebase_merges == -1 && options.config_rebase_merges == 1)
+ die(_("apply options are incompatible with rebase.rebaseMerges. Consider adding --no-rebase-merges"));
else if (options.update_refs == -1 && options.config_update_refs == 1)
die(_("apply options are incompatible with rebase.updateRefs. Consider adding --no-update-refs"));
else
@@ -1537,6 +1539,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
options.update_refs = (options.update_refs >= 0) ? options.update_refs :
((options.config_update_refs >= 0) ? options.config_update_refs : 0);
+ if (options.rebase_merges == 1)
+ imply_merge(&options, "--rebase-merges");
+ options.rebase_merges = (options.rebase_merges >= 0) ? options.rebase_merges :
+ ((options.config_rebase_merges >= 0) ? options.config_rebase_merges : 0);
+
if (options.autosquash == 1)
imply_merge(&options, "--autosquash");
options.autosquash = (options.autosquash >= 0) ? options.autosquash :
@@ -1861,10 +1868,9 @@ cleanup:
free(options.gpg_sign_opt);
string_list_clear(&options.exec, 0);
free(options.strategy);
- free(options.strategy_opts);
+ string_list_clear(&options.strategy_opts, 0);
strbuf_release(&options.git_format_patch_opt);
free(squash_onto_name);
free(keep_base_onto_name);
- string_list_clear(&strategy_options, 0);
return !!ret;
}
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index dae99e4554..1a31a58367 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -38,6 +38,7 @@
#include "trace2.h"
#include "worktree.h"
#include "shallow.h"
+#include "parse-options.h"
#include "wrapper.h"
static const char * const receive_pack_usage[] = {
@@ -2096,7 +2097,7 @@ static struct command *read_head_info(struct packet_reader *reader,
const char *feature_list = reader->line + linelen + 1;
const char *hash = NULL;
const char *client_sid;
- int len = 0;
+ size_t len = 0;
if (parse_feature_request(feature_list, "report-status"))
report_status = 1;
if (parse_feature_request(feature_list, "report-status-v2"))
@@ -2191,7 +2192,7 @@ static const char *parse_pack_header(struct pack_header *hdr)
}
}
-static const char *pack_lockfile;
+static struct tempfile *pack_lockfile;
static void push_header_arg(struct strvec *args, struct pack_header *hdr)
{
@@ -2258,6 +2259,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)
return "unpack-objects abnormal exit";
} else {
char hostname[HOST_NAME_MAX + 1];
+ char *lockfile;
strvec_pushl(&child.args, "index-pack", "--stdin", NULL);
push_header_arg(&child.args, &hdr);
@@ -2287,8 +2289,14 @@ static const char *unpack(int err_fd, struct shallow_info *si)
status = start_command(&child);
if (status)
return "index-pack fork failed";
- pack_lockfile = index_pack_lockfile(child.out, NULL);
+
+ lockfile = index_pack_lockfile(child.out, NULL);
+ if (lockfile) {
+ pack_lockfile = register_tempfile(lockfile);
+ free(lockfile);
+ }
close(child.out);
+
status = finish_command(&child);
if (status)
return "index-pack abnormal exit";
@@ -2575,8 +2583,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
use_keepalive = KEEPALIVE_ALWAYS;
execute_commands(commands, unpack_status, &si,
&push_options);
- if (pack_lockfile)
- unlink_or_warn(pack_lockfile);
+ delete_tempfile(&pack_lockfile);
sigchain_push(SIGPIPE, SIG_IGN);
if (report_status_v2)
report_v2(commands, unpack_status);
diff --git a/builtin/reflog.c b/builtin/reflog.c
index 0879d4d224..a1fa0c855f 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -5,6 +5,7 @@
#include "reachable.h"
#include "worktree.h"
#include "reflog.h"
+#include "parse-options.h"
#define BUILTIN_REFLOG_SHOW_USAGE \
N_("git reflog [show] [<log-options>] [<ref>]")
diff --git a/builtin/remote-ext.c b/builtin/remote-ext.c
index ee338bf440..282782eccd 100644
--- a/builtin/remote-ext.c
+++ b/builtin/remote-ext.c
@@ -197,6 +197,8 @@ static int command_loop(const char *child)
int cmd_remote_ext(int argc, const char **argv, const char *prefix)
{
+ BUG_ON_NON_EMPTY_PREFIX(prefix);
+
if (argc != 3)
usage(usage_msg);
diff --git a/builtin/remote-fd.c b/builtin/remote-fd.c
index b2a3980b1d..9020fab9c5 100644
--- a/builtin/remote-fd.c
+++ b/builtin/remote-fd.c
@@ -59,6 +59,8 @@ int cmd_remote_fd(int argc, const char **argv, const char *prefix)
int output_fd = -1;
char *end;
+ BUG_ON_NON_EMPTY_PREFIX(prefix);
+
if (argc != 3)
usage(usage_msg);
diff --git a/builtin/repack.c b/builtin/repack.c
index bed2c2aaaf..0541c3ce15 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -326,7 +326,8 @@ static int geometry_cmp(const void *va, const void *vb)
}
static void init_pack_geometry(struct pack_geometry **geometry_p,
- struct string_list *existing_kept_packs)
+ struct string_list *existing_kept_packs,
+ const struct pack_objects_args *args)
{
struct packed_git *p;
struct pack_geometry *geometry;
@@ -336,6 +337,14 @@ static void init_pack_geometry(struct pack_geometry **geometry_p,
geometry = *geometry_p;
for (p = get_all_packs(the_repository); p; p = p->next) {
+ if (args->local && !p->pack_local)
+ /*
+ * When asked to only repack local packfiles we skip
+ * over any packfiles that are borrowed from alternate
+ * object directories.
+ */
+ continue;
+
if (!pack_kept_objects) {
/*
* Any pack that has its pack_keep bit set will appear
@@ -449,8 +458,10 @@ static void split_pack_geometry(struct pack_geometry *geometry, int factor)
geometry->split = split;
}
-static struct packed_git *get_largest_active_pack(struct pack_geometry *geometry)
+static struct packed_git *get_preferred_pack(struct pack_geometry *geometry)
{
+ uint32_t i;
+
if (!geometry) {
/*
* No geometry means either an all-into-one repack (in which
@@ -465,7 +476,21 @@ static struct packed_git *get_largest_active_pack(struct pack_geometry *geometry
}
if (geometry->split == geometry->pack_nr)
return NULL;
- return geometry->pack[geometry->pack_nr - 1];
+
+ /*
+ * The preferred pack is the largest pack above the split line. In
+ * other words, it is the largest pack that does not get rolled up in
+ * the geometric repack.
+ */
+ for (i = geometry->pack_nr; i > geometry->split; i--)
+ /*
+ * A pack that is not local would never be included in a
+ * multi-pack index. We thus skip over any non-local packs.
+ */
+ if (geometry->pack[i - 1]->pack_local)
+ return geometry->pack[i - 1];
+
+ return NULL;
}
static void clear_pack_geometry(struct pack_geometry *geometry)
@@ -559,6 +584,17 @@ static void midx_included_packs(struct string_list *include,
for (i = geometry->split; i < geometry->pack_nr; i++) {
struct packed_git *p = geometry->pack[i];
+ /*
+ * The multi-pack index never refers to packfiles part
+ * of an alternate object database, so we skip these.
+ * While git-multi-pack-index(1) would silently ignore
+ * them anyway, this allows us to skip executing the
+ * command completely when we have only non-local
+ * packfiles.
+ */
+ if (!p->pack_local)
+ continue;
+
strbuf_addstr(&buf, pack_basename(p));
strbuf_strip_suffix(&buf, ".pack");
strbuf_addstr(&buf, ".idx");
@@ -592,7 +628,7 @@ static int write_midx_included_packs(struct string_list *include,
{
struct child_process cmd = CHILD_PROCESS_INIT;
struct string_list_item *item;
- struct packed_git *largest = get_largest_active_pack(geometry);
+ struct packed_git *preferred = get_preferred_pack(geometry);
FILE *in;
int ret;
@@ -613,9 +649,9 @@ static int write_midx_included_packs(struct string_list *include,
if (write_bitmaps)
strvec_push(&cmd.args, "--bitmap");
- if (largest)
+ if (preferred)
strvec_pushf(&cmd.args, "--preferred-pack=%s",
- pack_basename(largest));
+ pack_basename(preferred));
if (refs_snapshot)
strvec_pushf(&cmd.args, "--refs-snapshot=%s", refs_snapshot);
@@ -775,7 +811,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
N_("same as -a, pack unreachable cruft objects separately"),
PACK_CRUFT),
OPT_STRING(0, "cruft-expiration", &cruft_expiration, N_("approxidate"),
- N_("with -C, expire objects older than this")),
+ N_("with --cruft, expire objects older than this")),
OPT_BOOL('d', NULL, &delete_redundant,
N_("remove redundant packs, and run git-prune-packed")),
OPT_BOOL('f', NULL, &po_args.no_reuse_delta,
@@ -854,6 +890,18 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
if (write_bitmaps && !(pack_everything & ALL_INTO_ONE) && !write_midx)
die(_(incremental_bitmap_conflict_error));
+ if (write_bitmaps && po_args.local && has_alt_odb(the_repository)) {
+ /*
+ * When asked to do a local repack, but we have
+ * packfiles that are inherited from an alternate, then
+ * we cannot guarantee that the multi-pack-index would
+ * have full coverage of all objects. We thus disable
+ * writing bitmaps in that case.
+ */
+ warning(_("disabling bitmap writing, as some objects are not being packed"));
+ write_bitmaps = 0;
+ }
+
if (write_midx && write_bitmaps) {
struct strbuf path = STRBUF_INIT;
@@ -876,7 +924,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
if (geometric_factor) {
if (pack_everything)
die(_("options '%s' and '%s' cannot be used together"), "--geometric", "-A/-a");
- init_pack_geometry(&geometry, &existing_kept_packs);
+ init_pack_geometry(&geometry, &existing_kept_packs, &po_args);
split_pack_geometry(geometry, geometric_factor);
}
diff --git a/builtin/revert.c b/builtin/revert.c
index dd6587a99d..0240ec8593 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -45,20 +45,6 @@ static const char * const *revert_or_cherry_pick_usage(struct replay_opts *opts)
return opts->action == REPLAY_REVERT ? revert_usage : cherry_pick_usage;
}
-static int option_parse_x(const struct option *opt,
- const char *arg, int unset)
-{
- struct replay_opts **opts_ptr = opt->value;
- struct replay_opts *opts = *opts_ptr;
-
- if (unset)
- return 0;
-
- ALLOC_GROW(opts->xopts, opts->xopts_nr + 1, opts->xopts_alloc);
- opts->xopts[opts->xopts_nr++] = xstrdup(arg);
- return 0;
-}
-
static int option_parse_m(const struct option *opt,
const char *arg, int unset)
{
@@ -95,7 +81,8 @@ static void verify_opt_compatible(const char *me, const char *base_opt, ...)
die(_("%s: %s cannot be used with %s"), me, this_opt, base_opt);
}
-static int run_sequencer(int argc, const char **argv, struct replay_opts *opts)
+static int run_sequencer(int argc, const char **argv, const char *prefix,
+ struct replay_opts *opts)
{
const char * const * usage_str = revert_or_cherry_pick_usage(opts);
const char *me = action_name(opts);
@@ -115,8 +102,8 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts)
N_("select mainline parent"), option_parse_m),
OPT_RERERE_AUTOUPDATE(&opts->allow_rerere_auto),
OPT_STRING(0, "strategy", &opts->strategy, N_("strategy"), N_("merge strategy")),
- OPT_CALLBACK('X', "strategy-option", &opts, N_("option"),
- N_("option for merge strategy"), option_parse_x),
+ OPT_STRVEC('X', "strategy-option", &opts->xopts, N_("option"),
+ N_("option for merge strategy")),
{ OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"),
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_END()
@@ -142,7 +129,7 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts)
options = parse_options_concat(options, cp_extra);
}
- argc = parse_options(argc, argv, NULL, options, usage_str,
+ argc = parse_options(argc, argv, prefix, options, usage_str,
PARSE_OPT_KEEP_ARGV0 |
PARSE_OPT_KEEP_UNKNOWN_OPT);
@@ -177,7 +164,7 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts)
"--signoff", opts->signoff,
"--mainline", opts->mainline,
"--strategy", opts->strategy ? 1 : 0,
- "--strategy-option", opts->xopts ? 1 : 0,
+ "--strategy-option", opts->xopts.nr ? 1 : 0,
"-x", opts->record_origin,
"--ff", opts->allow_ff,
"--rerere-autoupdate", opts->allow_rerere_auto == RERERE_AUTOUPDATE,
@@ -247,7 +234,7 @@ int cmd_revert(int argc, const char **argv, const char *prefix)
opts.action = REPLAY_REVERT;
sequencer_init_config(&opts);
- res = run_sequencer(argc, argv, &opts);
+ res = run_sequencer(argc, argv, prefix, &opts);
if (res < 0)
die(_("revert failed"));
replay_opts_release(&opts);
@@ -261,7 +248,7 @@ int cmd_cherry_pick(int argc, const char **argv, const char *prefix)
opts.action = REPLAY_PICK;
sequencer_init_config(&opts);
- res = run_sequencer(argc, argv, &opts);
+ res = run_sequencer(argc, argv, prefix, &opts);
if (res < 0)
die(_("cherry-pick failed"));
replay_opts_release(&opts);
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 2b360fee42..4784143004 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -16,6 +16,7 @@
#include "gpg-interface.h"
#include "gettext.h"
#include "protocol.h"
+#include "parse-options.h"
#include "write-or-die.h"
static const char * const send_pack_usage[] = {
@@ -275,7 +276,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
fd[0] = 0;
fd[1] = 1;
} else {
- conn = git_connect(fd, dest, receivepack,
+ conn = git_connect(fd, dest, "git-receive-pack", receivepack,
args.verbose ? CONNECT_VERBOSE : 0);
}
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
index 4de37d07fd..40d420f06c 100644
--- a/builtin/sparse-checkout.c
+++ b/builtin/sparse-checkout.c
@@ -25,7 +25,7 @@
static const char *empty_base = "";
static char const * const builtin_sparse_checkout_usage[] = {
- N_("git sparse-checkout (init | list | set | add | reapply | disable) [<options>]"),
+ N_("git sparse-checkout (init | list | set | add | reapply | disable | check-rules) [<options>]"),
NULL
};
@@ -62,6 +62,7 @@ static int sparse_checkout_list(int argc, const char **argv, const char *prefix)
char *sparse_filename;
int res;
+ setup_work_tree();
if (!core_apply_sparse_checkout)
die(_("this worktree is not sparse"));
@@ -386,13 +387,7 @@ static int set_config(enum sparse_checkout_mode mode)
return 0;
}
-static int update_modes(int *cone_mode, int *sparse_index)
-{
- int mode, record_mode;
-
- /* Determine if we need to record the mode; ensure sparse checkout on */
- record_mode = (*cone_mode != -1) || !core_apply_sparse_checkout;
-
+static enum sparse_checkout_mode update_cone_mode(int *cone_mode) {
/* If not specified, use previous definition of cone mode */
if (*cone_mode == -1 && core_apply_sparse_checkout)
*cone_mode = core_sparse_checkout_cone;
@@ -400,12 +395,21 @@ static int update_modes(int *cone_mode, int *sparse_index)
/* Set cone/non-cone mode appropriately */
core_apply_sparse_checkout = 1;
if (*cone_mode == 1 || *cone_mode == -1) {
- mode = MODE_CONE_PATTERNS;
core_sparse_checkout_cone = 1;
- } else {
- mode = MODE_ALL_PATTERNS;
- core_sparse_checkout_cone = 0;
+ return MODE_CONE_PATTERNS;
}
+ core_sparse_checkout_cone = 0;
+ return MODE_ALL_PATTERNS;
+}
+
+static int update_modes(int *cone_mode, int *sparse_index)
+{
+ int mode, record_mode;
+
+ /* Determine if we need to record the mode; ensure sparse checkout on */
+ record_mode = (*cone_mode != -1) || !core_apply_sparse_checkout;
+
+ mode = update_cone_mode(cone_mode);
if (record_mode && set_config(mode))
return 1;
@@ -451,6 +455,7 @@ static int sparse_checkout_init(int argc, const char **argv, const char *prefix)
OPT_END(),
};
+ setup_work_tree();
repo_read_index(the_repository);
init_opts.cone_mode = -1;
@@ -548,7 +553,7 @@ static void strbuf_to_cone_pattern(struct strbuf *line, struct pattern_list *pl)
static void add_patterns_from_input(struct pattern_list *pl,
int argc, const char **argv,
- int use_stdin)
+ FILE *file)
{
int i;
if (core_sparse_checkout_cone) {
@@ -558,9 +563,9 @@ static void add_patterns_from_input(struct pattern_list *pl,
hashmap_init(&pl->parent_hashmap, pl_hashmap_cmp, NULL, 0);
pl->use_cone_patterns = 1;
- if (use_stdin) {
+ if (file) {
struct strbuf unquoted = STRBUF_INIT;
- while (!strbuf_getline(&line, stdin)) {
+ while (!strbuf_getline(&line, file)) {
if (line.buf[0] == '"') {
strbuf_reset(&unquoted);
if (unquote_c_style(&unquoted, line.buf, NULL))
@@ -582,10 +587,10 @@ static void add_patterns_from_input(struct pattern_list *pl,
}
}
} else {
- if (use_stdin) {
+ if (file) {
struct strbuf line = STRBUF_INIT;
- while (!strbuf_getline(&line, stdin)) {
+ while (!strbuf_getline(&line, file)) {
size_t len;
char *buf = strbuf_detach(&line, &len);
add_pattern(buf, empty_base, 0, pl, 0);
@@ -612,7 +617,8 @@ static void add_patterns_cone_mode(int argc, const char **argv,
struct pattern_list existing;
char *sparse_filename = get_sparse_checkout_filename();
- add_patterns_from_input(pl, argc, argv, use_stdin);
+ add_patterns_from_input(pl, argc, argv,
+ use_stdin ? stdin : NULL);
memset(&existing, 0, sizeof(existing));
existing.use_cone_patterns = core_sparse_checkout_cone;
@@ -649,7 +655,7 @@ static void add_patterns_literal(int argc, const char **argv,
pl, NULL, 0))
die(_("unable to load existing sparse-checkout patterns"));
free(sparse_filename);
- add_patterns_from_input(pl, argc, argv, use_stdin);
+ add_patterns_from_input(pl, argc, argv, use_stdin ? stdin : NULL);
}
static int modify_pattern_list(int argc, const char **argv, int use_stdin,
@@ -668,7 +674,8 @@ static int modify_pattern_list(int argc, const char **argv, int use_stdin,
break;
case REPLACE:
- add_patterns_from_input(pl, argc, argv, use_stdin);
+ add_patterns_from_input(pl, argc, argv,
+ use_stdin ? stdin : NULL);
break;
}
@@ -763,6 +770,7 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
OPT_END(),
};
+ setup_work_tree();
if (!core_apply_sparse_checkout)
die(_("no sparse-checkout to add to"));
@@ -809,6 +817,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
OPT_END(),
};
+ setup_work_tree();
repo_read_index(the_repository);
set_opts.cone_mode = -1;
@@ -858,6 +867,7 @@ static int sparse_checkout_reapply(int argc, const char **argv,
OPT_END(),
};
+ setup_work_tree();
if (!core_apply_sparse_checkout)
die(_("must be in a sparse-checkout to reapply sparsity patterns"));
@@ -901,6 +911,7 @@ static int sparse_checkout_disable(int argc, const char **argv,
* forcibly return to a dense checkout regardless of initial state.
*/
+ setup_work_tree();
argc = parse_options(argc, argv, prefix,
builtin_sparse_checkout_disable_options,
builtin_sparse_checkout_disable_usage, 0);
@@ -926,6 +937,91 @@ static int sparse_checkout_disable(int argc, const char **argv,
return set_config(MODE_NO_PATTERNS);
}
+static char const * const builtin_sparse_checkout_check_rules_usage[] = {
+ N_("git sparse-checkout check-rules [-z] [--skip-checks]"
+ "[--[no-]cone] [--rules-file <file>]"),
+ NULL
+};
+
+static struct sparse_checkout_check_rules_opts {
+ int cone_mode;
+ int null_termination;
+ char *rules_file;
+} check_rules_opts;
+
+static int check_rules(struct pattern_list *pl, int null_terminated) {
+ struct strbuf line = STRBUF_INIT;
+ struct strbuf unquoted = STRBUF_INIT;
+ char *path;
+ int line_terminator = null_terminated ? 0 : '\n';
+ strbuf_getline_fn getline_fn = null_terminated ? strbuf_getline_nul
+ : strbuf_getline;
+ the_repository->index->sparse_checkout_patterns = pl;
+ while (!getline_fn(&line, stdin)) {
+ path = line.buf;
+ if (!null_terminated && line.buf[0] == '"') {
+ strbuf_reset(&unquoted);
+ if (unquote_c_style(&unquoted, line.buf, NULL))
+ die(_("unable to unquote C-style string '%s'"),
+ line.buf);
+
+ path = unquoted.buf;
+ }
+
+ if (path_in_sparse_checkout(path, the_repository->index))
+ write_name_quoted(path, stdout, line_terminator);
+ }
+ strbuf_release(&line);
+ strbuf_release(&unquoted);
+
+ return 0;
+}
+
+static int sparse_checkout_check_rules(int argc, const char **argv, const char *prefix)
+{
+ static struct option builtin_sparse_checkout_check_rules_options[] = {
+ OPT_BOOL('z', NULL, &check_rules_opts.null_termination,
+ N_("terminate input and output files by a NUL character")),
+ OPT_BOOL(0, "cone", &check_rules_opts.cone_mode,
+ N_("when used with --rules-file interpret patterns as cone mode patterns")),
+ OPT_FILENAME(0, "rules-file", &check_rules_opts.rules_file,
+ N_("use patterns in <file> instead of the current ones.")),
+ OPT_END(),
+ };
+
+ FILE *fp;
+ int ret;
+ struct pattern_list pl = {0};
+ char *sparse_filename;
+ check_rules_opts.cone_mode = -1;
+
+ argc = parse_options(argc, argv, prefix,
+ builtin_sparse_checkout_check_rules_options,
+ builtin_sparse_checkout_check_rules_usage,
+ PARSE_OPT_KEEP_UNKNOWN_OPT);
+
+ if (check_rules_opts.rules_file && check_rules_opts.cone_mode < 0)
+ check_rules_opts.cone_mode = 1;
+
+ update_cone_mode(&check_rules_opts.cone_mode);
+ pl.use_cone_patterns = core_sparse_checkout_cone;
+ if (check_rules_opts.rules_file) {
+ fp = xfopen(check_rules_opts.rules_file, "r");
+ add_patterns_from_input(&pl, argc, argv, fp);
+ fclose(fp);
+ } else {
+ sparse_filename = get_sparse_checkout_filename();
+ if (add_patterns_from_file_to_list(sparse_filename, "", 0, &pl,
+ NULL, 0))
+ die(_("unable to load existing sparse-checkout patterns"));
+ free(sparse_filename);
+ }
+
+ ret = check_rules(&pl, check_rules_opts.null_termination);
+ clear_pattern_list(&pl);
+ return ret;
+}
+
int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)
{
parse_opt_subcommand_fn *fn = NULL;
@@ -936,6 +1032,7 @@ int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)
OPT_SUBCOMMAND("add", &fn, sparse_checkout_add),
OPT_SUBCOMMAND("reapply", &fn, sparse_checkout_reapply),
OPT_SUBCOMMAND("disable", &fn, sparse_checkout_disable),
+ OPT_SUBCOMMAND("check-rules", &fn, sparse_checkout_check_rules),
OPT_END(),
};
diff --git a/builtin/stash.c b/builtin/stash.c
index 6442b5e20a..a7e17ffe38 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -1473,7 +1473,7 @@ done:
return ret;
}
-static int create_stash(int argc, const char **argv, const char *prefix)
+static int create_stash(int argc, const char **argv, const char *prefix UNUSED)
{
int ret;
struct strbuf stash_msg_buf = STRBUF_INIT;
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 5d999f814e..6bf8d666ce 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -565,7 +565,7 @@ static int module_init(int argc, const char **argv, const char *prefix)
* If there are no path args and submodule.active is set then,
* by default, only initialize 'active' modules.
*/
- if (!argc && git_config_get_value_multi("submodule.active"))
+ if (!argc && !git_config_get("submodule.active"))
module_list_active(&list);
info.prefix = prefix;
@@ -2751,7 +2751,7 @@ static int module_update(int argc, const char **argv, const char *prefix)
* If there are no path args and submodule.active is set then,
* by default, only initialize 'active' modules.
*/
- if (!argc && git_config_get_value_multi("submodule.active"))
+ if (!argc && !git_config_get("submodule.active"))
module_list_active(&list);
info.prefix = opt.prefix;
@@ -2772,7 +2772,7 @@ cleanup:
return ret;
}
-static int push_check(int argc, const char **argv, const char *prefix)
+static int push_check(int argc, const char **argv, const char *prefix UNUSED)
{
struct remote *remote;
const char *superproject_head;
@@ -3148,7 +3148,6 @@ static int config_submodule_in_gitmodules(const char *name, const char *var, con
static void configure_added_submodule(struct add_data *add_data)
{
char *key;
- const char *val;
struct child_process add_submod = CHILD_PROCESS_INIT;
struct child_process add_gitmodules = CHILD_PROCESS_INIT;
@@ -3193,7 +3192,7 @@ static void configure_added_submodule(struct add_data *add_data)
* is_submodule_active(), since that function needs to find
* out the value of "submodule.active" again anyway.
*/
- if (!git_config_get_string_tmp("submodule.active", &val)) {
+ if (!git_config_get("submodule.active")) {
/*
* If the submodule being added isn't already covered by the
* current configured pathspec, set the submodule's active flag
diff --git a/builtin/tag.c b/builtin/tag.c
index 7d189a4a5d..1850a6a6fd 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -44,6 +44,7 @@ static const char * const git_tag_usage[] = {
static unsigned int colopts;
static int force_sign_annotate;
static int config_sign_tag = -1; /* unspecified */
+static int omit_empty = 0;
static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
struct ref_format *format)
@@ -73,6 +74,7 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
die(_("unable to parse format string"));
filter->with_commit_tag_algo = 1;
filter_refs(&array, filter, FILTER_REFS_TAGS);
+ filter_ahead_behind(the_repository, format, &array);
ref_array_sort(sorting, &array);
for (i = 0; i < array.nr; i++) {
@@ -81,7 +83,8 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
if (format_ref_array_item(array.items[i], format, &output, &err))
die("%s", err.buf);
fwrite(output.buf, 1, output.len, stdout);
- putchar('\n');
+ if (output.len || !omit_empty)
+ putchar('\n');
}
strbuf_release(&err);
@@ -476,6 +479,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
OPT_WITHOUT(&filter.no_commit, N_("print only tags that don't contain the commit")),
OPT_MERGED(&filter, N_("print only tags that are merged")),
OPT_NO_MERGED(&filter, N_("print only tags that are not merged")),
+ OPT_BOOL(0, "omit-empty", &omit_empty,
+ N_("do not output a newline after empty formatted refs")),
OPT_REF_SORT(&sorting_options),
{
OPTION_CALLBACK, 0, "points-at", &filter.points_at, N_("object"),
diff --git a/builtin/unpack-file.c b/builtin/unpack-file.c
index 21082ceb60..b35a4b9dfe 100644
--- a/builtin/unpack-file.c
+++ b/builtin/unpack-file.c
@@ -26,7 +26,7 @@ static char *create_temp_file(struct object_id *oid)
return path;
}
-int cmd_unpack_file(int argc, const char **argv, const char *prefix)
+int cmd_unpack_file(int argc, const char **argv, const char *prefix UNUSED)
{
struct object_id oid;
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index ddbdb3dd22..2c52c3a741 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -604,7 +604,7 @@ static void unpack_all(void)
die("unresolved deltas left after unpacking");
}
-int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
+int cmd_unpack_objects(int argc, const char **argv, const char *prefix UNUSED)
{
int i;
struct object_id oid;
diff --git a/builtin/upload-archive.c b/builtin/upload-archive.c
index 5be97ca1af..44ad400e18 100644
--- a/builtin/upload-archive.c
+++ b/builtin/upload-archive.c
@@ -80,6 +80,8 @@ int cmd_upload_archive(int argc, const char **argv, const char *prefix)
{
struct child_process writer = CHILD_PROCESS_INIT;
+ BUG_ON_NON_EMPTY_PREFIX(prefix);
+
if (argc == 2 && !strcmp(argv[1], "-h"))
usage(upload_archive_usage);
diff --git a/builtin/var.c b/builtin/var.c
index aa8150fa92..2149998980 100644
--- a/builtin/var.c
+++ b/builtin/var.c
@@ -80,7 +80,7 @@ static int show_config(const char *var, const char *value, void *cb)
return git_default_config(var, value, cb);
}
-int cmd_var(int argc, const char **argv, const char *prefix)
+int cmd_var(int argc, const char **argv, const char *prefix UNUSED)
{
const struct git_var *git_var;
const char *val;
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 5d3ca819e7..f3180463be 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -328,7 +328,6 @@ static void copy_filtered_worktree_config(const char *worktree_git_dir)
if (file_exists(from_file)) {
struct config_set cs = { { 0 } };
- const char *core_worktree;
int bare;
if (safe_create_leading_directories(to_file) ||
@@ -347,7 +346,7 @@ static void copy_filtered_worktree_config(const char *worktree_git_dir)
to_file, "core.bare", NULL, "true", 0))
error(_("failed to unset '%s' in '%s'"),
"core.bare", to_file);
- if (!git_configset_get_value(&cs, "core.worktree", &core_worktree) &&
+ if (!git_configset_get(&cs, "core.worktree") &&
git_config_set_in_file_gently(to_file,
"core.worktree", NULL))
error(_("failed to unset '%s' in '%s'"),
diff --git a/builtin/write-tree.c b/builtin/write-tree.c
index 6085f64d10..84b83318c9 100644
--- a/builtin/write-tree.c
+++ b/builtin/write-tree.c
@@ -13,6 +13,7 @@
#include "tree.h"
#include "cache-tree.h"
#include "parse-options.h"
+#include "repository.h"
static const char * const write_tree_usage[] = {
N_("git write-tree [--missing-ok] [--prefix=<prefix>/]"),
@@ -41,6 +42,9 @@ int cmd_write_tree(int argc, const char **argv, const char *cmd_prefix)
argc = parse_options(argc, argv, cmd_prefix, write_tree_options,
write_tree_usage, 0);
+ prepare_repo_settings(the_repository);
+ the_repository->settings.command_requires_full_index = 0;
+
ret = write_index_as_tree(&oid, &the_index, get_index_file(), flags,
tree_prefix);
switch (ret) {