summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/add.c15
-rw-r--r--builtin/am.c2
-rw-r--r--builtin/archive.c4
-rw-r--r--builtin/branch.c2
-rw-r--r--builtin/bugreport.c5
-rw-r--r--builtin/checkout.c8
-rw-r--r--builtin/clone.c15
-rw-r--r--builtin/column.c2
-rw-r--r--builtin/commit-graph.c106
-rw-r--r--builtin/commit-tree.c4
-rw-r--r--builtin/commit.c4
-rw-r--r--builtin/diff-index.c6
-rw-r--r--builtin/fast-export.c1
-rw-r--r--builtin/fetch.c93
-rw-r--r--builtin/gc.c93
-rw-r--r--builtin/grep.c64
-rw-r--r--builtin/hash-object.c6
-rw-r--r--builtin/index-pack.c8
-rw-r--r--builtin/ls-remote.c2
-rw-r--r--builtin/mailsplit.c4
-rw-r--r--builtin/merge.c8
-rw-r--r--builtin/multi-pack-index.c13
-rw-r--r--builtin/notes.c4
-rw-r--r--builtin/pack-objects.c93
-rw-r--r--builtin/push.c12
-rw-r--r--builtin/rebase.c3
-rw-r--r--builtin/receive-pack.c17
-rw-r--r--builtin/repack.c12
-rw-r--r--builtin/replace.c2
-rw-r--r--builtin/reset.c2
-rw-r--r--builtin/rm.c2
-rw-r--r--builtin/show-branch.c15
-rw-r--r--builtin/submodule--helper.c2
-rw-r--r--builtin/tag.c4
-rw-r--r--builtin/update-index.c4
35 files changed, 317 insertions, 320 deletions
diff --git a/builtin/add.c b/builtin/add.c
index 17528e8f92..2244311d48 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -319,9 +319,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix)
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
rev.diffopt.use_color = 0;
rev.diffopt.flags.ignore_dirty_submodules = 1;
- out = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
- if (out < 0)
- die(_("Could not open '%s' for writing."), file);
+ out = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
rev.diffopt.file = xfdopen(out, "w");
rev.diffopt.close_file = 1;
if (run_diff_files(&rev, 0))
@@ -425,6 +423,7 @@ static const char embedded_advice[] = N_(
static void check_embedded_repo(const char *path)
{
struct strbuf name = STRBUF_INIT;
+ static int adviced_on_embedded_repo = 0;
if (!warn_on_embedded_repo)
return;
@@ -436,10 +435,10 @@ static void check_embedded_repo(const char *path)
strbuf_strip_suffix(&name, "/");
warning(_("adding embedded git repository: %s"), name.buf);
- if (advice_add_embedded_repo) {
+ if (!adviced_on_embedded_repo &&
+ advice_enabled(ADVICE_ADD_EMBEDDED_REPO)) {
advise(embedded_advice, name.buf, name.buf);
- /* there may be multiple entries; advise only once */
- advice_add_embedded_repo = 0;
+ adviced_on_embedded_repo = 1;
}
strbuf_release(&name);
@@ -453,7 +452,7 @@ static int add_files(struct dir_struct *dir, int flags)
fprintf(stderr, _(ignore_error));
for (i = 0; i < dir->ignored_nr; i++)
fprintf(stderr, "%s\n", dir->ignored[i]->name);
- if (advice_add_ignored_file)
+ if (advice_enabled(ADVICE_ADD_IGNORED_FILE))
advise(_("Use -f if you really want to add them.\n"
"Turn this message off by running\n"
"\"git config advice.addIgnoredFile false\""));
@@ -562,7 +561,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
if (require_pathspec && pathspec.nr == 0) {
fprintf(stderr, _("Nothing specified, nothing added.\n"));
- if (advice_add_empty_pathspec)
+ if (advice_enabled(ADVICE_ADD_EMPTY_PATHSPEC))
advise( _("Maybe you wanted to say 'git add .'?\n"
"Turn this message off by running\n"
"\"git config advice.addEmptyPathspec false\""));
diff --git a/builtin/am.c b/builtin/am.c
index 0c2ad96b70..ff7dd33fcd 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -1820,7 +1820,7 @@ static void am_run(struct am_state *state, int resume)
printf_ln(_("Patch failed at %s %.*s"), msgnum(state),
linelen(state->msg), state->msg);
- if (advice_amworkdir)
+ if (advice_enabled(ADVICE_AM_WORK_DIR))
advise(_("Use 'git am --show-current-patch=diff' to see the failed patch"));
die_user_resolve(state);
diff --git a/builtin/archive.c b/builtin/archive.c
index 45d11669aa..7176b041b6 100644
--- a/builtin/archive.c
+++ b/builtin/archive.c
@@ -12,9 +12,7 @@
static void create_output_file(const char *output_file)
{
- int output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
- if (output_fd < 0)
- die_errno(_("could not create archive file '%s'"), output_file);
+ int output_fd = xopen(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (output_fd != 1) {
if (dup2(output_fd, 1) < 0)
die_errno(_("could not redirect output"));
diff --git a/builtin/branch.c b/builtin/branch.c
index b23b1d1752..03c7b7253a 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -168,7 +168,7 @@ static int check_branch_commit(const char *branchname, const char *refname,
int kinds, int force)
{
struct commit *rev = lookup_commit_reference(the_repository, oid);
- if (!rev) {
+ if (!force && !rev) {
error(_("Couldn't look up commit object for '%s'"), refname);
return -1;
}
diff --git a/builtin/bugreport.c b/builtin/bugreport.c
index 9915a5841d..06ed10dc92 100644
--- a/builtin/bugreport.c
+++ b/builtin/bugreport.c
@@ -171,10 +171,7 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)
get_populated_hooks(&buffer, !startup_info->have_repository);
/* fopen doesn't offer us an O_EXCL alternative, except with glibc. */
- report = open(report_path.buf, O_CREAT | O_EXCL | O_WRONLY, 0666);
-
- if (report < 0)
- die(_("couldn't create a new file at '%s'"), report_path.buf);
+ report = xopen(report_path.buf, O_CREAT | O_EXCL | O_WRONLY, 0666);
if (write_in_full(report, buffer.buf, buffer.len) < 0)
die_errno(_("unable to write to %s"), report_path.buf);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index b5d477919a..8c69dcdf72 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -404,7 +404,7 @@ static int checkout_worktree(const struct checkout_opts *opts,
mem_pool_discard(&ce_mem_pool, should_validate_cache_entries());
remove_marked_cache_entries(&the_index, 1);
remove_scheduled_dirs();
- errs |= finish_delayed_checkout(&state, &nr_checkouts);
+ errs |= finish_delayed_checkout(&state, &nr_checkouts, opts->show_progress);
if (opts->count_checkout_paths) {
if (nr_unmerged)
@@ -918,7 +918,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
REF_NO_DEREF, UPDATE_REFS_DIE_ON_ERR);
if (!opts->quiet) {
if (old_branch_info->path &&
- advice_detached_head && !opts->force_detach)
+ advice_enabled(ADVICE_DETACHED_HEAD) && !opts->force_detach)
detach_advice(new_branch_info->name);
describe_detached_head(_("HEAD is now at"), new_branch_info->commit);
}
@@ -1011,7 +1011,7 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs)
sb.buf);
strbuf_release(&sb);
- if (advice_detached_head)
+ if (advice_enabled(ADVICE_DETACHED_HEAD))
fprintf(stderr,
Q_(
/* The singular version */
@@ -1182,7 +1182,7 @@ static const char *parse_remote_branch(const char *arg,
}
if (!remote && num_matches > 1) {
- if (advice_checkout_ambiguous_remote_branch_name) {
+ if (advice_enabled(ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME)) {
advise(_("If you meant to check out a remote tracking branch on, e.g. 'origin',\n"
"you can do so by fully qualifying the name with the --track option:\n"
"\n"
diff --git a/builtin/clone.c b/builtin/clone.c
index 66fe66679c..143b4e0a3e 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -657,7 +657,7 @@ static void write_followtags(const struct ref *refs, const char *msg)
}
}
-static int iterate_ref_map(void *cb_data, struct object_id *oid)
+static const struct object_id *iterate_ref_map(void *cb_data)
{
struct ref **rm = cb_data;
struct ref *ref = *rm;
@@ -668,13 +668,11 @@ static int iterate_ref_map(void *cb_data, struct object_id *oid)
*/
while (ref && !ref->peer_ref)
ref = ref->next;
- /* Returning -1 notes "end of list" to the caller. */
if (!ref)
- return -1;
+ return NULL;
- oidcpy(oid, &ref->old_oid);
*rm = ref->next;
- return 0;
+ return &ref->old_oid;
}
static void update_remote_refs(const struct ref *refs,
@@ -786,7 +784,7 @@ static int checkout(int submodule_progress)
return 0;
}
if (!strcmp(head, "HEAD")) {
- if (advice_detached_head)
+ if (advice_enabled(ADVICE_DETACHED_HEAD))
detach_advice(oid_to_hex(&oid));
FREE_AND_NULL(head);
} else {
@@ -1114,6 +1112,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (option_recurse_submodules.nr > 0) {
struct string_list_item *item;
struct strbuf sb = STRBUF_INIT;
+ int val;
/* remove duplicates */
string_list_sort(&option_recurse_submodules);
@@ -1130,6 +1129,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
strbuf_detach(&sb, NULL));
}
+ if (!git_config_get_bool("submodule.stickyRecursiveClone", &val) &&
+ val)
+ string_list_append(&option_config, "submodule.recurse=true");
+
if (option_required_reference.nr &&
option_optional_reference.nr)
die(_("clone --recursive is not compatible with "
diff --git a/builtin/column.c b/builtin/column.c
index 40d4b3bee2..158fdf53d9 100644
--- a/builtin/column.c
+++ b/builtin/column.c
@@ -29,7 +29,7 @@ int cmd_column(int argc, const char **argv, const char *prefix)
OPT_INTEGER(0, "raw-mode", &colopts, N_("layout to use")),
OPT_INTEGER(0, "width", &copts.width, N_("maximum width")),
OPT_STRING(0, "indent", &copts.indent, N_("string"), N_("padding space on left border")),
- OPT_INTEGER(0, "nl", &copts.nl, N_("padding space on right border")),
+ OPT_STRING(0, "nl", &copts.nl, N_("string"), N_("padding space on right border")),
OPT_INTEGER(0, "padding", &copts.padding, N_("padding space between columns")),
OPT_END()
};
diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c
index cd86315221..0386f5c775 100644
--- a/builtin/commit-graph.c
+++ b/builtin/commit-graph.c
@@ -9,26 +9,29 @@
#include "progress.h"
#include "tag.h"
-static char const * const builtin_commit_graph_usage[] = {
- N_("git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]"),
- N_("git commit-graph write [--object-dir <objdir>] [--append] "
- "[--split[=<strategy>]] [--reachable|--stdin-packs|--stdin-commits] "
- "[--changed-paths] [--[no-]max-new-filters <n>] [--[no-]progress] "
- "<split options>"),
+#define BUILTIN_COMMIT_GRAPH_VERIFY_USAGE \
+ N_("git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]")
+
+#define BUILTIN_COMMIT_GRAPH_WRITE_USAGE \
+ N_("git commit-graph write [--object-dir <objdir>] [--append] " \
+ "[--split[=<strategy>]] [--reachable|--stdin-packs|--stdin-commits] " \
+ "[--changed-paths] [--[no-]max-new-filters <n>] [--[no-]progress] " \
+ "<split options>")
+
+static const char * builtin_commit_graph_verify_usage[] = {
+ BUILTIN_COMMIT_GRAPH_VERIFY_USAGE,
NULL
};
-static const char * const builtin_commit_graph_verify_usage[] = {
- N_("git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]"),
+static const char * builtin_commit_graph_write_usage[] = {
+ BUILTIN_COMMIT_GRAPH_WRITE_USAGE,
NULL
};
-static const char * const builtin_commit_graph_write_usage[] = {
- N_("git commit-graph write [--object-dir <objdir>] [--append] "
- "[--split[=<strategy>]] [--reachable|--stdin-packs|--stdin-commits] "
- "[--changed-paths] [--[no-]max-new-filters <n>] [--[no-]progress] "
- "<split options>"),
- NULL
+static char const * const builtin_commit_graph_usage[] = {
+ BUILTIN_COMMIT_GRAPH_VERIFY_USAGE,
+ BUILTIN_COMMIT_GRAPH_WRITE_USAGE,
+ NULL,
};
static struct opts_commit_graph {
@@ -43,26 +46,18 @@ static struct opts_commit_graph {
int enable_changed_paths;
} opts;
-static struct object_directory *find_odb(struct repository *r,
- const char *obj_dir)
-{
- struct object_directory *odb;
- char *obj_dir_real = real_pathdup(obj_dir, 1);
- struct strbuf odb_path_real = STRBUF_INIT;
-
- prepare_alt_odb(r);
- for (odb = r->objects->odb; odb; odb = odb->next) {
- strbuf_realpath(&odb_path_real, odb->path, 1);
- if (!strcmp(obj_dir_real, odb_path_real.buf))
- break;
- }
-
- free(obj_dir_real);
- strbuf_release(&odb_path_real);
+static struct option common_opts[] = {
+ OPT_STRING(0, "object-dir", &opts.obj_dir,
+ N_("dir"),
+ N_("the object directory to store the graph")),
+ OPT_BOOL(0, "progress", &opts.progress,
+ N_("force progress reporting")),
+ OPT_END()
+};
- if (!odb)
- die(_("could not find object directory matching %s"), obj_dir);
- return odb;
+static struct option *add_common_options(struct option *to)
+{
+ return parse_options_concat(common_opts, to);
}
static int graph_verify(int argc, const char **argv)
@@ -76,21 +71,20 @@ static int graph_verify(int argc, const char **argv)
int flags = 0;
static struct option builtin_commit_graph_verify_options[] = {
- OPT_STRING(0, "object-dir", &opts.obj_dir,
- N_("dir"),
- N_("the object directory to store the graph")),
OPT_BOOL(0, "shallow", &opts.shallow,
N_("if the commit-graph is split, only verify the tip file")),
- OPT_BOOL(0, "progress", &opts.progress, N_("force progress reporting")),
OPT_END(),
};
+ struct option *options = add_common_options(builtin_commit_graph_verify_options);
trace2_cmd_mode("verify");
opts.progress = isatty(2);
argc = parse_options(argc, argv, NULL,
- builtin_commit_graph_verify_options,
+ options,
builtin_commit_graph_verify_usage, 0);
+ if (argc)
+ usage_with_options(builtin_commit_graph_verify_usage, options);
if (!opts.obj_dir)
opts.obj_dir = get_object_directory();
@@ -106,6 +100,7 @@ static int graph_verify(int argc, const char **argv)
die_errno(_("Could not open commit-graph '%s'"), graph_name);
FREE_AND_NULL(graph_name);
+ FREE_AND_NULL(options);
if (open_ok)
graph = load_commit_graph_one_fd_st(the_repository, fd, &st, odb);
@@ -206,9 +201,6 @@ static int graph_write(int argc, const char **argv)
struct progress *progress = NULL;
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, "reachable", &opts.reachable,
N_("start walk at all refs")),
OPT_BOOL(0, "stdin-packs", &opts.stdin_packs,
@@ -219,7 +211,6 @@ static int graph_write(int argc, const char **argv)
N_("include all commits already in the commit-graph file")),
OPT_BOOL(0, "changed-paths", &opts.enable_changed_paths,
N_("enable computation for changed paths")),
- OPT_BOOL(0, "progress", &opts.progress, N_("force progress reporting")),
OPT_CALLBACK_F(0, "split", &write_opts.split_flags, NULL,
N_("allow writing an incremental commit-graph file"),
PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
@@ -235,6 +226,7 @@ static int graph_write(int argc, const char **argv)
0, write_option_max_new_filters),
OPT_END(),
};
+ struct option *options = add_common_options(builtin_commit_graph_write_options);
opts.progress = isatty(2);
opts.enable_changed_paths = -1;
@@ -248,8 +240,10 @@ static int graph_write(int argc, const char **argv)
git_config(git_commit_graph_write_config, &opts);
argc = parse_options(argc, argv, NULL,
- builtin_commit_graph_write_options,
+ options,
builtin_commit_graph_write_usage, 0);
+ if (argc)
+ usage_with_options(builtin_commit_graph_write_usage, options);
if (opts.reachable + opts.stdin_packs + opts.stdin_commits > 1)
die(_("use at most one of --reachable, --stdin-commits, or --stdin-packs"));
@@ -304,6 +298,7 @@ static int graph_write(int argc, const char **argv)
result = 1;
cleanup:
+ FREE_AND_NULL(options);
string_list_clear(&pack_indexes, 0);
strbuf_release(&buf);
return result;
@@ -311,32 +306,25 @@ cleanup:
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);
+ struct option *builtin_commit_graph_options = common_opts;
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)
+ goto usage;
save_commit_buffer = 0;
- if (argc > 0) {
- if (!strcmp(argv[0], "verify"))
- return graph_verify(argc, argv);
- if (!strcmp(argv[0], "write"))
- return graph_write(argc, argv);
- }
+ if (!strcmp(argv[0], "verify"))
+ return graph_verify(argc, argv);
+ else if (argc && !strcmp(argv[0], "write"))
+ return graph_write(argc, argv);
+ error(_("unrecognized subcommand: %s"), argv[0]);
+usage:
usage_with_options(builtin_commit_graph_usage,
builtin_commit_graph_options);
}
diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c
index 1031b9a491..63ea322933 100644
--- a/builtin/commit-tree.c
+++ b/builtin/commit-tree.c
@@ -88,9 +88,7 @@ static int parse_file_arg_callback(const struct option *opt,
if (!strcmp(arg, "-"))
fd = 0;
else {
- fd = open(arg, O_RDONLY);
- if (fd < 0)
- die_errno(_("git commit-tree: failed to open '%s'"), arg);
+ fd = xopen(arg, O_RDONLY);
}
if (strbuf_read(buf, fd, 0) < 0)
die_errno(_("git commit-tree: failed to read '%s'"), arg);
diff --git a/builtin/commit.c b/builtin/commit.c
index 7c9b1e7be3..e7320f66f9 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -203,7 +203,7 @@ static void status_init_config(struct wt_status *s, config_fn_t fn)
init_diff_ui_defaults();
git_config(fn, s);
determine_whence(s);
- s->hints = advice_status_hints; /* must come after git_config() */
+ s->hints = advice_enabled(ADVICE_STATUS_HINTS); /* must come after git_config() */
}
static void rollback_index_files(void)
@@ -1033,7 +1033,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
*/
if (!committable && whence != FROM_MERGE && !allow_empty &&
!(amend && is_a_merge(current_head))) {
- s->hints = advice_status_hints;
+ s->hints = advice_enabled(ADVICE_STATUS_HINTS);
s->display_comment_prefix = old_display_comment_prefix;
run_status(stdout, index_file, prefix, 0, s);
if (amend)
diff --git a/builtin/diff-index.c b/builtin/diff-index.c
index cf09559e42..5fd23ab5b6 100644
--- a/builtin/diff-index.c
+++ b/builtin/diff-index.c
@@ -29,10 +29,10 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
prefix = precompose_argv_prefix(argc, argv, prefix);
/*
- * We need no diff for merges options, and we need to avoid conflict
- * with our own meaning of "-m".
+ * We need (some of) diff for merges options (e.g., --cc), and we need
+ * to avoid conflict with our own meaning of "-m".
*/
- diff_merges_suppress_options_parsing();
+ diff_merges_suppress_m_parsing();
argc = setup_revisions(argc, argv, &rev, NULL);
for (i = 1; i < argc; i++) {
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 3c20f164f0..95e8e89e81 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -821,6 +821,7 @@ static void handle_tag(const char *name, struct tag *tag)
static struct hashmap tags;
message = anonymize_str(&tags, anonymize_tag,
message, message_size, NULL);
+ message_size = strlen(message);
}
}
diff --git a/builtin/fetch.c b/builtin/fetch.c
index e064687dbd..75848d851d 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -712,7 +712,7 @@ static void adjust_refcol_width(const struct ref *ref)
int max, rlen, llen, len;
/* uptodate lines are only shown on high verbosity level */
- if (!verbosity && oideq(&ref->peer_ref->old_oid, &ref->old_oid))
+ if (verbosity <= 0 && oideq(&ref->peer_ref->old_oid, &ref->old_oid))
return;
max = term_columns();
@@ -748,6 +748,9 @@ static void prepare_format_display(struct ref *ref_map)
struct ref *rm;
const char *format = "full";
+ if (verbosity < 0)
+ return;
+
git_config_get_string_tmp("fetch.output", &format);
if (!strcasecmp(format, "full"))
compact_format = 0;
@@ -827,7 +830,12 @@ static void format_display(struct strbuf *display, char code,
const char *remote, const char *local,
int summary_width)
{
- int width = (summary_width + strlen(summary) - gettext_width(summary));
+ int width;
+
+ if (verbosity < 0)
+ return;
+
+ width = (summary_width + strlen(summary) - gettext_width(summary));
strbuf_addf(display, "%c %-*s ", code, width, summary);
if (!compact_format)
@@ -846,13 +854,11 @@ static int update_local_ref(struct ref *ref,
int summary_width)
{
struct commit *current = NULL, *updated;
- enum object_type type;
struct branch *current_branch = branch_get(NULL);
const char *pretty_ref = prettify_refname(ref->name);
int fast_forward = 0;
- type = oid_object_info(the_repository, &ref->new_oid, NULL);
- if (type < 0)
+ if (!repo_has_object_file(the_repository, &ref->new_oid))
die(_("object %s not found"), oid_to_hex(&ref->new_oid));
if (oideq(&ref->old_oid, &ref->new_oid)) {
@@ -964,7 +970,7 @@ static int update_local_ref(struct ref *ref,
}
}
-static int iterate_ref_map(void *cb_data, struct object_id *oid)
+static const struct object_id *iterate_ref_map(void *cb_data)
{
struct ref **rm = cb_data;
struct ref *ref = *rm;
@@ -972,10 +978,9 @@ static int iterate_ref_map(void *cb_data, struct object_id *oid)
while (ref && ref->status == REF_STATUS_REJECT_SHALLOW)
ref = ref->next;
if (!ref)
- return -1; /* end of the list */
+ return NULL;
*rm = ref->next;
- oidcpy(oid, &ref->old_oid);
- return 0;
+ return &ref->old_oid;
}
struct fetch_head {
@@ -1074,7 +1079,6 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
int connectivity_checked, struct ref *ref_map)
{
struct fetch_head fetch_head;
- struct commit *commit;
int url_len, i, rc = 0;
struct strbuf note = STRBUF_INIT, err = STRBUF_INIT;
struct ref_transaction *transaction = NULL;
@@ -1122,6 +1126,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
want_status <= FETCH_HEAD_IGNORE;
want_status++) {
for (rm = ref_map; rm; rm = rm->next) {
+ struct commit *commit = NULL;
struct ref *ref = NULL;
if (rm->status == REF_STATUS_REJECT_SHALLOW) {
@@ -1131,11 +1136,23 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
continue;
}
- commit = lookup_commit_reference_gently(the_repository,
- &rm->old_oid,
- 1);
- if (!commit)
- rm->fetch_head_status = FETCH_HEAD_NOT_FOR_MERGE;
+ /*
+ * References in "refs/tags/" are often going to point
+ * to annotated tags, which are not part of the
+ * commit-graph. We thus only try to look up refs in
+ * the graph which are not in that namespace to not
+ * regress performance in repositories with many
+ * annotated tags.
+ */
+ if (!starts_with(rm->name, "refs/tags/"))
+ commit = lookup_commit_in_graph(the_repository, &rm->old_oid);
+ if (!commit) {
+ commit = lookup_commit_reference_gently(the_repository,
+ &rm->old_oid,
+ 1);
+ if (!commit)
+ rm->fetch_head_status = FETCH_HEAD_NOT_FOR_MERGE;
+ }
if (rm->fetch_head_status != want_status)
continue;
@@ -1202,13 +1219,12 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
"FETCH_HEAD", summary_width);
}
if (note.len) {
- if (verbosity >= 0 && !shown_url) {
+ if (!shown_url) {
fprintf(stderr, _("From %.*s\n"),
url_len, url);
shown_url = 1;
}
- if (verbosity >= 0)
- fprintf(stderr, " %s\n", note.buf);
+ fprintf(stderr, " %s\n", note.buf);
}
}
}
@@ -1229,7 +1245,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
" 'git remote prune %s' to remove any old, conflicting "
"branches"), remote_name);
- if (advice_fetch_show_forced_updates) {
+ if (advice_enabled(ADVICE_FETCH_SHOW_FORCED_UPDATES)) {
if (!fetch_show_forced_updates) {
warning(_(warn_show_forced_updates));
} else if (forced_updates_ms > FORCED_UPDATES_DELAY_WARNING_IN_MS) {
@@ -1282,37 +1298,35 @@ static int check_exist_and_connected(struct ref *ref_map)
return check_connected(iterate_ref_map, &rm, &opt);
}
-static int fetch_refs(struct transport *transport, struct ref *ref_map)
+static int fetch_and_consume_refs(struct transport *transport, struct ref *ref_map)
{
- int ret = check_exist_and_connected(ref_map);
+ int connectivity_checked = 1;
+ int ret;
+
+ /*
+ * We don't need to perform a fetch in case we can already satisfy all
+ * refs.
+ */
+ ret = check_exist_and_connected(ref_map);
if (ret) {
trace2_region_enter("fetch", "fetch_refs", the_repository);
ret = transport_fetch_refs(transport, ref_map);
trace2_region_leave("fetch", "fetch_refs", the_repository);
+ if (ret)
+ goto out;
+ connectivity_checked = transport->smart_options ?
+ transport->smart_options->connectivity_checked : 0;
}
- if (!ret)
- /*
- * Keep the new pack's ".keep" file around to allow the caller
- * time to update refs to reference the new objects.
- */
- return 0;
- transport_unlock_pack(transport);
- return ret;
-}
-/* Update local refs based on the ref values fetched from a remote */
-static int consume_refs(struct transport *transport, struct ref *ref_map)
-{
- int connectivity_checked = transport->smart_options
- ? transport->smart_options->connectivity_checked : 0;
- int ret;
trace2_region_enter("fetch", "consume_refs", the_repository);
ret = store_updated_refs(transport->url,
transport->remote->name,
connectivity_checked,
ref_map);
- transport_unlock_pack(transport);
trace2_region_leave("fetch", "consume_refs", the_repository);
+
+out:
+ transport_unlock_pack(transport);
return ret;
}
@@ -1501,8 +1515,7 @@ static void backfill_tags(struct transport *transport, struct ref *ref_map)
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);
- if (!fetch_refs(transport, ref_map))
- consume_refs(transport, ref_map);
+ fetch_and_consume_refs(transport, ref_map);
if (gsecondary) {
transport_disconnect(gsecondary);
@@ -1593,7 +1606,7 @@ static int do_fetch(struct transport *transport,
transport->url);
}
}
- if (fetch_refs(transport, ref_map) || consume_refs(transport, ref_map)) {
+ if (fetch_and_consume_refs(transport, ref_map)) {
free_refs(ref_map);
retcode = 1;
goto cleanup;
diff --git a/builtin/gc.c b/builtin/gc.c
index 6ce5ca4512..43c36024cb 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -502,7 +502,7 @@ static int report_last_gc_error(void)
*/
warning(_("The last gc run reported the following. "
"Please correct the root cause\n"
- "and remove %s.\n"
+ "and remove %s\n"
"Automatic cleanup will not be performed "
"until the file is removed.\n\n"
"%s"),
@@ -1600,18 +1600,40 @@ static int launchctl_remove_plists(const char *cmd)
launchctl_remove_plist(SCHEDULE_WEEKLY, cmd);
}
+static int launchctl_list_contains_plist(const char *name, const char *cmd)
+{
+ int result;
+ struct child_process child = CHILD_PROCESS_INIT;
+ char *uid = launchctl_get_uid();
+
+ strvec_split(&child.args, cmd);
+ strvec_pushl(&child.args, "list", name, NULL);
+
+ child.no_stderr = 1;
+ child.no_stdout = 1;
+
+ if (start_command(&child))
+ die(_("failed to start launchctl"));
+
+ result = finish_command(&child);
+
+ free(uid);
+
+ /* Returns failure if 'name' doesn't exist. */
+ return !result;
+}
+
static int launchctl_schedule_plist(const char *exec_path, enum schedule_priority schedule, const char *cmd)
{
- FILE *plist;
- int i;
+ int i, fd;
const char *preamble, *repeat;
const char *frequency = get_frequency(schedule);
char *name = launchctl_service_name(frequency);
char *filename = launchctl_service_filename(name);
-
- if (safe_create_leading_directories(filename))
- die(_("failed to create directories for '%s'"), filename);
- plist = xfopen(filename, "w");
+ struct lock_file lk = LOCK_INIT;
+ static unsigned long lock_file_timeout_ms = ULONG_MAX;
+ struct strbuf plist = STRBUF_INIT, plist2 = STRBUF_INIT;
+ struct stat st;
preamble = "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
@@ -1630,7 +1652,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
"</array>\n"
"<key>StartCalendarInterval</key>\n"
"<array>\n";
- fprintf(plist, preamble, name, exec_path, exec_path, frequency);
+ strbuf_addf(&plist, preamble, name, exec_path, exec_path, frequency);
switch (schedule) {
case SCHEDULE_HOURLY:
@@ -1639,7 +1661,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
"<key>Minute</key><integer>0</integer>\n"
"</dict>\n";
for (i = 1; i <= 23; i++)
- fprintf(plist, repeat, i);
+ strbuf_addf(&plist, repeat, i);
break;
case SCHEDULE_DAILY:
@@ -1649,32 +1671,59 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
"<key>Minute</key><integer>0</integer>\n"
"</dict>\n";
for (i = 1; i <= 6; i++)
- fprintf(plist, repeat, i);
+ strbuf_addf(&plist, repeat, i);
break;
case SCHEDULE_WEEKLY:
- fprintf(plist,
- "<dict>\n"
- "<key>Day</key><integer>0</integer>\n"
- "<key>Hour</key><integer>0</integer>\n"
- "<key>Minute</key><integer>0</integer>\n"
- "</dict>\n");
+ strbuf_addstr(&plist,
+ "<dict>\n"
+ "<key>Day</key><integer>0</integer>\n"
+ "<key>Hour</key><integer>0</integer>\n"
+ "<key>Minute</key><integer>0</integer>\n"
+ "</dict>\n");
break;
default:
/* unreachable */
break;
}
- fprintf(plist, "</array>\n</dict>\n</plist>\n");
- fclose(plist);
+ strbuf_addstr(&plist, "</array>\n</dict>\n</plist>\n");
+
+ if (safe_create_leading_directories(filename))
+ die(_("failed to create directories for '%s'"), filename);
+
+ if ((long)lock_file_timeout_ms < 0 &&
+ git_config_get_ulong("gc.launchctlplistlocktimeoutms",
+ &lock_file_timeout_ms))
+ lock_file_timeout_ms = 150;
+
+ fd = hold_lock_file_for_update_timeout(&lk, filename, LOCK_DIE_ON_ERROR,
+ lock_file_timeout_ms);
- /* bootout might fail if not already running, so ignore */
- launchctl_boot_plist(0, filename, cmd);
- if (launchctl_boot_plist(1, filename, cmd))
- die(_("failed to bootstrap service %s"), filename);
+ /*
+ * Does this file already exist? With the intended contents? Is it
+ * registered already? Then it does not need to be re-registered.
+ */
+ if (!stat(filename, &st) && st.st_size == plist.len &&
+ strbuf_read_file(&plist2, filename, plist.len) == plist.len &&
+ !strbuf_cmp(&plist, &plist2) &&
+ launchctl_list_contains_plist(name, cmd))
+ rollback_lock_file(&lk);
+ else {
+ if (write_in_full(fd, plist.buf, plist.len) < 0 ||
+ commit_lock_file(&lk))
+ die_errno(_("could not write '%s'"), filename);
+
+ /* bootout might fail if not already running, so ignore */
+ launchctl_boot_plist(0, filename, cmd);
+ if (launchctl_boot_plist(1, filename, cmd))
+ die(_("failed to bootstrap service %s"), filename);
+ }
free(filename);
free(name);
+ strbuf_release(&plist);
+ strbuf_release(&plist2);
return 0;
}
diff --git a/builtin/grep.c b/builtin/grep.c
index 7d2f8e5adb..51278b01fa 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -65,6 +65,9 @@ static int todo_done;
/* Has all work items been added? */
static int all_work_added;
+static struct repository **repos_to_free;
+static size_t repos_to_free_nr, repos_to_free_alloc;
+
/* This lock protects all the variables above. */
static pthread_mutex_t grep_mutex;
@@ -168,6 +171,19 @@ static void work_done(struct work_item *w)
grep_unlock();
}
+static void free_repos(void)
+{
+ int i;
+
+ for (i = 0; i < repos_to_free_nr; i++) {
+ repo_clear(repos_to_free[i]);
+ free(repos_to_free[i]);
+ }
+ FREE_AND_NULL(repos_to_free);
+ repos_to_free_nr = 0;
+ repos_to_free_alloc = 0;
+}
+
static void *run(void *arg)
{
int hit = 0;
@@ -333,7 +349,7 @@ static int grep_oid(struct grep_opt *opt, const struct object_id *oid,
struct grep_source gs;
grep_source_name(opt, filename, tree_name_len, &pathbuf);
- grep_source_init(&gs, GREP_SOURCE_OID, pathbuf.buf, path, oid);
+ grep_source_init_oid(&gs, pathbuf.buf, path, oid, opt->repo);
strbuf_release(&pathbuf);
if (num_threads > 1) {
@@ -359,7 +375,7 @@ static int grep_file(struct grep_opt *opt, const char *filename)
struct grep_source gs;
grep_source_name(opt, filename, 0, &buf);
- grep_source_init(&gs, GREP_SOURCE_FILE, buf.buf, filename, filename);
+ grep_source_init_file(&gs, buf.buf, filename);
strbuf_release(&buf);
if (num_threads > 1) {
@@ -415,19 +431,24 @@ static int grep_submodule(struct grep_opt *opt,
const struct object_id *oid,
const char *filename, const char *path, int cached)
{
- struct repository subrepo;
+ struct repository *subrepo;
struct repository *superproject = opt->repo;
const struct submodule *sub;
struct grep_opt subopt;
- int hit;
+ int hit = 0;
sub = submodule_from_path(superproject, null_oid(), path);
if (!is_submodule_active(superproject, path))
return 0;
- if (repo_submodule_init(&subrepo, superproject, sub))
+ subrepo = xmalloc(sizeof(*subrepo));
+ if (repo_submodule_init(subrepo, superproject, sub)) {
+ free(subrepo);
return 0;
+ }
+ ALLOC_GROW(repos_to_free, repos_to_free_nr + 1, repos_to_free_alloc);
+ repos_to_free[repos_to_free_nr++] = subrepo;
/*
* NEEDSWORK: repo_read_gitmodules() might call
@@ -438,53 +459,49 @@ static int grep_submodule(struct grep_opt *opt,
* subrepo's odbs to the in-memory alternates list.
*/
obj_read_lock();
- repo_read_gitmodules(&subrepo, 0);
+ repo_read_gitmodules(subrepo, 0);
/*
- * NEEDSWORK: This adds the submodule's object directory to the list of
- * alternates for the single in-memory object store. This has some bad
- * consequences for memory (processed objects will never be freed) and
- * performance (this increases the number of pack files git has to pay
- * attention to, to the sum of the number of pack files in all the
- * repositories processed so far). This can be removed once the object
- * store is no longer global and instead is a member of the repository
- * object.
+ * All code paths tested by test code no longer need submodule ODBs to
+ * be added as alternates, but add it to the list just in case.
+ * Submodule ODBs added through add_submodule_odb_by_path() will be
+ * lazily registered as alternates when needed (and except in an
+ * unexpected code interaction, it won't be needed).
*/
- add_to_alternates_memory(subrepo.objects->odb->path);
+ add_submodule_odb_by_path(subrepo->objects->odb->path);
obj_read_unlock();
memcpy(&subopt, opt, sizeof(subopt));
- subopt.repo = &subrepo;
+ subopt.repo = subrepo;
if (oid) {
- struct object *object;
+ enum object_type object_type;
struct tree_desc tree;
void *data;
unsigned long size;
struct strbuf base = STRBUF_INIT;
obj_read_lock();
- object = parse_object_or_die(oid, NULL);
+ object_type = oid_object_info(subrepo, oid, NULL);
obj_read_unlock();
- data = read_object_with_reference(&subrepo,
- &object->oid, tree_type,
+ data = read_object_with_reference(subrepo,
+ oid, tree_type,
&size, NULL);
if (!data)
- die(_("unable to read tree (%s)"), oid_to_hex(&object->oid));
+ die(_("unable to read tree (%s)"), oid_to_hex(oid));
strbuf_addstr(&base, filename);
strbuf_addch(&base, '/');
init_tree_desc(&tree, data, size);
hit = grep_tree(&subopt, pathspec, &tree, &base, base.len,
- object->type == OBJ_COMMIT);
+ object_type == OBJ_COMMIT);
strbuf_release(&base);
free(data);
} else {
hit = grep_cache(&subopt, pathspec, cached);
}
- repo_clear(&subrepo);
return hit;
}
@@ -1182,5 +1199,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
run_pager(&opt, prefix);
clear_pathspec(&pathspec);
free_grep_patterns(&opt);
+ free_repos();
return !hit;
}
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index 640ef4ded5..c7b3ad74c6 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -53,9 +53,7 @@ static void hash_object(const char *path, const char *type, const char *vpath,
unsigned flags, int literally)
{
int fd;
- fd = open(path, O_RDONLY);
- if (fd < 0)
- die_errno("Cannot open '%s'", path);
+ fd = xopen(path, O_RDONLY);
hash_fd(fd, type, vpath, flags, literally);
}
@@ -117,7 +115,7 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
prefix = setup_git_directory_gently(&nongit);
if (vpath && prefix)
- vpath = xstrdup(prefix_filename(prefix, vpath));
+ vpath = prefix_filename(prefix, vpath);
git_config(git_default_config, NULL);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 8336466865..6cc4890217 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -338,15 +338,11 @@ static const char *open_pack_file(const char *pack_name)
"pack/tmp_pack_XXXXXX");
pack_name = strbuf_detach(&tmp_file, NULL);
} else {
- output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
- if (output_fd < 0)
- die_errno(_("unable to create '%s'"), pack_name);
+ output_fd = xopen(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
}
nothread_data.pack_fd = output_fd;
} else {
- input_fd = open(pack_name, O_RDONLY);
- if (input_fd < 0)
- die_errno(_("cannot open packfile '%s'"), pack_name);
+ input_fd = xopen(pack_name, O_RDONLY);
output_fd = -1;
nothread_data.pack_fd = input_fd;
}
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index 1794548c71..f4fd823af8 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -84,6 +84,8 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
PARSE_OPT_STOP_AT_NON_OPTION);
dest = argv[0];
+ packet_trace_identity("ls-remote");
+
UNLEAK(sorting);
if (argc > 1) {
diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c
index 664400b816..7baef30569 100644
--- a/builtin/mailsplit.c
+++ b/builtin/mailsplit.c
@@ -75,9 +75,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
fprintf(stderr, "corrupt mailbox\n");
exit(1);
}
- fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0666);
- if (fd < 0)
- die_errno("cannot open output file '%s'", name);
+ fd = xopen(name, O_WRONLY | O_CREAT | O_EXCL, 0666);
output = xfdopen(fd, "w");
/* Copy it out, while searching for a line that begins with
diff --git a/builtin/merge.c b/builtin/merge.c
index febb0c99c9..d2c52b6e97 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -1138,9 +1138,7 @@ static void handle_fetch_head(struct commit_list **remotes, struct strbuf *merge
merge_names = &fetch_head_file;
filename = git_path_fetch_head(the_repository);
- fd = open(filename, O_RDONLY);
- if (fd < 0)
- die_errno(_("could not open '%s' for reading"), filename);
+ fd = xopen(filename, O_RDONLY);
if (strbuf_read(merge_names, fd, 0) < 0)
die_errno(_("could not read '%s'"), filename);
@@ -1370,14 +1368,14 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
* There is no unmerged entry, don't advise 'git
* add/rm <file>', just 'git commit'.
*/
- if (advice_resolve_conflict)
+ if (advice_enabled(ADVICE_RESOLVE_CONFLICT))
die(_("You have not concluded your merge (MERGE_HEAD exists).\n"
"Please, commit your changes before you merge."));
else
die(_("You have not concluded your merge (MERGE_HEAD exists)."));
}
if (ref_exists("CHERRY_PICK_HEAD")) {
- if (advice_resolve_conflict)
+ if (advice_enabled(ADVICE_RESOLVE_CONFLICT))
die(_("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
"Please, commit your changes before you merge."));
else
diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c
index 8ff0dee2ec..66de6efd41 100644
--- a/builtin/multi-pack-index.c
+++ b/builtin/multi-pack-index.c
@@ -68,6 +68,8 @@ static int cmd_multi_pack_index_write(int argc, const char **argv)
OPT_STRING(0, "preferred-pack", &opts.preferred_pack,
N_("preferred-pack"),
N_("pack for reuse when computing a multi-pack bitmap")),
+ OPT_BIT(0, "bitmap", &opts.flags, N_("write multi-pack bitmap"),
+ MIDX_WRITE_BITMAP | MIDX_WRITE_REV_INDEX),
OPT_END(),
};
@@ -164,7 +166,7 @@ int cmd_multi_pack_index(int argc, const char **argv,
if (!opts.object_dir)
opts.object_dir = get_object_directory();
- if (argc == 0)
+ if (!argc)
goto usage;
if (!strcmp(argv[0], "repack"))
@@ -175,10 +177,9 @@ int cmd_multi_pack_index(int argc, const char **argv,
return cmd_multi_pack_index_verify(argc, argv);
else if (!strcmp(argv[0], "expire"))
return cmd_multi_pack_index_expire(argc, argv);
- else {
- error(_("unrecognized subcommand: %s"), argv[0]);
+
+ error(_("unrecognized subcommand: %s"), argv[0]);
usage:
- usage_with_options(builtin_multi_pack_index_usage,
- builtin_multi_pack_index_options);
- }
+ usage_with_options(builtin_multi_pack_index_usage,
+ builtin_multi_pack_index_options);
}
diff --git a/builtin/notes.c b/builtin/notes.c
index 74bba39ca8..71c59583a1 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -172,9 +172,7 @@ static void prepare_note_data(const struct object_id *object, struct note_data *
/* write the template message before editing: */
d->edit_path = git_pathdup("NOTES_EDITMSG");
- fd = open(d->edit_path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
- if (fd < 0)
- die_errno(_("could not create file '%s'"), d->edit_path);
+ fd = xopen(d->edit_path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (d->given)
write_or_die(fd, d->buf.buf, d->buf.len);
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index df49f656b9..e27f7cdb91 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1124,6 +1124,11 @@ static void write_reused_pack(struct hashfile *f)
break;
offset += ewah_bit_ctz64(word >> offset);
+ /*
+ * Can use bit positions directly, even for MIDX
+ * bitmaps. See comment in try_partial_reuse()
+ * for why.
+ */
write_reused_pack_one(pos + offset, f, &w_curs);
display_progress(progress_state, ++written);
}
@@ -1256,7 +1261,8 @@ static void write_pack_file(void)
bitmap_writer_show_progress(progress);
bitmap_writer_select_commits(indexed_commits, indexed_commits_nr, -1);
- bitmap_writer_build(&to_pack);
+ if (bitmap_writer_build(&to_pack) < 0)
+ die(_("failed to write bitmap index"));
bitmap_writer_finish(written_list, nr_written,
tmpname.buf, write_bitmap_options);
write_bitmap_index = 0;
@@ -3405,13 +3411,9 @@ static void read_object_list_from_stdin(void)
}
}
-/* Remember to update object flag allocation in object.h */
-#define OBJECT_ADDED (1u<<20)
-
static void show_commit(struct commit *commit, void *data)
{
add_object_entry(&commit->object.oid, OBJ_COMMIT, NULL, 0);
- commit->object.flags |= OBJECT_ADDED;
if (write_bitmap_index)
index_commit_for_bitmap(commit);
@@ -3424,7 +3426,6 @@ static void show_object(struct object *obj, const char *name, void *data)
{
add_preferred_base_object(name);
add_object_entry(&obj->oid, obj->type, name, 0);
- obj->flags |= OBJECT_ADDED;
if (use_delta_islands) {
const char *p;
@@ -3505,79 +3506,23 @@ static void show_edge(struct commit *commit)
add_preferred_base(&commit->object.oid);
}
-struct in_pack_object {
- off_t offset;
- struct object *object;
-};
-
-struct in_pack {
- unsigned int alloc;
- unsigned int nr;
- struct in_pack_object *array;
-};
-
-static void mark_in_pack_object(struct object *object, struct packed_git *p, struct in_pack *in_pack)
+static int add_object_in_unpacked_pack(const struct object_id *oid,
+ struct packed_git *pack,
+ uint32_t pos,
+ void *_data)
{
- in_pack->array[in_pack->nr].offset = find_pack_entry_one(object->oid.hash, p);
- in_pack->array[in_pack->nr].object = object;
- in_pack->nr++;
-}
-
-/*
- * Compare the objects in the offset order, in order to emulate the
- * "git rev-list --objects" output that produced the pack originally.
- */
-static int ofscmp(const void *a_, const void *b_)
-{
- struct in_pack_object *a = (struct in_pack_object *)a_;
- struct in_pack_object *b = (struct in_pack_object *)b_;
-
- if (a->offset < b->offset)
- return -1;
- else if (a->offset > b->offset)
- return 1;
- else
- return oidcmp(&a->object->oid, &b->object->oid);
+ add_object_entry(oid, OBJ_NONE, "", 0);
+ return 0;
}
static void add_objects_in_unpacked_packs(void)
{
- struct packed_git *p;
- struct in_pack in_pack;
- uint32_t i;
-
- memset(&in_pack, 0, sizeof(in_pack));
-
- for (p = get_all_packs(the_repository); p; p = p->next) {
- struct object_id oid;
- struct object *o;
-
- if (!p->pack_local || p->pack_keep || p->pack_keep_in_core)
- continue;
- if (open_pack_index(p))
- die(_("cannot open pack index"));
-
- ALLOC_GROW(in_pack.array,
- in_pack.nr + p->num_objects,
- in_pack.alloc);
-
- for (i = 0; i < p->num_objects; i++) {
- nth_packed_object_id(&oid, p, i);
- o = lookup_unknown_object(the_repository, &oid);
- if (!(o->flags & OBJECT_ADDED))
- mark_in_pack_object(o, p, &in_pack);
- o->flags |= OBJECT_ADDED;
- }
- }
-
- if (in_pack.nr) {
- QSORT(in_pack.array, in_pack.nr, ofscmp);
- for (i = 0; i < in_pack.nr; i++) {
- struct object *o = in_pack.array[i].object;
- add_object_entry(&o->oid, o->type, "", 0);
- }
- }
- free(in_pack.array);
+ if (for_each_packed_object(add_object_in_unpacked_pack, NULL,
+ FOR_EACH_OBJECT_PACK_ORDER |
+ FOR_EACH_OBJECT_LOCAL_ONLY |
+ FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS |
+ FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS))
+ die(_("cannot open pack index"));
}
static int add_loose_object(const struct object_id *oid, const char *path,
diff --git a/builtin/push.c b/builtin/push.c
index e8b10a9b7e..4b026ce6c6 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -289,42 +289,42 @@ static const char message_advice_ref_needs_update[] =
static void advise_pull_before_push(void)
{
- if (!advice_push_non_ff_current || !advice_push_update_rejected)
+ if (!advice_enabled(ADVICE_PUSH_NON_FF_CURRENT) || !advice_enabled(ADVICE_PUSH_UPDATE_REJECTED))
return;
advise(_(message_advice_pull_before_push));
}
static void advise_checkout_pull_push(void)
{
- if (!advice_push_non_ff_matching || !advice_push_update_rejected)
+ if (!advice_enabled(ADVICE_PUSH_NON_FF_MATCHING) || !advice_enabled(ADVICE_PUSH_UPDATE_REJECTED))
return;
advise(_(message_advice_checkout_pull_push));
}
static void advise_ref_already_exists(void)
{
- if (!advice_push_already_exists || !advice_push_update_rejected)
+ if (!advice_enabled(ADVICE_PUSH_ALREADY_EXISTS) || !advice_enabled(ADVICE_PUSH_UPDATE_REJECTED))
return;
advise(_(message_advice_ref_already_exists));
}
static void advise_ref_fetch_first(void)
{
- if (!advice_push_fetch_first || !advice_push_update_rejected)
+ if (!advice_enabled(ADVICE_PUSH_FETCH_FIRST) || !advice_enabled(ADVICE_PUSH_UPDATE_REJECTED))
return;
advise(_(message_advice_ref_fetch_first));
}
static void advise_ref_needs_force(void)
{
- if (!advice_push_needs_force || !advice_push_update_rejected)
+ if (!advice_enabled(ADVICE_PUSH_NEEDS_FORCE) || !advice_enabled(ADVICE_PUSH_UPDATE_REJECTED))
return;
advise(_(message_advice_ref_needs_force));
}
static void advise_ref_needs_update(void)
{
- if (!advice_push_ref_needs_update || !advice_push_update_rejected)
+ if (!advice_enabled(ADVICE_PUSH_REF_NEEDS_UPDATE) || !advice_enabled(ADVICE_PUSH_UPDATE_REJECTED))
return;
advise(_(message_advice_ref_needs_update));
}
diff --git a/builtin/rebase.c b/builtin/rebase.c
index c284a7ace1..eb01f4d790 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -405,6 +405,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,
flags |= opts->root_with_onto ? TODO_LIST_ROOT_WITH_ONTO : 0;
flags |= command == ACTION_SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;
flags |= opts->reapply_cherry_picks ? TODO_LIST_REAPPLY_CHERRY_PICKS : 0;
+ flags |= opts->flags & REBASE_NO_QUIET ? TODO_LIST_WARN_SKIPPED_CHERRY_PICKS : 0;
switch (command) {
case ACTION_NONE: {
@@ -1918,7 +1919,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
&options.orig_head))
options.head_name = NULL;
else
- die(_("fatal: no such branch/commit '%s'"),
+ die(_("no such branch/commit '%s'"),
branch_name);
} else if (argc == 0) {
/* Do not need to switch branches, we are already on it. */
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 2d1f97e1ca..041e915454 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1306,7 +1306,7 @@ static void refuse_unconfigured_deny_delete_current(void)
rp_error("%s", _(refuse_unconfigured_deny_delete_current_msg));
}
-static int command_singleton_iterator(void *cb_data, struct object_id *oid);
+static const struct object_id *command_singleton_iterator(void *cb_data);
static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
{
struct shallow_lock shallow_lock = SHALLOW_LOCK_INIT;
@@ -1731,16 +1731,15 @@ static void check_aliased_updates(struct command *commands)
string_list_clear(&ref_list, 0);
}
-static int command_singleton_iterator(void *cb_data, struct object_id *oid)
+static const struct object_id *command_singleton_iterator(void *cb_data)
{
struct command **cmd_list = cb_data;
struct command *cmd = *cmd_list;
if (!cmd || is_null_oid(&cmd->new_oid))
- return -1; /* end of list */
+ return NULL;
*cmd_list = NULL; /* this returns only one */
- oidcpy(oid, &cmd->new_oid);
- return 0;
+ return &cmd->new_oid;
}
static void set_connectivity_errors(struct command *commands,
@@ -1770,7 +1769,7 @@ struct iterate_data {
struct shallow_info *si;
};
-static int iterate_receive_command_list(void *cb_data, struct object_id *oid)
+static const struct object_id *iterate_receive_command_list(void *cb_data)
{
struct iterate_data *data = cb_data;
struct command **cmd_list = &data->cmds;
@@ -1781,13 +1780,11 @@ static int iterate_receive_command_list(void *cb_data, struct object_id *oid)
/* to be checked in update_shallow_ref() */
continue;
if (!is_null_oid(&cmd->new_oid) && !cmd->skip_update) {
- oidcpy(oid, &cmd->new_oid);
*cmd_list = cmd->next;
- return 0;
+ return &cmd->new_oid;
}
}
- *cmd_list = NULL;
- return -1; /* end of list */
+ return NULL;
}
static void reject_updates_to_hidden(struct command *commands)
diff --git a/builtin/repack.c b/builtin/repack.c
index 5f9bc74adc..82ab668272 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -515,6 +515,10 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
if (!(pack_everything & ALL_INTO_ONE) ||
!is_bare_repository())
write_bitmaps = 0;
+ } else if (write_bitmaps &&
+ git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0) &&
+ git_env_bool(GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP, 0)) {
+ write_bitmaps = 0;
}
if (pack_kept_objects < 0)
pack_kept_objects = write_bitmaps > 0;
@@ -725,8 +729,12 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
update_server_info(0);
remove_temporary_files();
- if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0))
- write_midx_file(get_object_directory(), NULL, 0);
+ if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0)) {
+ unsigned flags = 0;
+ if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP, 0))
+ flags |= MIDX_WRITE_BITMAP | MIDX_WRITE_REV_INDEX;
+ write_midx_file(get_object_directory(), NULL, flags);
+ }
string_list_clear(&names, 0);
string_list_clear(&rollback, 0);
diff --git a/builtin/replace.c b/builtin/replace.c
index cd48765911..946938d011 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -507,7 +507,7 @@ static int convert_graft_file(int force)
if (!fp)
return -1;
- advice_graft_file_deprecated = 0;
+ no_graft_file_deprecated_advice = 1;
while (strbuf_getline(&buf, fp) != EOF) {
if (*buf.buf == '#')
continue;
diff --git a/builtin/reset.c b/builtin/reset.c
index 43e855cb88..51c9e2f43f 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -412,7 +412,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
refresh_index(&the_index, flags, NULL, NULL,
_("Unstaged changes after reset:"));
t_delta_in_ms = (getnanotime() - t_begin) / 1000000;
- if (advice_reset_quiet_warning && t_delta_in_ms > REFRESH_INDEX_DELAY_WARNING_IN_MS) {
+ if (advice_enabled(ADVICE_RESET_QUIET_WARNING) && t_delta_in_ms > REFRESH_INDEX_DELAY_WARNING_IN_MS) {
printf(_("\nIt took %.2f seconds to enumerate unstaged changes after reset. You can\n"
"use '--quiet' to avoid this. Set the config setting reset.quiet to true\n"
"to make this the default.\n"), t_delta_in_ms / 1000.0);
diff --git a/builtin/rm.c b/builtin/rm.c
index 8a24c715e0..3b44b807e5 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -55,7 +55,7 @@ static void print_error_files(struct string_list *files_list,
strbuf_addf(&err_msg,
"\n %s",
files_list->items[i].string);
- if (advice_rm_hints)
+ if (advice_enabled(ADVICE_RM_HINTS))
strbuf_addstr(&err_msg, hints_msg);
*errs = error("%s", err_msg.buf);
strbuf_release(&err_msg);
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index d77ce7aeb3..bea4bbf468 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -482,10 +482,9 @@ static void snarf_refs(int head, int remotes)
}
}
-static int rev_is_head(const char *head, const char *name,
- unsigned char *head_sha1, unsigned char *sha1)
+static int rev_is_head(const char *head, const char *name)
{
- if (!head || (head_sha1 && sha1 && !hasheq(head_sha1, sha1)))
+ if (!head)
return 0;
skip_prefix(head, "refs/heads/", &head);
if (!skip_prefix(name, "refs/heads/", &name))
@@ -806,9 +805,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
/* We are only interested in adding the branch
* HEAD points at.
*/
- if (rev_is_head(head,
- ref_name[i],
- head_oid.hash, NULL))
+ if (rev_is_head(head, ref_name[i]))
has_head++;
}
if (!has_head) {
@@ -867,10 +864,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
if (1 < num_rev || extra < 0) {
for (i = 0; i < num_rev; i++) {
int j;
- int is_head = rev_is_head(head,
- ref_name[i],
- head_oid.hash,
- rev[i]->object.oid.hash);
+ int is_head = rev_is_head(head, ref_name[i]) &&
+ oideq(&head_oid, &rev[i]->object.oid);
if (extra < 0)
printf("%c [%s] ",
is_head ? '*' : ' ', ref_name[i]);
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index ef2776a9e4..4da9781b99 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1724,7 +1724,7 @@ static int add_possible_reference_from_superproject(
} else {
switch (sas->error_mode) {
case SUBMODULE_ALTERNATE_ERROR_DIE:
- if (advice_submodule_alternate_error_strategy_die)
+ if (advice_enabled(ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE))
advise(_(alternate_error_advice));
die(_("submodule '%s' cannot add alternate: %s"),
sas->submodule_name, err.buf);
diff --git a/builtin/tag.c b/builtin/tag.c
index 452558ec95..065b6bf093 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -293,9 +293,7 @@ static void create_tag(const struct object_id *object, const char *object_ref,
/* write the template message before editing: */
path = git_pathdup("TAG_EDITMSG");
- fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
- if (fd < 0)
- die_errno(_("could not create file '%s'"), path);
+ fd = xopen(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (opt->message_given) {
write_or_die(fd, buf->buf, buf->len);
diff --git a/builtin/update-index.c b/builtin/update-index.c
index f1f16f2de5..187203e8bb 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -95,9 +95,7 @@ static int create_file(const char *path)
{
int fd;
path = get_mtime_path(path);
- fd = open(path, O_CREAT | O_RDWR, 0644);
- if (fd < 0)
- die_errno(_("failed to create file %s"), path);
+ fd = xopen(path, O_CREAT | O_RDWR, 0644);
return fd;
}