summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/add.c10
-rw-r--r--builtin/am.c4
-rw-r--r--builtin/backfill.c2
-rw-r--r--builtin/branch.c2
-rw-r--r--builtin/cat-file.c3
-rw-r--r--builtin/clean.c2
-rw-r--r--builtin/commit-graph.c4
-rw-r--r--builtin/commit.c11
-rw-r--r--builtin/config.c45
-rw-r--r--builtin/count-objects.c3
-rw-r--r--builtin/describe.c37
-rw-r--r--builtin/fast-export.c19
-rw-r--r--builtin/fast-import.c73
-rw-r--r--builtin/fetch.c21
-rw-r--r--builtin/fsck.c11
-rw-r--r--builtin/gc.c14
-rw-r--r--builtin/grep.c4
-rw-r--r--builtin/index-pack.c10
-rw-r--r--builtin/last-modified.c327
-rw-r--r--builtin/log.c9
-rw-r--r--builtin/ls-files.c13
-rw-r--r--builtin/ls-tree.c7
-rw-r--r--builtin/merge.c3
-rw-r--r--builtin/multi-pack-index.c31
-rw-r--r--builtin/pack-objects.c46
-rw-r--r--builtin/pack-redundant.c8
-rw-r--r--builtin/pack-refs.c54
-rw-r--r--builtin/push.c2
-rw-r--r--builtin/range-diff.c24
-rw-r--r--builtin/rebase.c6
-rw-r--r--builtin/receive-pack.c2
-rw-r--r--builtin/reflog.c2
-rw-r--r--builtin/refs.c65
-rw-r--r--builtin/repack.c18
-rw-r--r--builtin/repo.c45
-rw-r--r--builtin/rev-parse.c7
-rw-r--r--builtin/revert.c7
-rw-r--r--builtin/show-branch.c2
-rw-r--r--builtin/stash.c40
-rw-r--r--builtin/submodule--helper.c10
-rw-r--r--builtin/unpack-objects.c6
-rw-r--r--builtin/update-index.c30
42 files changed, 788 insertions, 251 deletions
diff --git a/builtin/add.c b/builtin/add.c
index 0235854f80..32709794b3 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -14,13 +14,14 @@
#include "gettext.h"
#include "pathspec.h"
#include "run-command.h"
+#include "object-file.h"
+#include "odb.h"
#include "parse-options.h"
#include "path.h"
#include "preload-index.h"
#include "diff.h"
#include "read-cache.h"
#include "revision.h"
-#include "bulk-checkin.h"
#include "strvec.h"
#include "submodule.h"
#include "add-interactive.h"
@@ -200,7 +201,7 @@ static int edit_patch(struct repository *repo,
argc = setup_revisions(argc, argv, &rev, NULL);
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
- rev.diffopt.use_color = 0;
+ rev.diffopt.use_color = GIT_COLOR_NEVER;
rev.diffopt.flags.ignore_dirty_submodules = 1;
out = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
rev.diffopt.file = xfdopen(out, "w");
@@ -389,6 +390,7 @@ int cmd_add(int argc,
char *seen = NULL;
char *ps_matched = NULL;
struct lock_file lock_file = LOCK_INIT;
+ struct odb_transaction *transaction;
repo_config(repo, add_config, NULL);
@@ -574,7 +576,7 @@ int cmd_add(int argc,
string_list_clear(&only_match_skip_worktree, 0);
}
- begin_odb_transaction();
+ transaction = odb_transaction_begin(repo->objects);
ps_matched = xcalloc(pathspec.nr, 1);
if (add_renormalize)
@@ -593,7 +595,7 @@ int cmd_add(int argc,
if (chmod_arg && pathspec.nr)
exit_status |= chmod_pathspec(repo, &pathspec, chmod_arg[0], show_only);
- end_odb_transaction();
+ odb_transaction_commit(transaction);
finish:
if (write_locked_index(repo->index, &lock_file,
diff --git a/builtin/am.c b/builtin/am.c
index 6073d64ae9..277c2e7937 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -1408,7 +1408,7 @@ static void write_commit_patch(const struct am_state *state, struct commit *comm
rev_info.no_commit_id = 1;
rev_info.diffopt.flags.binary = 1;
rev_info.diffopt.flags.full_index = 1;
- rev_info.diffopt.use_color = 0;
+ rev_info.diffopt.use_color = GIT_COLOR_NEVER;
rev_info.diffopt.file = fp;
rev_info.diffopt.close_file = 1;
add_pending_object(&rev_info, &commit->object, "");
@@ -1441,7 +1441,7 @@ static void write_index_patch(const struct am_state *state)
rev_info.disable_stdin = 1;
rev_info.no_commit_id = 1;
rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;
- rev_info.diffopt.use_color = 0;
+ rev_info.diffopt.use_color = GIT_COLOR_NEVER;
rev_info.diffopt.file = fp;
rev_info.diffopt.close_file = 1;
add_pending_object(&rev_info, &tree->object, "");
diff --git a/builtin/backfill.c b/builtin/backfill.c
index 80056abe47..e80fc1b694 100644
--- a/builtin/backfill.c
+++ b/builtin/backfill.c
@@ -53,7 +53,7 @@ static void download_batch(struct backfill_context *ctx)
* We likely have a new packfile. Add it to the packed list to
* avoid possible duplicate downloads of the same objects.
*/
- reprepare_packed_git(ctx->repo);
+ odb_reprepare(ctx->repo->objects);
}
static int fill_missing_blobs(const char *path UNUSED,
diff --git a/builtin/branch.c b/builtin/branch.c
index fa5ced452e..9fcf04bebb 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -46,7 +46,7 @@ static struct object_id head_oid;
static int recurse_submodules = 0;
static int submodule_propagate_branches = 0;
-static int branch_use_color = -1;
+static enum git_colorbool branch_use_color = GIT_COLOR_UNKNOWN;
static char branch_colors[][COLOR_MAXLEN] = {
GIT_COLOR_RESET,
GIT_COLOR_NORMAL, /* PLAIN */
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index fce0b06451..ee6715fa52 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -852,9 +852,10 @@ static void batch_each_object(struct batch_options *opt,
if (bitmap && !for_each_bitmapped_object(bitmap, &opt->objects_filter,
batch_one_object_bitmapped, &payload)) {
+ struct packfile_store *packs = the_repository->objects->packfiles;
struct packed_git *pack;
- for (pack = get_all_packs(the_repository); pack; pack = pack->next) {
+ for (pack = packfile_store_get_all_packs(packs); pack; pack = pack->next) {
if (bitmap_index_contains_pack(bitmap, pack) ||
open_pack_index(pack))
continue;
diff --git a/builtin/clean.c b/builtin/clean.c
index 38b67923a6..1d5e7e5366 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -64,7 +64,7 @@ static const char *color_interactive_slots[] = {
[CLEAN_COLOR_RESET] = "reset",
};
-static int clean_use_color = -1;
+static enum git_colorbool clean_use_color = GIT_COLOR_UNKNOWN;
static char clean_colors[][COLOR_MAXLEN] = {
[CLEAN_COLOR_ERROR] = GIT_COLOR_BOLD_RED,
[CLEAN_COLOR_HEADER] = GIT_COLOR_BOLD,
diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c
index 6656187f90..fe3ebaadad 100644
--- a/builtin/commit-graph.c
+++ b/builtin/commit-graph.c
@@ -102,7 +102,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix,
if (opts.progress)
flags |= COMMIT_GRAPH_WRITE_PROGRESS;
- source = odb_find_source(the_repository->objects, opts.obj_dir);
+ source = odb_find_source_or_die(the_repository->objects, opts.obj_dir);
graph_name = get_commit_graph_filename(source);
chain_name = get_commit_graph_chain_filename(source);
if (open_commit_graph(graph_name, &fd, &st))
@@ -291,7 +291,7 @@ static int graph_write(int argc, const char **argv, const char *prefix,
git_env_bool(GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS, 0))
flags |= COMMIT_GRAPH_WRITE_BLOOM_FILTERS;
- source = odb_find_source(the_repository->objects, opts.obj_dir);
+ source = odb_find_source_or_die(the_repository->objects, opts.obj_dir);
if (opts.reachable) {
if (write_commit_graph_reachable(source, flags, &write_opts))
diff --git a/builtin/commit.c b/builtin/commit.c
index 8a5dee384d..0243f17d53 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -695,6 +695,7 @@ static int author_date_is_interesting(void)
return author_message || force_date;
}
+#ifndef WITH_BREAKING_CHANGES
static void adjust_comment_line_char(const struct strbuf *sb)
{
char candidates[] = "#;@!$%^&|:";
@@ -732,6 +733,7 @@ static void adjust_comment_line_char(const struct strbuf *sb)
free(comment_line_str_to_free);
comment_line_str = comment_line_str_to_free = xstrfmt("%c", *p);
}
+#endif /* !WITH_BREAKING_CHANGES */
static void prepare_amend_commit(struct commit *commit, struct strbuf *sb,
struct pretty_print_context *ctx)
@@ -928,15 +930,17 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len)
die_errno(_("could not write commit template"));
+#ifndef WITH_BREAKING_CHANGES
if (auto_comment_line_char)
adjust_comment_line_char(&sb);
+#endif /* !WITH_BREAKING_CHANGES */
strbuf_release(&sb);
/* This checks if committer ident is explicitly given */
strbuf_addstr(&committer_ident, git_committer_info(IDENT_STRICT));
if (use_editor && include_status) {
int ident_shown = 0;
- int saved_color_setting;
+ enum git_colorbool saved_color_setting;
struct ident_split ci, ai;
const char *hint_cleanup_all = allow_empty_message ?
_("Please enter the commit message for your changes."
@@ -1016,7 +1020,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
status_printf_ln(s, GIT_COLOR_NORMAL, "%s", ""); /* Add new line for clarity */
saved_color_setting = s->use_color;
- s->use_color = 0;
+ s->use_color = GIT_COLOR_NEVER;
committable = run_status(s->fp, index_file, prefix, 1, s);
s->use_color = saved_color_setting;
string_list_clear_func(&s->change, change_data_free);
@@ -1793,6 +1797,9 @@ int cmd_commit(int argc,
show_usage_with_options_if_asked(argc, argv,
builtin_commit_usage, builtin_commit_options);
+#ifndef WITH_BREAKING_CHANGES
+ warn_on_auto_comment_char = true;
+#endif /* !WITH_BREAKING_CHANGES */
prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;
diff --git a/builtin/config.c b/builtin/config.c
index 59fb113b07..75852bd79d 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -547,30 +547,37 @@ static int git_get_color_config(const char *var, const char *value,
return 0;
}
-static void get_color(const struct config_location_options *opts,
+static int get_color(const struct config_location_options *opts,
const char *var, const char *def_color)
{
struct get_color_config_data data = {
.get_color_slot = var,
.parsed_color[0] = '\0',
};
+ int ret;
config_with_options(git_get_color_config, &data,
&opts->source, the_repository,
&opts->options);
if (!data.get_color_found && def_color) {
- if (color_parse(def_color, data.parsed_color) < 0)
- die(_("unable to parse default color value"));
+ if (color_parse(def_color, data.parsed_color) < 0) {
+ ret = error(_("unable to parse default color value"));
+ goto out;
+ }
}
+ ret = 0;
+
+out:
fputs(data.parsed_color, stdout);
+ return ret;
}
struct get_colorbool_config_data {
- int get_colorbool_found;
- int get_diff_color_found;
- int get_color_ui_found;
+ enum git_colorbool get_colorbool_found;
+ enum git_colorbool get_diff_color_found;
+ enum git_colorbool get_color_ui_found;
const char *get_colorbool_slot;
};
@@ -594,33 +601,34 @@ static int get_colorbool(const struct config_location_options *opts,
{
struct get_colorbool_config_data data = {
.get_colorbool_slot = var,
- .get_colorbool_found = -1,
- .get_diff_color_found = -1,
- .get_color_ui_found = -1,
+ .get_colorbool_found = GIT_COLOR_UNKNOWN,
+ .get_diff_color_found = GIT_COLOR_UNKNOWN,
+ .get_color_ui_found = GIT_COLOR_UNKNOWN,
};
+ bool result;
config_with_options(git_get_colorbool_config, &data,
&opts->source, the_repository,
&opts->options);
- if (data.get_colorbool_found < 0) {
+ if (data.get_colorbool_found == GIT_COLOR_UNKNOWN) {
if (!strcmp(data.get_colorbool_slot, "color.diff"))
data.get_colorbool_found = data.get_diff_color_found;
- if (data.get_colorbool_found < 0)
+ if (data.get_colorbool_found == GIT_COLOR_UNKNOWN)
data.get_colorbool_found = data.get_color_ui_found;
}
- if (data.get_colorbool_found < 0)
+ if (data.get_colorbool_found == GIT_COLOR_UNKNOWN)
/* default value if none found in config */
data.get_colorbool_found = GIT_COLOR_AUTO;
- data.get_colorbool_found = want_color(data.get_colorbool_found);
+ result = want_color(data.get_colorbool_found);
if (print) {
- printf("%s\n", data.get_colorbool_found ? "true" : "false");
+ printf("%s\n", result ? "true" : "false");
return 0;
} else
- return data.get_colorbool_found ? 0 : 1;
+ return result ? 0 : 1;
}
static void check_write(const struct git_config_source *source)
@@ -912,10 +920,13 @@ static int cmd_config_get(int argc, const char **argv, const char *prefix,
location_options_init(&location_opts, prefix);
display_options_init(&display_opts);
- setup_auto_pager("config", 1);
+ if (display_opts.type != TYPE_COLOR)
+ setup_auto_pager("config", 1);
if (url)
ret = get_urlmatch(&location_opts, &display_opts, argv[0], url);
+ else if (display_opts.type == TYPE_COLOR && !strlen(argv[0]) && display_opts.default_value)
+ ret = get_color(&location_opts, "", display_opts.default_value);
else
ret = get_value(&location_opts, &display_opts, argv[0], value_pattern,
get_value_flags, flags);
@@ -1390,7 +1401,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
}
else if (actions == ACTION_GET_COLOR) {
check_argc(argc, 1, 2);
- get_color(&location_opts, argv[0], argv[1]);
+ ret = get_color(&location_opts, argv[0], argv[1]);
}
else if (actions == ACTION_GET_COLORBOOL) {
check_argc(argc, 1, 2);
diff --git a/builtin/count-objects.c b/builtin/count-objects.c
index a61d3b46aa..f2f407c2a7 100644
--- a/builtin/count-objects.c
+++ b/builtin/count-objects.c
@@ -122,6 +122,7 @@ int cmd_count_objects(int argc,
count_loose, count_cruft, NULL, NULL);
if (verbose) {
+ struct packfile_store *packs = the_repository->objects->packfiles;
struct packed_git *p;
unsigned long num_pack = 0;
off_t size_pack = 0;
@@ -129,7 +130,7 @@ int cmd_count_objects(int argc,
struct strbuf pack_buf = STRBUF_INIT;
struct strbuf garbage_buf = STRBUF_INIT;
- for (p = get_all_packs(the_repository); p; p = p->next) {
+ for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
if (!p->pack_local)
continue;
if (open_pack_index(p))
diff --git a/builtin/describe.c b/builtin/describe.c
index fbe78ace66..ffaf8d9f0a 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -24,6 +24,7 @@
#include "commit-slab.h"
#include "wildmatch.h"
#include "prio-queue.h"
+#include "oidset.h"
#define MAX_TAGS (FLAG_BITS - 1)
#define DEFAULT_CANDIDATES 10
@@ -286,38 +287,47 @@ static void lazy_queue_clear(struct lazy_queue *queue)
queue->get_pending = false;
}
-static bool all_have_flag(const struct lazy_queue *queue, unsigned flag)
+static unsigned long finish_depth_computation(struct lazy_queue *queue,
+ struct possible_tag *best)
{
+ unsigned long seen_commits = 0;
+ struct oidset unflagged = OIDSET_INIT;
+
for (size_t i = queue->get_pending ? 1 : 0; i < queue->queue.nr; i++) {
struct commit *commit = queue->queue.array[i].data;
- if (!(commit->object.flags & flag))
- return false;
+ if (!(commit->object.flags & best->flag_within))
+ oidset_insert(&unflagged, &commit->object.oid);
}
- return true;
-}
-static unsigned long finish_depth_computation(struct lazy_queue *queue,
- struct possible_tag *best)
-{
- unsigned long seen_commits = 0;
while (!lazy_queue_empty(queue)) {
struct commit *c = lazy_queue_get(queue);
struct commit_list *parents = c->parents;
seen_commits++;
if (c->object.flags & best->flag_within) {
- if (all_have_flag(queue, best->flag_within))
+ if (!oidset_size(&unflagged))
break;
- } else
+ } else {
+ oidset_remove(&unflagged, &c->object.oid);
best->depth++;
+ }
while (parents) {
+ unsigned seen, flag_before, flag_after;
struct commit *p = parents->item;
repo_parse_commit(the_repository, p);
- if (!(p->object.flags & SEEN))
+ seen = p->object.flags & SEEN;
+ if (!seen)
lazy_queue_put(queue, p);
+ flag_before = p->object.flags & best->flag_within;
p->object.flags |= c->object.flags;
+ flag_after = p->object.flags & best->flag_within;
+ if (!seen && !flag_after)
+ oidset_insert(&unflagged, &p->object.oid);
+ if (seen && !flag_before && flag_after)
+ oidset_remove(&unflagged, &p->object.oid);
parents = parents->next;
}
}
+ oidset_clear(&unflagged);
return seen_commits;
}
@@ -570,7 +580,8 @@ static void describe_blob(const struct object_id *oid, struct strbuf *dst)
NULL);
repo_init_revisions(the_repository, &revs, NULL);
- if (setup_revisions(args.nr, args.v, &revs, NULL) > 1)
+ setup_revisions_from_strvec(&args, &revs, NULL);
+ if (args.nr > 1)
BUG("setup_revisions could not handle all args?");
if (prepare_revision_walk(&revs))
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index c06ee0b213..dc2486f9a8 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -37,8 +37,6 @@ static const char *const fast_export_usage[] = {
NULL
};
-enum sign_mode { SIGN_ABORT, SIGN_VERBATIM, SIGN_STRIP, SIGN_WARN_VERBATIM, SIGN_WARN_STRIP };
-
static int progress;
static enum sign_mode signed_tag_mode = SIGN_ABORT;
static enum sign_mode signed_commit_mode = SIGN_STRIP;
@@ -59,23 +57,16 @@ static struct hashmap anonymized_seeds;
static struct revision_sources revision_sources;
static int parse_opt_sign_mode(const struct option *opt,
- const char *arg, int unset)
+ const char *arg, int unset)
{
enum sign_mode *val = opt->value;
+
if (unset)
return 0;
- else if (!strcmp(arg, "abort"))
- *val = SIGN_ABORT;
- else if (!strcmp(arg, "verbatim") || !strcmp(arg, "ignore"))
- *val = SIGN_VERBATIM;
- else if (!strcmp(arg, "warn-verbatim") || !strcmp(arg, "warn"))
- *val = SIGN_WARN_VERBATIM;
- else if (!strcmp(arg, "warn-strip"))
- *val = SIGN_WARN_STRIP;
- else if (!strcmp(arg, "strip"))
- *val = SIGN_STRIP;
- else
+
+ if (parse_sign_mode(arg, val))
return error("Unknown %s mode: %s", opt->long_name, arg);
+
return 0;
}
diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 2c35f9345d..606c6aea82 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -188,6 +188,8 @@ static int global_argc;
static const char **global_argv;
static const char *global_prefix;
+static enum sign_mode signed_commit_mode = SIGN_VERBATIM;
+
/* Memory pools */
static struct mem_pool fi_mem_pool = {
.block_alloc = 2*1024*1024 - sizeof(struct mp_block),
@@ -897,11 +899,11 @@ static void end_packfile(void)
idx_name = keep_pack(create_index());
/* Register the packfile with core git's machinery. */
- new_p = add_packed_git(pack_data->repo, idx_name, strlen(idx_name), 1);
+ new_p = packfile_store_load_pack(pack_data->repo->objects->packfiles,
+ idx_name, 1);
if (!new_p)
die("core git rejected index %s", idx_name);
all_packs[pack_id] = new_p;
- install_packed_git(the_repository, new_p);
free(idx_name);
/* Print the boundary */
@@ -952,6 +954,7 @@ static int store_object(
struct object_id *oidout,
uintmax_t mark)
{
+ struct packfile_store *packs = the_repository->objects->packfiles;
void *out, *delta;
struct object_entry *e;
unsigned char hdr[96];
@@ -975,7 +978,7 @@ static int store_object(
if (e->idx.offset) {
duplicate_count_by_type[type]++;
return 1;
- } else if (find_oid_pack(&oid, get_all_packs(the_repository))) {
+ } else if (find_oid_pack(&oid, packfile_store_get_all_packs(packs))) {
e->type = type;
e->pack_id = MAX_PACK_ID;
e->idx.offset = 1; /* just not zero! */
@@ -1092,6 +1095,7 @@ static void truncate_pack(struct hashfile_checkpoint *checkpoint)
static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
{
+ struct packfile_store *packs = the_repository->objects->packfiles;
size_t in_sz = 64 * 1024, out_sz = 64 * 1024;
unsigned char *in_buf = xmalloc(in_sz);
unsigned char *out_buf = xmalloc(out_sz);
@@ -1175,7 +1179,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
duplicate_count_by_type[OBJ_BLOB]++;
truncate_pack(&checkpoint);
- } else if (find_oid_pack(&oid, get_all_packs(the_repository))) {
+ } else if (find_oid_pack(&oid, packfile_store_get_all_packs(packs))) {
e->type = OBJ_BLOB;
e->pack_id = MAX_PACK_ID;
e->idx.offset = 1; /* just not zero! */
@@ -2752,6 +2756,15 @@ static void parse_one_signature(struct signature_data *sig, const char *v)
parse_data(&sig->data, 0, NULL);
}
+static void discard_one_signature(void)
+{
+ struct strbuf data = STRBUF_INIT;
+
+ read_next_command();
+ parse_data(&data, 0, NULL);
+ strbuf_release(&data);
+}
+
static void add_gpgsig_to_commit(struct strbuf *commit_data,
const char *header,
struct signature_data *sig)
@@ -2785,6 +2798,22 @@ static void store_signature(struct signature_data *stored_sig,
}
}
+static void import_one_signature(struct signature_data *sig_sha1,
+ struct signature_data *sig_sha256,
+ const char *v)
+{
+ struct signature_data sig = { NULL, NULL, STRBUF_INIT };
+
+ parse_one_signature(&sig, v);
+
+ if (!strcmp(sig.hash_algo, "sha1"))
+ store_signature(sig_sha1, &sig, "SHA-1");
+ else if (!strcmp(sig.hash_algo, "sha256"))
+ store_signature(sig_sha256, &sig, "SHA-256");
+ else
+ die(_("parse_one_signature() returned unknown hash algo"));
+}
+
static void parse_new_commit(const char *arg)
{
static struct strbuf msg = STRBUF_INIT;
@@ -2817,19 +2846,32 @@ static void parse_new_commit(const char *arg)
if (!committer)
die("Expected committer but didn't get one");
- /* Process signatures (up to 2: one "sha1" and one "sha256") */
while (skip_prefix(command_buf.buf, "gpgsig ", &v)) {
- struct signature_data sig = { NULL, NULL, STRBUF_INIT };
-
- parse_one_signature(&sig, v);
+ switch (signed_commit_mode) {
+
+ /* First, modes that don't need the signature to be parsed */
+ case SIGN_ABORT:
+ die("encountered signed commit; use "
+ "--signed-commits=<mode> to handle it");
+ case SIGN_WARN_STRIP:
+ warning(_("stripping a commit signature"));
+ /* fallthru */
+ case SIGN_STRIP:
+ discard_one_signature();
+ break;
- if (!strcmp(sig.hash_algo, "sha1"))
- store_signature(&sig_sha1, &sig, "SHA-1");
- else if (!strcmp(sig.hash_algo, "sha256"))
- store_signature(&sig_sha256, &sig, "SHA-256");
- else
- BUG("parse_one_signature() returned unknown hash algo");
+ /* Second, modes that parse the signature */
+ case SIGN_WARN_VERBATIM:
+ warning(_("importing a commit signature verbatim"));
+ /* fallthru */
+ case SIGN_VERBATIM:
+ import_one_signature(&sig_sha1, &sig_sha256, v);
+ break;
+ /* Third, BUG */
+ default:
+ BUG("invalid signed_commit_mode value %d", signed_commit_mode);
+ }
read_next_command();
}
@@ -3501,6 +3543,9 @@ static int parse_one_option(const char *option)
option_active_branches(option);
} else if (skip_prefix(option, "export-pack-edges=", &option)) {
option_export_pack_edges(option);
+ } else if (skip_prefix(option, "signed-commits=", &option)) {
+ if (parse_sign_mode(option, &signed_commit_mode))
+ usagef(_("unknown --signed-commits mode '%s'"), option);
} else if (!strcmp(option, "quiet")) {
show_stats = 0;
quiet = 1;
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 24645c4653..c7ff3480fb 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -1643,7 +1643,8 @@ cleanup:
struct ref_rejection_data {
int *retcode;
- int conflict_msg_shown;
+ bool conflict_msg_shown;
+ bool case_sensitive_msg_shown;
const char *remote_name;
};
@@ -1657,11 +1658,25 @@ static void ref_transaction_rejection_handler(const char *refname,
{
struct ref_rejection_data *data = cb_data;
- if (err == REF_TRANSACTION_ERROR_NAME_CONFLICT && !data->conflict_msg_shown) {
+ if (err == REF_TRANSACTION_ERROR_CASE_CONFLICT && ignore_case &&
+ !data->case_sensitive_msg_shown) {
+ error(_("You're on a case-insensitive filesystem, and the remote you are\n"
+ "trying to fetch from has references that only differ in casing. It\n"
+ "is impossible to store such references with the 'files' backend. You\n"
+ "can either accept this as-is, in which case you won't be able to\n"
+ "store all remote references on disk. Or you can alternatively\n"
+ "migrate your repository to use the 'reftable' backend with the\n"
+ "following command:\n\n git refs migrate --ref-format=reftable\n\n"
+ "Please keep in mind that not all implementations of Git support this\n"
+ "new format yet. So if you use tools other than Git to access this\n"
+ "repository it may not be an option to migrate to reftables.\n"));
+ data->case_sensitive_msg_shown = true;
+ } else if (err == REF_TRANSACTION_ERROR_NAME_CONFLICT &&
+ !data->conflict_msg_shown) {
error(_("some local refs could not be updated; try running\n"
" 'git remote prune %s' to remove any old, conflicting "
"branches"), data->remote_name);
- data->conflict_msg_shown = 1;
+ data->conflict_msg_shown = true;
} else {
const char *reason = ref_transaction_error_msg(err);
diff --git a/builtin/fsck.c b/builtin/fsck.c
index d2eb9d4fbe..8ee95e0d67 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -867,19 +867,20 @@ static int mark_packed_for_connectivity(const struct object_id *oid,
static int check_pack_rev_indexes(struct repository *r, int show_progress)
{
+ struct packfile_store *packs = r->objects->packfiles;
struct progress *progress = NULL;
uint32_t pack_count = 0;
int res = 0;
if (show_progress) {
- for (struct packed_git *p = get_all_packs(r); p; p = p->next)
+ for (struct packed_git *p = packfile_store_get_all_packs(packs); p; p = p->next)
pack_count++;
progress = start_delayed_progress(the_repository,
"Verifying reverse pack-indexes", pack_count);
pack_count = 0;
}
- for (struct packed_git *p = get_all_packs(r); p; p = p->next) {
+ for (struct packed_git *p = packfile_store_get_all_packs(packs); p; p = p->next) {
int load_error = load_pack_revindex_from_disk(p);
if (load_error < 0) {
@@ -999,6 +1000,8 @@ int cmd_fsck(int argc,
for_each_packed_object(the_repository,
mark_packed_for_connectivity, NULL, 0);
} else {
+ struct packfile_store *packs = the_repository->objects->packfiles;
+
odb_prepare_alternates(the_repository->objects);
for (source = the_repository->objects->sources; source; source = source->next)
fsck_source(source);
@@ -1009,7 +1012,7 @@ int cmd_fsck(int argc,
struct progress *progress = NULL;
if (show_progress) {
- for (p = get_all_packs(the_repository); p;
+ for (p = packfile_store_get_all_packs(packs); p;
p = p->next) {
if (open_pack_index(p))
continue;
@@ -1019,7 +1022,7 @@ int cmd_fsck(int argc,
progress = start_progress(the_repository,
_("Checking objects"), total);
}
- for (p = get_all_packs(the_repository); p;
+ for (p = packfile_store_get_all_packs(packs); p;
p = p->next) {
/* verify gives error messages itself */
if (verify_pack(the_repository,
diff --git a/builtin/gc.c b/builtin/gc.c
index 03ae4926b2..e19e13d978 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -487,9 +487,10 @@ static int too_many_loose_objects(struct gc_config *cfg)
static struct packed_git *find_base_packs(struct string_list *packs,
unsigned long limit)
{
+ struct packfile_store *packfiles = the_repository->objects->packfiles;
struct packed_git *p, *base = NULL;
- for (p = get_all_packs(the_repository); p; p = p->next) {
+ for (p = packfile_store_get_all_packs(packfiles); p; p = p->next) {
if (!p->pack_local || p->is_cruft)
continue;
if (limit) {
@@ -508,13 +509,14 @@ static struct packed_git *find_base_packs(struct string_list *packs,
static int too_many_packs(struct gc_config *cfg)
{
+ struct packfile_store *packs = the_repository->objects->packfiles;
struct packed_git *p;
int cnt;
if (cfg->gc_auto_pack_limit <= 0)
return 0;
- for (cnt = 0, p = get_all_packs(the_repository); p; p = p->next) {
+ for (cnt = 0, p = packfile_store_get_all_packs(packs); p; p = p->next) {
if (!p->pack_local)
continue;
if (p->pack_keep)
@@ -1042,7 +1044,7 @@ int cmd_gc(int argc,
die(FAILED_RUN, "rerere");
report_garbage = report_pack_garbage;
- reprepare_packed_git(the_repository);
+ odb_reprepare(the_repository->objects);
if (pack_garbage.nr > 0) {
close_object_store(the_repository->objects);
clean_pack_garbage();
@@ -1423,7 +1425,7 @@ static int incremental_repack_auto_condition(struct gc_config *cfg UNUSED)
if (incremental_repack_auto_limit < 0)
return 1;
- for (p = get_packed_git(the_repository);
+ for (p = packfile_store_get_packs(the_repository->objects->packfiles);
count < incremental_repack_auto_limit && p;
p = p->next) {
if (!p->multi_pack_index)
@@ -1491,8 +1493,8 @@ static off_t get_auto_pack_size(void)
struct packed_git *p;
struct repository *r = the_repository;
- reprepare_packed_git(r);
- for (p = get_all_packs(r); p; p = p->next) {
+ odb_reprepare(r->objects);
+ for (p = packfile_store_get_all_packs(r->objects->packfiles); p; p = p->next) {
if (p->pack_size > max_size) {
second_largest_size = max_size;
max_size = p->pack_size;
diff --git a/builtin/grep.c b/builtin/grep.c
index 5df6537333..13841fbf00 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -1091,7 +1091,7 @@ int cmd_grep(int argc,
if (show_in_pager == default_pager)
show_in_pager = git_pager(the_repository, 1);
if (show_in_pager) {
- opt.color = 0;
+ opt.color = GIT_COLOR_NEVER;
opt.name_only = 1;
opt.null_following_name = 1;
opt.output_priv = &path_list;
@@ -1214,7 +1214,7 @@ int cmd_grep(int argc,
if (recurse_submodules)
repo_read_gitmodules(the_repository, 1);
if (startup_info->have_repository)
- (void)get_packed_git(the_repository);
+ (void)packfile_store_get_packs(the_repository->objects->packfiles);
start_threads(&opt);
} else {
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index f91c301bba..2b78ba7fe4 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1640,13 +1640,9 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
rename_tmp_packfile(&final_index_name, curr_index_name, &index_name,
hash, "idx", 1);
- if (do_fsck_object) {
- struct packed_git *p;
- p = add_packed_git(the_repository, final_index_name,
- strlen(final_index_name), 0);
- if (p)
- install_packed_git(the_repository, p);
- }
+ if (do_fsck_object)
+ packfile_store_load_pack(the_repository->objects->packfiles,
+ final_index_name, 0);
if (!from_stdin) {
printf("%s\n", hash_to_hex(hash));
diff --git a/builtin/last-modified.c b/builtin/last-modified.c
new file mode 100644
index 0000000000..ae8b36a2c3
--- /dev/null
+++ b/builtin/last-modified.c
@@ -0,0 +1,327 @@
+#include "git-compat-util.h"
+#include "bloom.h"
+#include "builtin.h"
+#include "commit-graph.h"
+#include "commit.h"
+#include "config.h"
+#include "environment.h"
+#include "diff.h"
+#include "diffcore.h"
+#include "environment.h"
+#include "hashmap.h"
+#include "hex.h"
+#include "log-tree.h"
+#include "object-name.h"
+#include "object.h"
+#include "parse-options.h"
+#include "quote.h"
+#include "repository.h"
+#include "revision.h"
+
+struct last_modified_entry {
+ struct hashmap_entry hashent;
+ struct object_id oid;
+ struct bloom_key key;
+ const char path[FLEX_ARRAY];
+};
+
+static int last_modified_entry_hashcmp(const void *unused UNUSED,
+ const struct hashmap_entry *hent1,
+ const struct hashmap_entry *hent2,
+ const void *path)
+{
+ const struct last_modified_entry *ent1 =
+ container_of(hent1, const struct last_modified_entry, hashent);
+ const struct last_modified_entry *ent2 =
+ container_of(hent2, const struct last_modified_entry, hashent);
+ return strcmp(ent1->path, path ? path : ent2->path);
+}
+
+struct last_modified {
+ struct hashmap paths;
+ struct rev_info rev;
+ bool recursive;
+ bool show_trees;
+};
+
+static void last_modified_release(struct last_modified *lm)
+{
+ struct hashmap_iter iter;
+ struct last_modified_entry *ent;
+
+ hashmap_for_each_entry(&lm->paths, &iter, ent, hashent)
+ bloom_key_clear(&ent->key);
+
+ hashmap_clear_and_free(&lm->paths, struct last_modified_entry, hashent);
+ release_revisions(&lm->rev);
+}
+
+struct last_modified_callback_data {
+ struct last_modified *lm;
+ struct commit *commit;
+};
+
+static void add_path_from_diff(struct diff_queue_struct *q,
+ struct diff_options *opt UNUSED, void *data)
+{
+ struct last_modified *lm = data;
+
+ for (int i = 0; i < q->nr; i++) {
+ struct diff_filepair *p = q->queue[i];
+ struct last_modified_entry *ent;
+ const char *path = p->two->path;
+
+ FLEX_ALLOC_STR(ent, path, path);
+ oidcpy(&ent->oid, &p->two->oid);
+ if (lm->rev.bloom_filter_settings)
+ bloom_key_fill(&ent->key, path, strlen(path),
+ lm->rev.bloom_filter_settings);
+ hashmap_entry_init(&ent->hashent, strhash(ent->path));
+ hashmap_add(&lm->paths, &ent->hashent);
+ }
+}
+
+static int populate_paths_from_revs(struct last_modified *lm)
+{
+ int num_interesting = 0;
+ struct diff_options diffopt;
+
+ /*
+ * Create a copy of `struct diff_options`. In this copy a callback is
+ * set that when called adds entries to `paths` in `struct last_modified`.
+ * This copy is used to diff the tree of the target revision against an
+ * empty tree. This results in all paths in the target revision being
+ * listed. After `paths` is populated, we don't need this copy no more.
+ */
+ memcpy(&diffopt, &lm->rev.diffopt, sizeof(diffopt));
+ copy_pathspec(&diffopt.pathspec, &lm->rev.diffopt.pathspec);
+ diffopt.output_format = DIFF_FORMAT_CALLBACK;
+ diffopt.format_callback = add_path_from_diff;
+ diffopt.format_callback_data = lm;
+
+ for (size_t i = 0; i < lm->rev.pending.nr; i++) {
+ struct object_array_entry *obj = lm->rev.pending.objects + i;
+
+ if (obj->item->flags & UNINTERESTING)
+ continue;
+
+ if (num_interesting++)
+ return error(_("last-modified can only operate on one tree at a time"));
+
+ diff_tree_oid(lm->rev.repo->hash_algo->empty_tree,
+ &obj->item->oid, "", &diffopt);
+ diff_flush(&diffopt);
+ }
+ clear_pathspec(&diffopt.pathspec);
+
+ return 0;
+}
+
+static void last_modified_emit(struct last_modified *lm,
+ const char *path, const struct commit *commit)
+
+{
+ if (commit->object.flags & BOUNDARY)
+ putchar('^');
+ printf("%s\t", oid_to_hex(&commit->object.oid));
+
+ if (lm->rev.diffopt.line_termination)
+ write_name_quoted(path, stdout, '\n');
+ else
+ printf("%s%c", path, '\0');
+}
+
+static void mark_path(const char *path, const struct object_id *oid,
+ struct last_modified_callback_data *data)
+{
+ struct last_modified_entry *ent;
+
+ /* Is it even a path that we are interested in? */
+ ent = hashmap_get_entry_from_hash(&data->lm->paths, strhash(path), path,
+ struct last_modified_entry, hashent);
+ if (!ent)
+ return;
+
+ /*
+ * Is it arriving at a version of interest, or is it from a side branch
+ * which did not contribute to the final state?
+ */
+ if (!oideq(oid, &ent->oid))
+ return;
+
+ last_modified_emit(data->lm, path, data->commit);
+
+ hashmap_remove(&data->lm->paths, &ent->hashent, path);
+ bloom_key_clear(&ent->key);
+ free(ent);
+}
+
+static void last_modified_diff(struct diff_queue_struct *q,
+ struct diff_options *opt UNUSED, void *cbdata)
+{
+ struct last_modified_callback_data *data = cbdata;
+
+ for (int i = 0; i < q->nr; i++) {
+ struct diff_filepair *p = q->queue[i];
+ switch (p->status) {
+ case DIFF_STATUS_DELETED:
+ /*
+ * There's no point in feeding a deletion, as it could
+ * not have resulted in our current state, which
+ * actually has the file.
+ */
+ break;
+
+ default:
+ /*
+ * Otherwise, we care only that we somehow arrived at
+ * a final oid state. Note that this covers some
+ * potentially controversial areas, including:
+ *
+ * 1. A rename or copy will be found, as it is the
+ * first time the content has arrived at the given
+ * path.
+ *
+ * 2. Even a non-content modification like a mode or
+ * type change will trigger it.
+ *
+ * We take the inclusive approach for now, and find
+ * anything which impacts the path. Options to tweak
+ * the behavior (e.g., to "--follow" the content across
+ * renames) can come later.
+ */
+ mark_path(p->two->path, &p->two->oid, data);
+ break;
+ }
+ }
+}
+
+static bool maybe_changed_path(struct last_modified *lm, struct commit *origin)
+{
+ struct bloom_filter *filter;
+ struct last_modified_entry *ent;
+ struct hashmap_iter iter;
+
+ if (!lm->rev.bloom_filter_settings)
+ return true;
+
+ if (commit_graph_generation(origin) == GENERATION_NUMBER_INFINITY)
+ return true;
+
+ filter = get_bloom_filter(lm->rev.repo, origin);
+ if (!filter)
+ return true;
+
+ hashmap_for_each_entry(&lm->paths, &iter, ent, hashent) {
+ if (bloom_filter_contains(filter, &ent->key,
+ lm->rev.bloom_filter_settings))
+ return true;
+ }
+ return false;
+}
+
+static int last_modified_run(struct last_modified *lm)
+{
+ struct last_modified_callback_data data = { .lm = lm };
+
+ lm->rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
+ lm->rev.diffopt.format_callback = last_modified_diff;
+ lm->rev.diffopt.format_callback_data = &data;
+
+ prepare_revision_walk(&lm->rev);
+
+ while (hashmap_get_size(&lm->paths)) {
+ data.commit = get_revision(&lm->rev);
+ if (!data.commit)
+ BUG("paths remaining beyond boundary in last-modified");
+
+ if (data.commit->object.flags & BOUNDARY) {
+ diff_tree_oid(lm->rev.repo->hash_algo->empty_tree,
+ &data.commit->object.oid, "",
+ &lm->rev.diffopt);
+ diff_flush(&lm->rev.diffopt);
+
+ break;
+ }
+
+ if (!maybe_changed_path(lm, data.commit))
+ continue;
+
+ log_tree_commit(&lm->rev, data.commit);
+ }
+
+ return 0;
+}
+
+static int last_modified_init(struct last_modified *lm, struct repository *r,
+ const char *prefix, int argc, const char **argv)
+{
+ hashmap_init(&lm->paths, last_modified_entry_hashcmp, NULL, 0);
+
+ repo_init_revisions(r, &lm->rev, prefix);
+ lm->rev.def = "HEAD";
+ lm->rev.combine_merges = 1;
+ lm->rev.show_root_diff = 1;
+ lm->rev.boundary = 1;
+ lm->rev.no_commit_id = 1;
+ lm->rev.diff = 1;
+ lm->rev.diffopt.flags.no_recursive_diff_tree_combined = 1;
+ lm->rev.diffopt.flags.recursive = lm->recursive;
+ lm->rev.diffopt.flags.tree_in_recursive = lm->show_trees;
+
+ argc = setup_revisions(argc, argv, &lm->rev, NULL);
+ if (argc > 1) {
+ error(_("unknown last-modified argument: %s"), argv[1]);
+ return argc;
+ }
+
+ lm->rev.bloom_filter_settings = get_bloom_filter_settings(lm->rev.repo);
+
+ if (populate_paths_from_revs(lm) < 0)
+ return error(_("unable to setup last-modified"));
+
+ return 0;
+}
+
+int cmd_last_modified(int argc, const char **argv, const char *prefix,
+ struct repository *repo)
+{
+ int ret;
+ struct last_modified lm = { 0 };
+
+ const char * const last_modified_usage[] = {
+ N_("git last-modified [--recursive] [--show-trees] "
+ "[<revision-range>] [[--] <path>...]"),
+ NULL
+ };
+
+ struct option last_modified_options[] = {
+ OPT_BOOL('r', "recursive", &lm.recursive,
+ N_("recurse into subtrees")),
+ OPT_BOOL('t', "show-trees", &lm.show_trees,
+ N_("show tree entries when recursing into subtrees")),
+ OPT_END()
+ };
+
+ argc = parse_options(argc, argv, prefix, last_modified_options,
+ last_modified_usage,
+ PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT);
+
+ repo_config(repo, git_default_config, NULL);
+
+ ret = last_modified_init(&lm, repo, prefix, argc, argv);
+ if (ret > 0)
+ usage_with_options(last_modified_usage,
+ last_modified_options);
+ if (ret)
+ goto out;
+
+ ret = last_modified_run(&lm);
+ if (ret)
+ goto out;
+
+out:
+ last_modified_release(&lm);
+
+ return ret;
+}
diff --git a/builtin/log.c b/builtin/log.c
index c2f8bbf863..8aa1777940 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -543,7 +543,13 @@ int cmd_whatchanged(int argc,
cmd_log_init(argc, argv, prefix, &rev, &opt, &cfg);
if (!cfg.i_still_use_this)
- you_still_use_that("git whatchanged");
+ you_still_use_that("git whatchanged",
+ _("\n"
+ "hint: You can replace 'git whatchanged <opts>' with:\n"
+ "hint:\tgit log <opts> --raw --no-merges\n"
+ "hint: Or make an alias:\n"
+ "hint:\tgit config set --global alias.whatchanged 'log --raw --no-merges'\n"
+ "\n"));
if (!rev.diffopt.output_format)
rev.diffopt.output_format = DIFF_FORMAT_RAW;
@@ -1404,6 +1410,7 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,
struct range_diff_options range_diff_opts = {
.creation_factor = rev->creation_factor,
.dual_color = 1,
+ .max_memory = RANGE_DIFF_MAX_MEMORY_DEFAULT,
.diffopt = &opts,
.other_arg = &other_arg
};
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index c06a6f33e4..b148607f7a 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -414,14 +414,21 @@ static void show_files(struct repository *repo, struct dir_struct *dir)
if (!(show_cached || show_stage || show_deleted || show_modified))
return;
- if (!show_sparse_dirs)
- ensure_full_index(repo->index);
-
for (i = 0; i < repo->index->cache_nr; i++) {
const struct cache_entry *ce = repo->index->cache[i];
struct stat st;
int stat_err;
+ if (S_ISSPARSEDIR(ce->ce_mode) && !show_sparse_dirs) {
+ /*
+ * This is the first time we've hit a sparse dir,
+ * so expansion will leave the first 'i' entries
+ * alone.
+ */
+ ensure_full_index(repo->index);
+ ce = repo->index->cache[i];
+ }
+
construct_fullname(&fullname, repo, ce);
if ((dir->flags & DIR_SHOW_IGNORED) &&
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 5d55731ca3..ec6940fc7c 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -373,7 +373,6 @@ int cmd_ls_tree(int argc,
OPT_END()
};
struct ls_tree_cmdmode_to_fmt *m2f = ls_tree_cmdmode_format;
- struct object_context obj_context = {0};
int ret;
repo_config(the_repository, git_default_config, NULL);
@@ -405,9 +404,8 @@ int cmd_ls_tree(int argc,
ls_tree_usage, ls_tree_options);
if (argc < 1)
usage_with_options(ls_tree_usage, ls_tree_options);
- if (get_oid_with_context(the_repository, argv[0],
- GET_OID_HASH_ANY, &oid,
- &obj_context))
+ if (repo_get_oid_with_flags(the_repository, argv[0], &oid,
+ GET_OID_HASH_ANY))
die("Not a valid object name %s", argv[0]);
/*
@@ -447,6 +445,5 @@ int cmd_ls_tree(int argc,
ret = !!read_tree(the_repository, tree, &options.pathspec, fn, &options);
clear_pathspec(&options.pathspec);
- object_context_release(&obj_context);
return ret;
}
diff --git a/builtin/merge.c b/builtin/merge.c
index b235af730a..c421a11b0b 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -1379,6 +1379,9 @@ int cmd_merge(int argc,
show_usage_with_options_if_asked(argc, argv,
builtin_merge_usage, builtin_merge_options);
+#ifndef WITH_BREAKING_CHANGES
+ warn_on_auto_comment_char = true;
+#endif /* !WITH_BREAKING_CHANGES */
prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;
diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c
index d3b9e98be3..5f364aa816 100644
--- a/builtin/multi-pack-index.c
+++ b/builtin/multi-pack-index.c
@@ -65,12 +65,20 @@ static int parse_object_dir(const struct option *opt, const char *arg,
char **value = opt->value;
free(*value);
if (unset)
- *value = xstrdup(repo_get_object_directory(the_repository));
+ *value = xstrdup(the_repository->objects->sources->path);
else
*value = real_pathdup(arg, 1);
return 0;
}
+static struct odb_source *handle_object_dir_option(struct repository *repo)
+{
+ struct odb_source *source = odb_find_source(repo->objects, opts.object_dir);
+ if (!source)
+ source = odb_add_to_alternates_memory(repo->objects, opts.object_dir);
+ return source;
+}
+
static struct option common_opts[] = {
OPT_CALLBACK(0, "object-dir", &opts.object_dir,
N_("directory"),
@@ -140,6 +148,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
N_("refs snapshot for selecting bitmap commits")),
OPT_END(),
};
+ struct odb_source *source;
int ret;
opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE;
@@ -158,6 +167,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
if (argc)
usage_with_options(builtin_multi_pack_index_write_usage,
options);
+ source = handle_object_dir_option(repo);
FREE_AND_NULL(options);
@@ -166,7 +176,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
read_packs_from_stdin(&packs);
- ret = write_midx_file_only(repo, opts.object_dir, &packs,
+ ret = write_midx_file_only(source, &packs,
opts.preferred_pack,
opts.refs_snapshot, opts.flags);
@@ -177,7 +187,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
}
- ret = write_midx_file(repo, opts.object_dir, opts.preferred_pack,
+ ret = write_midx_file(source, opts.preferred_pack,
opts.refs_snapshot, opts.flags);
free(opts.refs_snapshot);
@@ -194,6 +204,8 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv,
N_("force progress reporting"), MIDX_PROGRESS),
OPT_END(),
};
+ struct odb_source *source;
+
options = add_common_options(builtin_multi_pack_index_verify_options);
trace2_cmd_mode(argv[0]);
@@ -206,10 +218,11 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv,
if (argc)
usage_with_options(builtin_multi_pack_index_verify_usage,
options);
+ source = handle_object_dir_option(the_repository);
FREE_AND_NULL(options);
- return verify_midx_file(the_repository, opts.object_dir, opts.flags);
+ return verify_midx_file(source, opts.flags);
}
static int cmd_multi_pack_index_expire(int argc, const char **argv,
@@ -222,6 +235,8 @@ static int cmd_multi_pack_index_expire(int argc, const char **argv,
N_("force progress reporting"), MIDX_PROGRESS),
OPT_END(),
};
+ struct odb_source *source;
+
options = add_common_options(builtin_multi_pack_index_expire_options);
trace2_cmd_mode(argv[0]);
@@ -234,10 +249,11 @@ static int cmd_multi_pack_index_expire(int argc, const char **argv,
if (argc)
usage_with_options(builtin_multi_pack_index_expire_usage,
options);
+ source = handle_object_dir_option(the_repository);
FREE_AND_NULL(options);
- return expire_midx_packs(the_repository, opts.object_dir, opts.flags);
+ return expire_midx_packs(source, opts.flags);
}
static int cmd_multi_pack_index_repack(int argc, const char **argv,
@@ -252,6 +268,7 @@ static int cmd_multi_pack_index_repack(int argc, const char **argv,
N_("force progress reporting"), MIDX_PROGRESS),
OPT_END(),
};
+ struct odb_source *source;
options = add_common_options(builtin_multi_pack_index_repack_options);
@@ -266,11 +283,11 @@ static int cmd_multi_pack_index_repack(int argc, const char **argv,
if (argc)
usage_with_options(builtin_multi_pack_index_repack_usage,
options);
+ source = handle_object_dir_option(the_repository);
FREE_AND_NULL(options);
- return midx_repack(the_repository, opts.object_dir,
- (size_t)opts.batch_size, opts.flags);
+ return midx_repack(source, (size_t)opts.batch_size, opts.flags);
}
int cmd_multi_pack_index(int argc,
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 53a2256250..5bdc44fb2d 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1741,19 +1741,19 @@ static int want_object_in_pack_mtime(const struct object_id *oid,
struct multi_pack_index *m = get_multi_pack_index(source);
struct pack_entry e;
- if (m && fill_midx_entry(the_repository, oid, &e, m)) {
+ if (m && fill_midx_entry(m, oid, &e)) {
want = want_object_in_pack_one(e.p, oid, exclude, found_pack, found_offset, found_mtime);
if (want != -1)
return want;
}
}
- list_for_each(pos, get_packed_git_mru(the_repository)) {
+ list_for_each(pos, packfile_store_get_packs_mru(the_repository->objects->packfiles)) {
struct packed_git *p = list_entry(pos, struct packed_git, mru);
want = want_object_in_pack_one(p, oid, exclude, found_pack, found_offset, found_mtime);
if (!exclude && want > 0)
list_move(&p->mru,
- get_packed_git_mru(the_repository));
+ packfile_store_get_packs_mru(the_repository->objects->packfiles));
if (want != -1)
return want;
}
@@ -3774,7 +3774,7 @@ static void show_object_pack_hint(struct object *object, const char *name,
enum stdin_packs_mode mode = *(enum stdin_packs_mode *)data;
if (mode == STDIN_PACKS_MODE_FOLLOW) {
if (object->type == OBJ_BLOB &&
- !has_object(the_repository, &object->oid, 0))
+ !odb_has_object(the_repository->objects, &object->oid, 0))
return;
add_object_entry(&object->oid, object->type, name, 0);
} else {
@@ -3831,6 +3831,7 @@ static int pack_mtime_cmp(const void *_a, const void *_b)
static void read_packs_list_from_stdin(struct rev_info *revs)
{
+ struct packfile_store *packs = the_repository->objects->packfiles;
struct strbuf buf = STRBUF_INIT;
struct string_list include_packs = STRING_LIST_INIT_DUP;
struct string_list exclude_packs = STRING_LIST_INIT_DUP;
@@ -3855,7 +3856,7 @@ static void read_packs_list_from_stdin(struct rev_info *revs)
string_list_sort(&exclude_packs);
string_list_remove_duplicates(&exclude_packs, 0);
- for (p = get_all_packs(the_repository); p; p = p->next) {
+ for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
const char *pack_name = pack_basename(p);
if ((item = string_list_lookup(&include_packs, pack_name)))
@@ -4076,6 +4077,7 @@ static void enumerate_cruft_objects(void)
static void enumerate_and_traverse_cruft_objects(struct string_list *fresh_packs)
{
+ struct packfile_store *packs = the_repository->objects->packfiles;
struct packed_git *p;
struct rev_info revs;
int ret;
@@ -4105,7 +4107,7 @@ static void enumerate_and_traverse_cruft_objects(struct string_list *fresh_packs
* Re-mark only the fresh packs as kept so that objects in
* unknown packs do not halt the reachability traversal early.
*/
- for (p = get_all_packs(the_repository); p; p = p->next)
+ for (p = packfile_store_get_all_packs(packs); p; p = p->next)
p->pack_keep_in_core = 0;
mark_pack_kept_in_core(fresh_packs, 1);
@@ -4122,6 +4124,7 @@ static void enumerate_and_traverse_cruft_objects(struct string_list *fresh_packs
static void read_cruft_objects(void)
{
+ struct packfile_store *packs = the_repository->objects->packfiles;
struct strbuf buf = STRBUF_INIT;
struct string_list discard_packs = STRING_LIST_INIT_DUP;
struct string_list fresh_packs = STRING_LIST_INIT_DUP;
@@ -4142,7 +4145,7 @@ static void read_cruft_objects(void)
string_list_sort(&discard_packs);
string_list_sort(&fresh_packs);
- for (p = get_all_packs(the_repository); p; p = p->next) {
+ for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
const char *pack_name = pack_basename(p);
struct string_list_item *item;
@@ -4390,11 +4393,12 @@ static void add_unreachable_loose_objects(struct rev_info *revs)
static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)
{
+ struct packfile_store *packs = the_repository->objects->packfiles;
static struct packed_git *last_found = (void *)1;
struct packed_git *p;
p = (last_found != (void *)1) ? last_found :
- get_all_packs(the_repository);
+ packfile_store_get_all_packs(packs);
while (p) {
if ((!p->pack_local || p->pack_keep ||
@@ -4404,7 +4408,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)
return 1;
}
if (p == last_found)
- p = get_all_packs(the_repository);
+ p = packfile_store_get_all_packs(packs);
else
p = p->next;
if (p == last_found)
@@ -4436,12 +4440,13 @@ static int loosened_object_can_be_discarded(const struct object_id *oid,
static void loosen_unused_packed_objects(void)
{
+ struct packfile_store *packs = the_repository->objects->packfiles;
struct packed_git *p;
uint32_t i;
uint32_t loosened_objects_nr = 0;
struct object_id oid;
- for (p = get_all_packs(the_repository); p; p = p->next) {
+ for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
if (!p->pack_local || p->pack_keep || p->pack_keep_in_core)
continue;
@@ -4591,8 +4596,8 @@ static int add_objects_by_path(const char *path,
/* Skip objects that do not exist locally. */
if ((exclude_promisor_objects || arg_missing_action != MA_ERROR) &&
- oid_object_info_extended(the_repository, oid, &oi,
- OBJECT_INFO_FOR_PREFETCH) < 0)
+ odb_read_object_info_extended(the_repository->objects, oid, &oi,
+ OBJECT_INFO_FOR_PREFETCH) < 0)
continue;
exclude = is_oid_uninteresting(the_repository, oid);
@@ -4650,7 +4655,7 @@ static void get_object_list_path_walk(struct rev_info *revs)
die(_("failed to pack objects via path-walk"));
}
-static void get_object_list(struct rev_info *revs, int ac, const char **av)
+static void get_object_list(struct rev_info *revs, struct strvec *argv)
{
struct setup_revision_opt s_r_opt = {
.allow_exclude_promisor_objects = 1,
@@ -4660,7 +4665,7 @@ static void get_object_list(struct rev_info *revs, int ac, const char **av)
int save_warning;
save_commit_buffer = 0;
- setup_revisions(ac, av, revs, &s_r_opt);
+ setup_revisions_from_strvec(argv, revs, &s_r_opt);
/* make sure shallows are read */
is_repository_shallow(the_repository);
@@ -4742,12 +4747,13 @@ static void get_object_list(struct rev_info *revs, int ac, const char **av)
static void add_extra_kept_packs(const struct string_list *names)
{
+ struct packfile_store *packs = the_repository->objects->packfiles;
struct packed_git *p;
if (!names->nr)
return;
- for (p = get_all_packs(the_repository); p; p = p->next) {
+ for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
const char *name = basename(p->pack_name);
int i;
@@ -5185,8 +5191,10 @@ int cmd_pack_objects(int argc,
add_extra_kept_packs(&keep_pack_list);
if (ignore_packed_keep_on_disk) {
+ struct packfile_store *packs = the_repository->objects->packfiles;
struct packed_git *p;
- for (p = get_all_packs(the_repository); p; p = p->next)
+
+ for (p = packfile_store_get_all_packs(packs); p; p = p->next)
if (p->pack_local && p->pack_keep)
break;
if (!p) /* no keep-able packs found */
@@ -5198,8 +5206,10 @@ int cmd_pack_objects(int argc,
* want to unset "local" based on looking at packs, as
* it also covers non-local objects
*/
+ struct packfile_store *packs = the_repository->objects->packfiles;
struct packed_git *p;
- for (p = get_all_packs(the_repository); p; p = p->next) {
+
+ for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
if (!p->pack_local) {
have_non_local_packs = 1;
break;
@@ -5229,7 +5239,7 @@ int cmd_pack_objects(int argc,
revs.include_check = is_not_in_promisor_pack;
revs.include_check_obj = is_not_in_promisor_pack_obj;
}
- get_object_list(&revs, rp.nr, rp.v);
+ get_object_list(&revs, &rp);
release_revisions(&revs);
}
cleanup_preferred_base();
diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c
index fe81c293e3..80743d8806 100644
--- a/builtin/pack-redundant.c
+++ b/builtin/pack-redundant.c
@@ -566,7 +566,8 @@ static struct pack_list * add_pack(struct packed_git *p)
static struct pack_list * add_pack_file(const char *filename)
{
- struct packed_git *p = get_all_packs(the_repository);
+ struct packfile_store *packs = the_repository->objects->packfiles;
+ struct packed_git *p = packfile_store_get_all_packs(packs);
if (strlen(filename) < 40)
die("Bad pack filename: %s", filename);
@@ -581,7 +582,8 @@ static struct pack_list * add_pack_file(const char *filename)
static void load_all(void)
{
- struct packed_git *p = get_all_packs(the_repository);
+ struct packfile_store *packs = the_repository->objects->packfiles;
+ struct packed_git *p = packfile_store_get_all_packs(packs);
while (p) {
add_pack(p);
@@ -626,7 +628,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s
}
if (!i_still_use_this)
- you_still_use_that("git pack-redundant");
+ you_still_use_that("git pack-redundant", NULL);
if (load_all_packs)
load_all();
diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c
index 5e28d0f9e8..3446b84cda 100644
--- a/builtin/pack-refs.c
+++ b/builtin/pack-refs.c
@@ -1,60 +1,16 @@
#include "builtin.h"
-#include "config.h"
-#include "environment.h"
#include "gettext.h"
-#include "parse-options.h"
-#include "refs.h"
-#include "revision.h"
-
-static char const * const pack_refs_usage[] = {
- N_("git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude <pattern>]"),
- NULL
-};
+#include "pack-refs.h"
int cmd_pack_refs(int argc,
const char **argv,
const char *prefix,
struct repository *repo)
{
- struct ref_exclusions excludes = REF_EXCLUSIONS_INIT;
- struct string_list included_refs = STRING_LIST_INIT_NODUP;
- struct pack_refs_opts pack_refs_opts = {
- .exclusions = &excludes,
- .includes = &included_refs,
- .flags = PACK_REFS_PRUNE,
- };
- struct string_list option_excluded_refs = STRING_LIST_INIT_NODUP;
- struct string_list_item *item;
- int pack_all = 0;
- int ret;
-
- struct option opts[] = {
- OPT_BOOL(0, "all", &pack_all, N_("pack everything")),
- OPT_BIT(0, "prune", &pack_refs_opts.flags, N_("prune loose refs (default)"), PACK_REFS_PRUNE),
- OPT_BIT(0, "auto", &pack_refs_opts.flags, N_("auto-pack refs as needed"), PACK_REFS_AUTO),
- OPT_STRING_LIST(0, "include", pack_refs_opts.includes, N_("pattern"),
- N_("references to include")),
- OPT_STRING_LIST(0, "exclude", &option_excluded_refs, N_("pattern"),
- N_("references to exclude")),
- OPT_END(),
+ static char const * const pack_refs_usage[] = {
+ N_("git pack-refs " PACK_REFS_OPTS),
+ NULL
};
- repo_config(repo, git_default_config, NULL);
- if (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0))
- usage_with_options(pack_refs_usage, opts);
-
- for_each_string_list_item(item, &option_excluded_refs)
- add_ref_exclusion(pack_refs_opts.exclusions, item->string);
-
- if (pack_all)
- string_list_append(pack_refs_opts.includes, "*");
-
- if (!pack_refs_opts.includes->nr)
- string_list_append(pack_refs_opts.includes, "refs/tags/*");
-
- ret = refs_pack_refs(get_main_ref_store(repo), &pack_refs_opts);
- clear_ref_exclusions(&excludes);
- string_list_clear(&included_refs, 0);
- string_list_clear(&option_excluded_refs, 0);
- return ret;
+ return pack_refs_core(argc, argv, prefix, repo, pack_refs_usage);
}
diff --git a/builtin/push.c b/builtin/push.c
index d0794b7b30..5b6cebbb85 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -27,7 +27,7 @@ static const char * const push_usage[] = {
NULL,
};
-static int push_use_color = -1;
+static enum git_colorbool push_use_color = GIT_COLOR_UNKNOWN;
static char push_colors[][COLOR_MAXLEN] = {
GIT_COLOR_RESET,
GIT_COLOR_RED, /* ERROR */
diff --git a/builtin/range-diff.c b/builtin/range-diff.c
index a563abff5f..1bc082a869 100644
--- a/builtin/range-diff.c
+++ b/builtin/range-diff.c
@@ -6,6 +6,8 @@
#include "parse-options.h"
#include "range-diff.h"
#include "config.h"
+#include "parse.h"
+#include "color.h"
static const char * const builtin_range_diff_usage[] = {
@@ -15,6 +17,21 @@ N_("git range-diff [<options>] <base> <old-tip> <new-tip>"),
NULL
};
+static int parse_max_memory(const struct option *opt, const char *arg, int unset)
+{
+ size_t *max_memory = opt->value;
+ uintmax_t val;
+
+ if (unset)
+ return 0;
+
+ if (!git_parse_unsigned(arg, &val, SIZE_MAX))
+ return error(_("invalid max-memory value: %s"), arg);
+
+ *max_memory = (size_t)val;
+ return 0;
+}
+
int cmd_range_diff(int argc,
const char **argv,
const char *prefix,
@@ -25,6 +42,7 @@ int cmd_range_diff(int argc,
struct strvec diff_merges_arg = STRVEC_INIT;
struct range_diff_options range_diff_opts = {
.creation_factor = RANGE_DIFF_CREATION_FACTOR_DEFAULT,
+ .max_memory = RANGE_DIFF_MAX_MEMORY_DEFAULT,
.diffopt = &diffopt,
.other_arg = &other_arg
};
@@ -40,6 +58,10 @@ int cmd_range_diff(int argc,
PARSE_OPT_OPTARG),
OPT_PASSTHRU_ARGV(0, "diff-merges", &diff_merges_arg,
N_("style"), N_("passed to 'git log'"), 0),
+ OPT_CALLBACK(0, "max-memory", &range_diff_opts.max_memory,
+ N_("size"),
+ N_("maximum memory for cost matrix (default 4G)"),
+ parse_max_memory),
OPT_PASSTHRU_ARGV(0, "remerge-diff", &diff_merges_arg, NULL,
N_("passed to 'git log'"), PARSE_OPT_NOARG),
OPT_BOOL(0, "left-only", &left_only,
@@ -66,7 +88,7 @@ int cmd_range_diff(int argc,
/* force color when --dual-color was used */
if (!simple_color)
- diffopt.use_color = 1;
+ diffopt.use_color = GIT_COLOR_ALWAYS;
/* If `--diff-merges` was specified, imply `--merges` */
if (diff_merges_arg.nr) {
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 3c85768d29..c468828189 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -299,8 +299,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
oid_to_hex(&opts->restrict_revision->object.oid));
ret = sequencer_make_script(the_repository, &todo_list.buf,
- make_script_args.nr, make_script_args.v,
- flags);
+ &make_script_args, flags);
if (ret) {
error(_("could not generate todo list"));
goto cleanup;
@@ -1242,6 +1241,9 @@ int cmd_rebase(int argc,
builtin_rebase_usage,
builtin_rebase_options);
+#ifndef WITH_BREAKING_CHANGES
+ warn_on_auto_comment_char = true;
+#endif /* !WITH_BREAKING_CHANGES */
prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 1113137a6f..c9288a9c7e 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -2389,7 +2389,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)
status = finish_command(&child);
if (status)
return "index-pack abnormal exit";
- reprepare_packed_git(the_repository);
+ odb_reprepare(the_repository->objects);
}
return NULL;
}
diff --git a/builtin/reflog.c b/builtin/reflog.c
index c8f6b93d60..dcbfe89339 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -418,6 +418,8 @@ static int cmd_reflog_write(int argc, const char **argv, const char *prefix,
const char *ref, *message;
int ret;
+ repo_config(repo, git_ident_config, NULL);
+
argc = parse_options(argc, argv, prefix, options, reflog_write_usage, 0);
if (argc != 4)
usage_with_options(reflog_write_usage, options);
diff --git a/builtin/refs.c b/builtin/refs.c
index 76224feba4..3064f888b2 100644
--- a/builtin/refs.c
+++ b/builtin/refs.c
@@ -2,11 +2,13 @@
#include "builtin.h"
#include "config.h"
#include "fsck.h"
+#include "pack-refs.h"
#include "parse-options.h"
#include "refs.h"
#include "strbuf.h"
#include "worktree.h"
#include "for-each-ref.h"
+#include "refs/refs-internal.h"
#define REFS_MIGRATE_USAGE \
N_("git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]")
@@ -14,6 +16,12 @@
#define REFS_VERIFY_USAGE \
N_("git refs verify [--strict] [--verbose]")
+#define REFS_EXISTS_USAGE \
+ N_("git refs exists <ref>")
+
+#define REFS_OPTIMIZE_USAGE \
+ N_("git refs optimize " PACK_REFS_OPTS)
+
static int cmd_refs_migrate(int argc, const char **argv, const char *prefix,
struct repository *repo UNUSED)
{
@@ -113,6 +121,59 @@ static int cmd_refs_list(int argc, const char **argv, const char *prefix,
return for_each_ref_core(argc, argv, prefix, repo, refs_list_usage);
}
+static int cmd_refs_exists(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
+{
+ struct strbuf unused_referent = STRBUF_INIT;
+ struct object_id unused_oid;
+ unsigned int unused_type;
+ int failure_errno = 0;
+ const char *ref;
+ int ret = 0;
+ const char * const exists_usage[] = {
+ REFS_EXISTS_USAGE,
+ NULL,
+ };
+ struct option options[] = {
+ OPT_END(),
+ };
+
+ argc = parse_options(argc, argv, prefix, options, exists_usage, 0);
+ if (argc != 1)
+ die(_("'git refs exists' requires a reference"));
+
+ ref = *argv++;
+ if (refs_read_raw_ref(get_main_ref_store(the_repository), ref,
+ &unused_oid, &unused_referent, &unused_type,
+ &failure_errno)) {
+ if (failure_errno == ENOENT || failure_errno == EISDIR) {
+ error(_("reference does not exist"));
+ ret = 2;
+ } else {
+ errno = failure_errno;
+ error_errno(_("failed to look up reference"));
+ ret = 1;
+ }
+
+ goto out;
+ }
+
+out:
+ strbuf_release(&unused_referent);
+ return ret;
+}
+
+static int cmd_refs_optimize(int argc, const char **argv, const char *prefix,
+ struct repository *repo)
+{
+ static char const * const refs_optimize_usage[] = {
+ REFS_OPTIMIZE_USAGE,
+ NULL
+ };
+
+ return pack_refs_core(argc, argv, prefix, repo, refs_optimize_usage);
+}
+
int cmd_refs(int argc,
const char **argv,
const char *prefix,
@@ -122,6 +183,8 @@ int cmd_refs(int argc,
REFS_MIGRATE_USAGE,
REFS_VERIFY_USAGE,
"git refs list " COMMON_USAGE_FOR_EACH_REF,
+ REFS_EXISTS_USAGE,
+ REFS_OPTIMIZE_USAGE,
NULL,
};
parse_opt_subcommand_fn *fn = NULL;
@@ -129,6 +192,8 @@ int cmd_refs(int argc,
OPT_SUBCOMMAND("migrate", &fn, cmd_refs_migrate),
OPT_SUBCOMMAND("verify", &fn, cmd_refs_verify),
OPT_SUBCOMMAND("list", &fn, cmd_refs_list),
+ OPT_SUBCOMMAND("exists", &fn, cmd_refs_exists),
+ OPT_SUBCOMMAND("optimize", &fn, cmd_refs_optimize),
OPT_END(),
};
diff --git a/builtin/repack.c b/builtin/repack.c
index a4def39197..e8730808c5 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -223,9 +223,10 @@ static void mark_packs_for_deletion(struct existing_packs *existing,
static void remove_redundant_pack(const char *dir_name, const char *base_name)
{
struct strbuf buf = STRBUF_INIT;
- struct multi_pack_index *m = get_multi_pack_index(the_repository->objects->sources);
+ struct odb_source *source = the_repository->objects->sources;
+ struct multi_pack_index *m = get_multi_pack_index(source);
strbuf_addf(&buf, "%s.pack", base_name);
- if (m && m->local && midx_contains_pack(m, buf.buf))
+ if (m && source->local && midx_contains_pack(m, buf.buf))
clear_midx_file(the_repository);
strbuf_insertf(&buf, 0, "%s/", dir_name);
unlink_pack_path(buf.buf, 1);
@@ -264,10 +265,11 @@ static void existing_packs_release(struct existing_packs *existing)
static void collect_pack_filenames(struct existing_packs *existing,
const struct string_list *extra_keep)
{
+ struct packfile_store *packs = the_repository->objects->packfiles;
struct packed_git *p;
struct strbuf buf = STRBUF_INIT;
- for (p = get_all_packs(the_repository); p; p = p->next) {
+ for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
int i;
const char *base;
@@ -496,10 +498,11 @@ static void init_pack_geometry(struct pack_geometry *geometry,
struct existing_packs *existing,
const struct pack_objects_args *args)
{
+ struct packfile_store *packs = the_repository->objects->packfiles;
struct packed_git *p;
struct strbuf buf = STRBUF_INIT;
- for (p = get_all_packs(the_repository); p; p = p->next) {
+ for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
if (args->local && !p->pack_local)
/*
* When asked to only repack local packfiles we skip
@@ -1136,11 +1139,12 @@ static int write_filtered_pack(const struct pack_objects_args *args,
static void combine_small_cruft_packs(FILE *in, size_t combine_cruft_below_size,
struct existing_packs *existing)
{
+ struct packfile_store *packs = the_repository->objects->packfiles;
struct packed_git *p;
struct strbuf buf = STRBUF_INIT;
size_t i;
- for (p = get_all_packs(the_repository); p; p = p->next) {
+ for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
if (!(p->is_cruft && p->pack_local))
continue;
@@ -1684,7 +1688,7 @@ int cmd_repack(int argc,
goto cleanup;
}
- reprepare_packed_git(the_repository);
+ odb_reprepare(the_repository->objects);
if (delete_redundant) {
int opts = 0;
@@ -1711,7 +1715,7 @@ int cmd_repack(int argc,
unsigned flags = 0;
if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL, 0))
flags |= MIDX_WRITE_INCREMENTAL;
- write_midx_file(the_repository, repo_get_object_directory(the_repository),
+ write_midx_file(the_repository->objects->sources,
NULL, NULL, flags);
}
diff --git a/builtin/repo.c b/builtin/repo.c
index 8c6e7f42ab..bbb0966f2d 100644
--- a/builtin/repo.c
+++ b/builtin/repo.c
@@ -9,7 +9,7 @@
#include "shallow.h"
static const char *const repo_usage[] = {
- "git repo info [--format=(keyvalue|nul)] [<key>...]",
+ "git repo info [--format=(keyvalue|nul)] [-z] [<key>...]",
NULL
};
@@ -38,6 +38,12 @@ static int get_layout_shallow(struct repository *repo, struct strbuf *buf)
return 0;
}
+static int get_object_format(struct repository *repo, struct strbuf *buf)
+{
+ strbuf_addstr(buf, repo->hash_algo->name);
+ return 0;
+}
+
static int get_references_format(struct repository *repo, struct strbuf *buf)
{
strbuf_addstr(buf,
@@ -49,6 +55,7 @@ static int get_references_format(struct repository *repo, struct strbuf *buf)
static const struct field repo_info_fields[] = {
{ "layout.bare", get_layout_bare },
{ "layout.shallow", get_layout_shallow },
+ { "object.format", get_object_format },
{ "references.format", get_references_format },
};
@@ -112,26 +119,40 @@ static int print_fields(int argc, const char **argv,
return ret;
}
+static int parse_format_cb(const struct option *opt,
+ const char *arg, int unset UNUSED)
+{
+ enum output_format *format = opt->value;
+
+ if (opt->short_name == 'z')
+ *format = FORMAT_NUL_TERMINATED;
+ else if (!strcmp(arg, "nul"))
+ *format = FORMAT_NUL_TERMINATED;
+ else if (!strcmp(arg, "keyvalue"))
+ *format = FORMAT_KEYVALUE;
+ else
+ die(_("invalid format '%s'"), arg);
+
+ return 0;
+}
+
static int repo_info(int argc, const char **argv, const char *prefix,
struct repository *repo)
{
- const char *format_str = "keyvalue";
- enum output_format format;
+ enum output_format format = FORMAT_KEYVALUE;
struct option options[] = {
- OPT_STRING(0, "format", &format_str, N_("format"),
- N_("output format")),
+ OPT_CALLBACK_F(0, "format", &format, N_("format"),
+ N_("output format"),
+ PARSE_OPT_NONEG, parse_format_cb),
+ OPT_CALLBACK_F('z', NULL, &format, NULL,
+ N_("synonym for --format=nul"),
+ PARSE_OPT_NONEG | PARSE_OPT_NOARG,
+ parse_format_cb),
OPT_END()
};
argc = parse_options(argc, argv, prefix, options, repo_usage, 0);
- if (!strcmp(format_str, "keyvalue"))
- format = FORMAT_KEYVALUE;
- else if (!strcmp(format_str, "nul"))
- format = FORMAT_NUL_TERMINATED;
- else
- die(_("invalid format '%s'"), format_str);
-
return print_fields(argc, argv, repo, format);
}
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 44ff1b8342..9da92b990d 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -708,7 +708,6 @@ int cmd_rev_parse(int argc,
struct object_id oid;
unsigned int flags = 0;
const char *name = NULL;
- struct object_context unused;
struct strbuf buf = STRBUF_INIT;
int seen_end_of_options = 0;
enum format_type format = FORMAT_DEFAULT;
@@ -1141,9 +1140,8 @@ int cmd_rev_parse(int argc,
name++;
type = REVERSED;
}
- if (!get_oid_with_context(the_repository, name,
- flags, &oid, &unused)) {
- object_context_release(&unused);
+ if (!repo_get_oid_with_flags(the_repository, name, &oid,
+ flags)) {
if (output_algo)
repo_oid_to_algop(the_repository, &oid,
output_algo, &oid);
@@ -1153,7 +1151,6 @@ int cmd_rev_parse(int argc,
show_rev(type, &oid, name);
continue;
}
- object_context_release(&unused);
if (verify)
die_no_single_rev(quiet);
if (has_dashdash)
diff --git a/builtin/revert.c b/builtin/revert.c
index c3f92b585d..bedc40f368 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -4,6 +4,7 @@
#include "builtin.h"
#include "parse-options.h"
#include "diff.h"
+#include "environment.h"
#include "gettext.h"
#include "revision.h"
#include "rerere.h"
@@ -285,6 +286,9 @@ int cmd_revert(int argc,
struct replay_opts opts = REPLAY_OPTS_INIT;
int res;
+#ifndef WITH_BREAKING_CHANGES
+ warn_on_auto_comment_char = true;
+#endif /* !WITH_BREAKING_CHANGES */
opts.action = REPLAY_REVERT;
sequencer_init_config(&opts);
res = run_sequencer(argc, argv, prefix, &opts);
@@ -302,6 +306,9 @@ struct repository *repo UNUSED)
struct replay_opts opts = REPLAY_OPTS_INIT;
int res;
+#ifndef WITH_BREAKING_CHANGES
+ warn_on_auto_comment_char = true;
+#endif /* !WITH_BREAKING_CHANGES */
opts.action = REPLAY_PICK;
sequencer_init_config(&opts);
res = run_sequencer(argc, argv, prefix, &opts);
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index 1ab7db9d2c..441babf2e3 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -29,7 +29,7 @@ static const char*const show_branch_usage[] = {
NULL
};
-static int showbranch_use_color = -1;
+static enum git_colorbool showbranch_use_color = GIT_COLOR_UNKNOWN;
static struct strvec default_args = STRVEC_INIT;
diff --git a/builtin/stash.c b/builtin/stash.c
index f5ddee5c7f..948eba06fb 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -146,6 +146,11 @@ static const char * const git_stash_import_usage[] = {
static const char ref_stash[] = "refs/stash";
static struct strbuf stash_index_path = STRBUF_INIT;
+static int show_stat = 1;
+static int show_patch;
+static int show_include_untracked;
+static int use_index;
+
/*
* w_commit is set to the commit containing the working tree
* b_commit is set to the base commit
@@ -377,7 +382,7 @@ static int diff_tree_binary(struct strbuf *out, struct object_id *w_commit)
* however it should be done together with apply_cached.
*/
cp.git_cmd = 1;
- strvec_pushl(&cp.args, "diff-tree", "--binary", NULL);
+ strvec_pushl(&cp.args, "diff-tree", "--binary", "--no-color", NULL);
strvec_pushf(&cp.args, "%s^2^..%s^2", w_commit_hex, w_commit_hex);
return pipe_command(&cp, NULL, 0, out, 0, NULL, 0);
@@ -717,7 +722,7 @@ static int apply_stash(int argc, const char **argv, const char *prefix,
{
int ret = -1;
int quiet = 0;
- int index = 0;
+ int index = use_index;
struct stash_info info = STASH_INFO_INIT;
struct option options[] = {
OPT__QUIET(&quiet, N_("be quiet, only report errors")),
@@ -815,7 +820,7 @@ static int pop_stash(int argc, const char **argv, const char *prefix,
struct repository *repo UNUSED)
{
int ret = -1;
- int index = 0;
+ int index = use_index;
int quiet = 0;
struct stash_info info = STASH_INFO_INIT;
struct option options[] = {
@@ -905,10 +910,6 @@ static int list_stash(int argc, const char **argv, const char *prefix,
return run_command(&cp);
}
-static int show_stat = 1;
-static int show_patch;
-static int show_include_untracked;
-
static int git_stash_config(const char *var, const char *value,
const struct config_context *ctx, void *cb)
{
@@ -924,6 +925,10 @@ static int git_stash_config(const char *var, const char *value,
show_include_untracked = git_config_bool(var, value);
return 0;
}
+ if (!strcmp(var, "stash.index")) {
+ use_index = git_config_bool(var, value);
+ return 0;
+ }
return git_diff_basic_config(var, value, ctx, cb);
}
@@ -1015,8 +1020,8 @@ static int show_stash(int argc, const char **argv, const char *prefix,
}
}
- argc = setup_revisions(revision_args.nr, revision_args.v, &rev, NULL);
- if (argc > 1)
+ setup_revisions_from_strvec(&revision_args, &rev, NULL);
+ if (revision_args.nr > 1)
goto usage;
if (!rev.diffopt.output_format) {
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
@@ -1089,7 +1094,6 @@ static int store_stash(int argc, const char **argv, const char *prefix,
int quiet = 0;
const char *stash_msg = NULL;
struct object_id obj;
- struct object_context dummy = {0};
struct option options[] = {
OPT__QUIET(&quiet, N_("be quiet")),
OPT_STRING('m', "message", &stash_msg, "message",
@@ -1109,9 +1113,8 @@ static int store_stash(int argc, const char **argv, const char *prefix,
return -1;
}
- if (get_oid_with_context(the_repository,
- argv[0], quiet ? GET_OID_QUIETLY : 0, &obj,
- &dummy)) {
+ if (repo_get_oid_with_flags(the_repository, argv[0], &obj,
+ quiet ? GET_OID_QUIETLY : 0)) {
if (!quiet)
fprintf_ln(stderr, _("Cannot update %s with %s"),
ref_stash, argv[0]);
@@ -1122,7 +1125,6 @@ static int store_stash(int argc, const char **argv, const char *prefix,
ret = do_store_stash(&obj, stash_msg, quiet);
out:
- object_context_release(&dummy);
return ret;
}
@@ -1284,6 +1286,7 @@ static int stash_staged(struct stash_info *info, struct strbuf *out_patch,
cp_diff_tree.git_cmd = 1;
strvec_pushl(&cp_diff_tree.args, "diff-tree", "-p", "--binary",
+ "--no-color",
"-U1", "HEAD", oid_to_hex(&info->w_tree), "--", NULL);
if (pipe_command(&cp_diff_tree, NULL, 0, out_patch, 0, NULL, 0)) {
ret = -1;
@@ -1346,6 +1349,7 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps,
cp_diff_tree.git_cmd = 1;
strvec_pushl(&cp_diff_tree.args, "diff-tree", "-p", "-U1", "HEAD",
+ "--no-color",
oid_to_hex(&info->w_tree), "--", NULL);
if (pipe_command(&cp_diff_tree, NULL, 0, out_patch, 0, NULL, 0)) {
ret = -1;
@@ -1720,6 +1724,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
cp_diff.git_cmd = 1;
strvec_pushl(&cp_diff.args, "diff-index", "-p",
+ "--no-color",
"--cached", "--binary", "HEAD", "--",
NULL);
add_pathspecs(&cp_diff.args, ps);
@@ -2235,7 +2240,6 @@ static int do_export_stash(struct repository *r,
const char **argv)
{
struct object_id base;
- struct object_context unused;
struct commit *prev;
struct commit_list *items = NULL, **iter = &items, *cur;
int res = 0;
@@ -2269,9 +2273,9 @@ static int do_export_stash(struct repository *r,
struct commit *stash;
if (parse_stash_revision(&revision, argv[i], 1) ||
- get_oid_with_context(r, revision.buf,
- GET_OID_QUIETLY | GET_OID_GENTLY,
- &oid, &unused)) {
+ repo_get_oid_with_flags(r, revision.buf, &oid,
+ GET_OID_QUIETLY |
+ GET_OID_GENTLY)) {
res = error(_("unable to find stash entry %s"), argv[i]);
goto out;
}
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 07a1935cbe..fcd73abe53 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -616,9 +616,6 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
struct rev_info rev = REV_INFO_INIT;
struct strbuf buf = STRBUF_INIT;
const char *git_dir;
- struct setup_revision_opt opt = {
- .free_removed_argv_elements = 1,
- };
if (validate_submodule_path(path) < 0)
die(NULL);
@@ -655,7 +652,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
repo_init_revisions(the_repository, &rev, NULL);
rev.abbrev = 0;
- setup_revisions(diff_files_args.nr, diff_files_args.v, &rev, &opt);
+ setup_revisions_from_strvec(&diff_files_args, &rev, NULL);
run_diff_files(&rev, 0);
if (!diff_result_code(&rev)) {
@@ -1094,9 +1091,6 @@ static int compute_summary_module_list(struct object_id *head_oid,
{
struct strvec diff_args = STRVEC_INIT;
struct rev_info rev;
- struct setup_revision_opt opt = {
- .free_removed_argv_elements = 1,
- };
struct module_cb_list list = MODULE_CB_LIST_INIT;
int ret = 0;
@@ -1114,7 +1108,7 @@ static int compute_summary_module_list(struct object_id *head_oid,
repo_init_revisions(the_repository, &rev, info->prefix);
rev.abbrev = 0;
precompose_argv_prefix(diff_args.nr, diff_args.v, NULL);
- setup_revisions(diff_args.nr, diff_args.v, &rev, &opt);
+ setup_revisions_from_strvec(&diff_args, &rev, NULL);
rev.diffopt.output_format = DIFF_FORMAT_NO_OUTPUT | DIFF_FORMAT_CALLBACK;
rev.diffopt.format_callback = submodule_summary_callback;
rev.diffopt.format_callback_data = &list;
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 7ae7c82b6c..ef79e43715 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -2,7 +2,6 @@
#define DISABLE_SIGN_COMPARE_WARNINGS
#include "builtin.h"
-#include "bulk-checkin.h"
#include "config.h"
#include "environment.h"
#include "gettext.h"
@@ -584,6 +583,7 @@ static void unpack_all(void)
{
int i;
unsigned char *hdr = fill(sizeof(struct pack_header));
+ struct odb_transaction *transaction;
if (get_be32(hdr) != PACK_SIGNATURE)
die("bad pack file");
@@ -599,12 +599,12 @@ static void unpack_all(void)
progress = start_progress(the_repository,
_("Unpacking objects"), nr_objects);
CALLOC_ARRAY(obj_list, nr_objects);
- begin_odb_transaction();
+ transaction = odb_transaction_begin(the_repository->objects);
for (i = 0; i < nr_objects; i++) {
unpack_one(i);
display_progress(progress, i + 1);
}
- end_odb_transaction();
+ odb_transaction_commit(transaction);
stop_progress(&progress);
if (delta_list)
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 2380f3ccd6..8a5907767b 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -8,7 +8,6 @@
#define DISABLE_SIGN_COMPARE_WARNINGS
#include "builtin.h"
-#include "bulk-checkin.h"
#include "config.h"
#include "environment.h"
#include "gettext.h"
@@ -19,6 +18,7 @@
#include "cache-tree.h"
#include "tree-walk.h"
#include "object-file.h"
+#include "odb.h"
#include "refs.h"
#include "resolve-undo.h"
#include "parse-options.h"
@@ -70,14 +70,6 @@ static void report(const char *fmt, ...)
if (!verbose)
return;
- /*
- * It is possible, though unlikely, that a caller could use the verbose
- * output to synchronize with addition of objects to the object
- * database. The current implementation of ODB transactions leaves
- * objects invisible while a transaction is active, so flush the
- * transaction here before reporting a change made by update-index.
- */
- flush_odb_transaction();
va_start(vp, fmt);
vprintf(fmt, vp);
putchar('\n');
@@ -940,6 +932,7 @@ int cmd_update_index(int argc,
strbuf_getline_fn getline_fn;
int parseopt_state = PARSE_OPT_UNKNOWN;
struct repository *r = the_repository;
+ struct odb_transaction *transaction;
struct option options[] = {
OPT_BIT('q', NULL, &refresh_args.flags,
N_("continue refresh even when index needs update"),
@@ -1130,7 +1123,7 @@ int cmd_update_index(int argc,
* Allow the object layer to optimize adding multiple objects in
* a batch.
*/
- begin_odb_transaction();
+ transaction = odb_transaction_begin(the_repository->objects);
while (ctx.argc) {
if (parseopt_state != PARSE_OPT_DONE)
parseopt_state = parse_options_step(&ctx, options,
@@ -1149,6 +1142,21 @@ int cmd_update_index(int argc,
const char *path = ctx.argv[0];
char *p;
+ /*
+ * It is possible, though unlikely, that a caller could
+ * use the verbose output to synchronize with addition
+ * of objects to the object database. The current
+ * implementation of ODB transactions leaves objects
+ * invisible while a transaction is active, so end the
+ * transaction here early before processing the next
+ * update. All further updates are performed outside of
+ * a transaction.
+ */
+ if (transaction && verbose) {
+ odb_transaction_commit(transaction);
+ transaction = NULL;
+ }
+
setup_work_tree();
p = prefix_path(prefix, prefix_length, path);
update_one(p);
@@ -1213,7 +1221,7 @@ int cmd_update_index(int argc,
/*
* By now we have added all of the new objects
*/
- end_odb_transaction();
+ odb_transaction_commit(transaction);
if (split_index > 0) {
if (repo_config_get_split_index(the_repository) == 0)