diff options
Diffstat (limited to 'builtin')
41 files changed, 520 insertions, 271 deletions
diff --git a/builtin/am.c b/builtin/am.c index 6273ea5195..2c19e69f58 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -32,6 +32,7 @@ #include "apply.h" #include "string-list.h" #include "packfile.h" +#include "repository.h" /** * Returns 1 if the file is empty or does not exist, 0 otherwise. @@ -1400,9 +1401,10 @@ static void write_index_patch(const struct am_state *state) FILE *fp; if (!get_oid_tree("HEAD", &head)) - tree = lookup_tree(&head); + tree = lookup_tree(the_repository, &head); else - tree = lookup_tree(the_hash_algo->empty_tree); + tree = lookup_tree(the_repository, + the_repository->hash_algo->empty_tree); fp = xfopen(am_path(state, "patch"), "w"); init_revisions(&rev_info, NULL); @@ -1631,7 +1633,8 @@ static void do_commit(const struct am_state *state) if (!get_oid_commit("HEAD", &parent)) { old_oid = &parent; - commit_list_insert(lookup_commit(&parent), &parents); + commit_list_insert(lookup_commit(the_repository, &parent), + &parents); } else { old_oid = NULL; say(state, stderr, _("applying to an empty history")); @@ -1763,7 +1766,7 @@ static void am_run(struct am_state *state, int resume) refresh_and_write_cache(); - if (index_has_changes(&sb)) { + if (index_has_changes(&the_index, NULL, &sb)) { write_state_bool(state, "dirtyindex", 1); die(_("Dirty index: cannot apply patches (dirty: %s)"), sb.buf); } @@ -1820,7 +1823,8 @@ static void am_run(struct am_state *state, int resume) * Applying the patch to an earlier tree and merging * the result may have produced the same tree as ours. */ - if (!apply_status && !index_has_changes(NULL)) { + if (!apply_status && + !index_has_changes(&the_index, NULL, NULL)) { say(state, stdout, _("No changes -- Patch already applied.")); goto next; } @@ -1874,7 +1878,7 @@ static void am_resolve(struct am_state *state) say(state, stdout, _("Applying: %.*s"), linelen(state->msg), state->msg); - if (!index_has_changes(NULL)) { + if (!index_has_changes(&the_index, NULL, NULL)) { printf_ln(_("No changes - did you forget to use 'git add'?\n" "If there is nothing left to stage, chances are that something else\n" "already introduced the same changes; you might want to skip this patch.")); diff --git a/builtin/blame.c b/builtin/blame.c index 921d127f29..5c93d169dd 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -1002,13 +1002,13 @@ parse_done: nth_line_cb, &sb, lno, anchor, &bottom, &top, sb.path)) usage(blame_usage); - if (lno < top || ((lno || bottom) && lno < bottom)) + if ((!lno && (top || bottom)) || lno < bottom) die(Q_("file %s has only %lu line", "file %s has only %lu lines", lno), path, lno); if (bottom < 1) bottom = 1; - if (top < 1) + if (top < 1 || lno < top) top = lno; bottom--; range_set_append_unsafe(&ranges, bottom, top); @@ -1071,7 +1071,9 @@ parse_done: find_alignment(&sb, &output_option); if (!*repeated_meta_color && (output_option & OUTPUT_COLOR_LINE)) - strcpy(repeated_meta_color, GIT_COLOR_CYAN); + xsnprintf(repeated_meta_color, + sizeof(repeated_meta_color), + "%s", GIT_COLOR_CYAN); } if (output_option & OUTPUT_ANNOTATE_COMPAT) output_option &= ~(OUTPUT_COLOR_LINE | OUTPUT_SHOW_AGE_WITH_COLOR); diff --git a/builtin/branch.c b/builtin/branch.c index 0192d4a879..4fc55c3508 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -122,7 +122,8 @@ static int branch_merged(int kind, const char *name, (reference_name = reference_name_to_free = resolve_refdup(upstream, RESOLVE_REF_READING, &oid, NULL)) != NULL) - reference_rev = lookup_commit_reference(&oid); + reference_rev = lookup_commit_reference(the_repository, + &oid); } if (!reference_rev) reference_rev = head_rev; @@ -155,7 +156,7 @@ static int check_branch_commit(const char *branchname, const char *refname, const struct object_id *oid, struct commit *head_rev, int kinds, int force) { - struct commit *rev = lookup_commit_reference(oid); + struct commit *rev = lookup_commit_reference(the_repository, oid); if (!rev) { error(_("Couldn't look up commit object for '%s'"), refname); return -1; @@ -209,7 +210,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds, } if (!force) { - head_rev = lookup_commit_reference(&head_oid); + head_rev = lookup_commit_reference(the_repository, &head_oid); if (!head_rev) die(_("Couldn't look up commit object for HEAD")); } diff --git a/builtin/checkout.c b/builtin/checkout.c index 28627650cd..516136a23a 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -23,6 +23,7 @@ #include "resolve-undo.h" #include "submodule-config.h" #include "submodule.h" +#include "advice.h" static const char * const checkout_usage[] = { N_("git checkout [<options>] <branch>"), @@ -78,7 +79,7 @@ static int update_some(const struct object_id *oid, struct strbuf *base, return READ_TREE_RECURSIVE; len = base->len + strlen(pathname); - ce = xcalloc(1, cache_entry_size(len)); + ce = make_empty_cache_entry(&the_index, len); oidcpy(&ce->oid, oid); memcpy(ce->name, base->buf, base->len); memcpy(ce->name + base->len, pathname, len - base->len); @@ -97,7 +98,7 @@ static int update_some(const struct object_id *oid, struct strbuf *base, if (ce->ce_mode == old->ce_mode && !oidcmp(&ce->oid, &old->oid)) { old->ce_flags |= CE_UPDATE; - free(ce); + discard_cache_entry(ce); return 0; } } @@ -231,11 +232,11 @@ static int checkout_merged(int pos, const struct checkout *state) if (write_object_file(result_buf.ptr, result_buf.size, blob_type, &oid)) die(_("Unable to add merge result for '%s'"), path); free(result_buf.ptr); - ce = make_cache_entry(mode, oid.hash, path, 2, 0); + ce = make_transient_cache_entry(mode, &oid, path, 2); if (!ce) die(_("make_cache_entry failed for path '%s'"), path); status = checkout_entry(ce, state, NULL); - free(ce); + discard_cache_entry(ce); return status; } @@ -379,7 +380,7 @@ static int checkout_paths(const struct checkout_opts *opts, die(_("unable to write new index file")); read_ref_full("HEAD", 0, &rev, NULL); - head = lookup_commit_reference_gently(&rev, 1); + head = lookup_commit_reference_gently(the_repository, &rev, 1); errs |= post_checkout_hook(head, head, 0); return errs; @@ -830,7 +831,7 @@ static int switch_branches(const struct checkout_opts *opts, memset(&old_branch_info, 0, sizeof(old_branch_info)); old_branch_info.path = path_to_free = resolve_refdup("HEAD", 0, &rev, &flag); if (old_branch_info.path) - old_branch_info.commit = lookup_commit_reference_gently(&rev, 1); + old_branch_info.commit = lookup_commit_reference_gently(the_repository, &rev, 1); if (!(flag & REF_ISSYMREF)) old_branch_info.path = NULL; @@ -879,7 +880,8 @@ static int parse_branchname_arg(int argc, const char **argv, int dwim_new_local_branch_ok, struct branch_info *new_branch_info, struct checkout_opts *opts, - struct object_id *rev) + struct object_id *rev, + int *dwim_remotes_matched) { struct tree **source_tree = &opts->source_tree; const char **new_branch = &opts->new_branch; @@ -911,8 +913,10 @@ static int parse_branchname_arg(int argc, const char **argv, * (b) If <something> is _not_ a commit, either "--" is present * or <something> is not a path, no -t or -b was given, and * and there is a tracking branch whose name is <something> - * in one and only one remote, then this is a short-hand to - * fork local <something> from that remote-tracking branch. + * in one and only one remote (or if the branch exists on the + * remote named in checkout.defaultRemote), then this is a + * short-hand to fork local <something> from that + * remote-tracking branch. * * (c) Otherwise, if "--" is present, treat it like case (1). * @@ -973,7 +977,8 @@ static int parse_branchname_arg(int argc, const char **argv, recover_with_dwim = 0; if (recover_with_dwim) { - const char *remote = unique_tracking_name(arg, rev); + const char *remote = unique_tracking_name(arg, rev, + dwim_remotes_matched); if (remote) { *new_branch = arg; arg = remote; @@ -1004,7 +1009,7 @@ static int parse_branchname_arg(int argc, const char **argv, else new_branch_info->path = NULL; /* not an existing branch */ - new_branch_info->commit = lookup_commit_reference_gently(rev, 1); + new_branch_info->commit = lookup_commit_reference_gently(the_repository, rev, 1); if (!new_branch_info->commit) { /* not a commit */ *source_tree = parse_tree_indirect(rev); @@ -1110,6 +1115,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) struct branch_info new_branch_info; char *conflict_style = NULL; int dwim_new_local_branch = 1; + int dwim_remotes_matched = 0; struct option options[] = { OPT__QUIET(&opts.quiet, N_("suppress progress reporting")), OPT_STRING('b', NULL, &opts.new_branch, N_("branch"), @@ -1222,7 +1228,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) opts.track == BRANCH_TRACK_UNSPECIFIED && !opts.new_branch; int n = parse_branchname_arg(argc, argv, dwim_ok, - &new_branch_info, &opts, &rev); + &new_branch_info, &opts, &rev, + &dwim_remotes_matched); argv += n; argc -= n; } @@ -1264,8 +1271,26 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) } UNLEAK(opts); - if (opts.patch_mode || opts.pathspec.nr) - return checkout_paths(&opts, new_branch_info.name); - else + if (opts.patch_mode || opts.pathspec.nr) { + int ret = checkout_paths(&opts, new_branch_info.name); + if (ret && dwim_remotes_matched > 1 && + advice_checkout_ambiguous_remote_branch_name) + advise(_("'%s' matched more than one remote tracking branch.\n" + "We found %d remotes with a reference that matched. So we fell back\n" + "on trying to resolve the argument as a path, but failed there too!\n" + "\n" + "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" + " git checkout --track origin/<name>\n" + "\n" + "If you'd like to always have checkouts of an ambiguous <name> prefer\n" + "one remote, e.g. the 'origin' remote, consider setting\n" + "checkout.defaultRemote=origin in your config."), + argv[0], + dwim_remotes_matched); + return ret; + } else { return checkout_branch(&opts, &new_branch_info); + } } diff --git a/builtin/clone.c b/builtin/clone.c index 1d939af9d8..9ebb5acf56 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -696,7 +696,8 @@ static void update_head(const struct ref *our, const struct ref *remote, install_branch_config(0, head, option_origin, our->name); } } else if (our) { - struct commit *c = lookup_commit_reference(&our->old_oid); + struct commit *c = lookup_commit_reference(the_repository, + &our->old_oid); /* --branch specifies a non-branch (i.e. tags), detach HEAD */ update_ref(msg, "HEAD", &c->object.oid, NULL, REF_NO_DEREF, UPDATE_REFS_DIE_ON_ERR); @@ -1156,7 +1157,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) } if (!is_local && !complete_refs_before_fetch) - transport_fetch_refs(transport, mapped_refs); + transport_fetch_refs(transport, mapped_refs, NULL); remote_head = find_ref_by_name(refs, "HEAD"); remote_head_points_at = @@ -1198,11 +1199,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (is_local) clone_local(path, git_dir); else if (refs && complete_refs_before_fetch) - transport_fetch_refs(transport, mapped_refs); + transport_fetch_refs(transport, mapped_refs, NULL); update_remote_refs(refs, mapped_refs, remote_head_points_at, branch_top.buf, reflog_msg.buf, transport, - !is_local && !filter_options.choice); + !is_local); update_head(our_head_points_at, remote_head, reflog_msg.buf); diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index 37420ae0fd..0bf0c48657 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -3,12 +3,19 @@ #include "dir.h" #include "lockfile.h" #include "parse-options.h" +#include "repository.h" #include "commit-graph.h" static char const * const builtin_commit_graph_usage[] = { N_("git commit-graph [--object-dir <objdir>]"), N_("git commit-graph read [--object-dir <objdir>]"), - N_("git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--stdin-commits]"), + N_("git commit-graph verify [--object-dir <objdir>]"), + N_("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits]"), + NULL +}; + +static const char * const builtin_commit_graph_verify_usage[] = { + N_("git commit-graph verify [--object-dir <objdir>]"), NULL }; @@ -18,17 +25,48 @@ static const char * const builtin_commit_graph_read_usage[] = { }; static const char * const builtin_commit_graph_write_usage[] = { - N_("git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--stdin-commits]"), + N_("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits]"), NULL }; static struct opts_commit_graph { const char *obj_dir; + int reachable; int stdin_packs; int stdin_commits; int append; } opts; + +static int graph_verify(int argc, const char **argv) +{ + struct commit_graph *graph = NULL; + char *graph_name; + + 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_END(), + }; + + argc = parse_options(argc, argv, NULL, + builtin_commit_graph_verify_options, + builtin_commit_graph_verify_usage, 0); + + if (!opts.obj_dir) + opts.obj_dir = get_object_directory(); + + graph_name = get_commit_graph_filename(opts.obj_dir); + graph = load_commit_graph_one(graph_name); + FREE_AND_NULL(graph_name); + + if (!graph) + return 0; + + return verify_commit_graph(the_repository, graph); +} + static int graph_read(int argc, const char **argv) { struct commit_graph *graph = NULL; @@ -51,8 +89,11 @@ static int graph_read(int argc, const char **argv) graph_name = get_commit_graph_filename(opts.obj_dir); graph = load_commit_graph_one(graph_name); - if (!graph) + if (!graph) { + UNLEAK(graph_name); die("graph file %s does not exist", graph_name); + } + FREE_AND_NULL(graph_name); printf("header: %08x %d %d %d %d\n", @@ -74,23 +115,23 @@ static int graph_read(int argc, const char **argv) printf(" large_edges"); printf("\n"); + free_commit_graph(graph); + return 0; } static int graph_write(int argc, const char **argv) { - const char **pack_indexes = NULL; - int packs_nr = 0; - const char **commit_hex = NULL; - int commits_nr = 0; - const char **lines = NULL; - int lines_nr = 0; - int lines_alloc = 0; + struct string_list *pack_indexes = NULL; + struct string_list *commit_hex = NULL; + struct string_list lines; 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, N_("scan pack-indexes listed by stdin for commits")), OPT_BOOL(0, "stdin-commits", &opts.stdin_commits, @@ -104,39 +145,35 @@ static int graph_write(int argc, const char **argv) builtin_commit_graph_write_options, builtin_commit_graph_write_usage, 0); - if (opts.stdin_packs && opts.stdin_commits) - die(_("cannot use both --stdin-commits and --stdin-packs")); + if (opts.reachable + opts.stdin_packs + opts.stdin_commits > 1) + die(_("use at most one of --reachable, --stdin-commits, or --stdin-packs")); if (!opts.obj_dir) opts.obj_dir = get_object_directory(); + if (opts.reachable) { + write_commit_graph_reachable(opts.obj_dir, opts.append); + return 0; + } + + string_list_init(&lines, 0); if (opts.stdin_packs || opts.stdin_commits) { struct strbuf buf = STRBUF_INIT; - lines_nr = 0; - lines_alloc = 128; - ALLOC_ARRAY(lines, lines_alloc); - - while (strbuf_getline(&buf, stdin) != EOF) { - ALLOC_GROW(lines, lines_nr + 1, lines_alloc); - lines[lines_nr++] = strbuf_detach(&buf, NULL); - } - - if (opts.stdin_packs) { - pack_indexes = lines; - packs_nr = lines_nr; - } - if (opts.stdin_commits) { - commit_hex = lines; - commits_nr = lines_nr; - } + + while (strbuf_getline(&buf, stdin) != EOF) + string_list_append(&lines, strbuf_detach(&buf, NULL)); + + if (opts.stdin_packs) + pack_indexes = &lines; + if (opts.stdin_commits) + commit_hex = &lines; } write_commit_graph(opts.obj_dir, pack_indexes, - packs_nr, commit_hex, - commits_nr, opts.append); + string_list_clear(&lines, 0); return 0; } @@ -162,6 +199,8 @@ int cmd_commit_graph(int argc, const char **argv, const char *prefix) if (argc > 0) { if (!strcmp(argv[0], "read")) return graph_read(argc, argv); + if (!strcmp(argv[0], "verify")) + return graph_verify(argc, argv); if (!strcmp(argv[0], "write")) return graph_write(argc, argv); } diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index 9fbd3529fb..9ec36a82b6 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -6,6 +6,7 @@ #include "cache.h" #include "config.h" #include "object-store.h" +#include "repository.h" #include "commit.h" #include "tree.h" #include "builtin.h" @@ -60,7 +61,8 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix) if (get_oid_commit(argv[i], &oid)) die("Not a valid object name %s", argv[i]); assert_oid_type(&oid, OBJ_COMMIT); - new_parent(lookup_commit(&oid), &parents); + new_parent(lookup_commit(the_repository, &oid), + &parents); continue; } diff --git a/builtin/config.c b/builtin/config.c index b29d26dede..2c93a289a7 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -67,7 +67,7 @@ static int show_origin; { OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \ PARSE_OPT_NONEG, option_parse_type, (i) } -static struct option builtin_config_options[]; +static NORETURN void usage_builtin_config(void); static int option_parse_type(const struct option *opt, const char *arg, int unset) @@ -111,8 +111,7 @@ static int option_parse_type(const struct option *opt, const char *arg, * --type=int'. */ error("only one type at a time."); - usage_with_options(builtin_config_usage, - builtin_config_options); + usage_builtin_config(); } *to_type = new_type; @@ -157,11 +156,16 @@ static struct option builtin_config_options[] = { OPT_END(), }; +static NORETURN void usage_builtin_config(void) +{ + usage_with_options(builtin_config_usage, builtin_config_options); +} + static void check_argc(int argc, int min, int max) { if (argc >= min && argc <= max) return; error("wrong number of arguments"); - usage_with_options(builtin_config_usage, builtin_config_options); + usage_builtin_config(); } static void show_config_origin(struct strbuf *buf) @@ -596,7 +600,7 @@ int cmd_config(int argc, const char **argv, const char *prefix) if (use_global_config + use_system_config + use_local_config + !!given_config_source.file + !!given_config_source.blob > 1) { error("only one config file at a time."); - usage_with_options(builtin_config_usage, builtin_config_options); + usage_builtin_config(); } if (use_local_config && nongit) @@ -660,12 +664,12 @@ int cmd_config(int argc, const char **argv, const char *prefix) if ((actions & (ACTION_GET_COLOR|ACTION_GET_COLORBOOL)) && type) { error("--get-color and variable type are incoherent"); - usage_with_options(builtin_config_usage, builtin_config_options); + usage_builtin_config(); } if (HAS_MULTI_BITS(actions)) { error("only one action at a time."); - usage_with_options(builtin_config_usage, builtin_config_options); + usage_builtin_config(); } if (actions == 0) switch (argc) { @@ -673,25 +677,24 @@ int cmd_config(int argc, const char **argv, const char *prefix) case 2: actions = ACTION_SET; break; case 3: actions = ACTION_SET_ALL; break; default: - usage_with_options(builtin_config_usage, builtin_config_options); + usage_builtin_config(); } if (omit_values && !(actions == ACTION_LIST || actions == ACTION_GET_REGEXP)) { error("--name-only is only applicable to --list or --get-regexp"); - usage_with_options(builtin_config_usage, builtin_config_options); + usage_builtin_config(); } if (show_origin && !(actions & (ACTION_GET|ACTION_GET_ALL|ACTION_GET_REGEXP|ACTION_LIST))) { error("--show-origin is only applicable to --get, --get-all, " "--get-regexp, and --list."); - usage_with_options(builtin_config_usage, builtin_config_options); + usage_builtin_config(); } if (default_value && !(actions & ACTION_GET)) { error("--default is only applicable to --get"); - usage_with_options(builtin_config_usage, - builtin_config_options); + usage_builtin_config(); } if (actions & PAGING_ACTIONS) diff --git a/builtin/describe.c b/builtin/describe.c index 1e87f68d5e..41606c8a90 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -93,13 +93,13 @@ static int replace_name(struct commit_name *e, struct tag *t; if (!e->tag) { - t = lookup_tag(&e->oid); + t = lookup_tag(the_repository, &e->oid); if (!t || parse_tag(t)) return 1; e->tag = t; } - t = lookup_tag(oid); + t = lookup_tag(the_repository, oid); if (!t || parse_tag(t)) return 0; *tag = t; @@ -267,7 +267,7 @@ static unsigned long finish_depth_computation( static void append_name(struct commit_name *n, struct strbuf *dst) { if (n->prio == 2 && !n->tag) { - n->tag = lookup_tag(&n->oid); + n->tag = lookup_tag(the_repository, &n->oid); if (!n->tag || parse_tag(n->tag)) die(_("annotated tag %s not available"), n->path); } @@ -303,7 +303,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) unsigned long seen_commits = 0; unsigned int unannotated_cnt = 0; - cmit = lookup_commit_reference(oid); + cmit = lookup_commit_reference(the_repository, oid); n = find_commit_name(&cmit->object.oid); if (n && (tags || all || n->prio == 2)) { @@ -331,7 +331,8 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) init_commit_names(&commit_names); n = hashmap_iter_first(&names, &iter); for (; n; n = hashmap_iter_next(&iter)) { - c = lookup_commit_reference_gently(&n->peeled, 1); + c = lookup_commit_reference_gently(the_repository, + &n->peeled, 1); if (c) *commit_names_at(&commit_names, c) = n; } @@ -509,7 +510,7 @@ static void describe(const char *arg, int last_one) if (get_oid(arg, &oid)) die(_("Not a valid object name %s"), arg); - cmit = lookup_commit_reference_gently(&oid, 1); + cmit = lookup_commit_reference_gently(the_repository, &oid, 1); if (cmit) describe_commit(&oid, &sb); diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index 473615117e..91ba67070e 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -5,12 +5,13 @@ #include "log-tree.h" #include "builtin.h" #include "submodule.h" +#include "repository.h" static struct rev_info log_tree_opt; static int diff_tree_commit_oid(const struct object_id *oid) { - struct commit *commit = lookup_commit_reference(oid); + struct commit *commit = lookup_commit_reference(the_repository, oid); if (!commit) return -1; return log_tree_commit(&log_tree_opt, commit); @@ -24,7 +25,7 @@ static int stdin_diff_commit(struct commit *commit, const char *p) /* Graft the fake parents locally to the commit */ while (isspace(*p++) && !parse_oid_hex(p, &oid, &p)) { - struct commit *parent = lookup_commit(&oid); + struct commit *parent = lookup_commit(the_repository, &oid); if (!pptr) { /* Free the real parent list */ free_commit_list(commit->parents); @@ -45,7 +46,7 @@ static int stdin_diff_trees(struct tree *tree1, const char *p) struct tree *tree2; if (!isspace(*p++) || parse_oid_hex(p, &oid, &p) || *p) return error("Need exactly two trees, separated by a space"); - tree2 = lookup_tree(&oid); + tree2 = lookup_tree(the_repository, &oid); if (!tree2 || parse_tree(tree2)) return -1; printf("%s %s\n", oid_to_hex(&tree1->object.oid), @@ -68,7 +69,7 @@ static int diff_tree_stdin(char *line) line[len-1] = 0; if (parse_oid_hex(line, &oid, &p)) return -1; - obj = parse_object(&oid); + obj = parse_object(the_repository, &oid); if (!obj) return -1; if (obj->type == OBJ_COMMIT) diff --git a/builtin/diff.c b/builtin/diff.c index b709b6e984..361a3c3ed3 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -386,7 +386,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix) add_head_to_pending(&rev); if (!rev.pending.nr) { struct tree *tree; - tree = lookup_tree(the_hash_algo->empty_tree); + tree = lookup_tree(the_repository, + the_repository->hash_algo->empty_tree); add_pending_object(&rev, &tree->object, "HEAD"); } break; @@ -400,8 +401,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix) const char *name = entry->name; int flags = (obj->flags & UNINTERESTING); if (!obj->parsed) - obj = parse_object(&obj->oid); - obj = deref_tag(obj, NULL, 0); + obj = parse_object(the_repository, &obj->oid); + obj = deref_tag(the_repository, obj, NULL, 0); if (!obj) die(_("invalid object '%s' given."), name); if (obj->type == OBJ_COMMIT) diff --git a/builtin/difftool.c b/builtin/difftool.c index 51f6c9cdb4..3018e61d04 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -322,10 +322,10 @@ static int checkout_path(unsigned mode, struct object_id *oid, struct cache_entry *ce; int ret; - ce = make_cache_entry(mode, oid->hash, path, 0, 0); + ce = make_transient_cache_entry(mode, oid, path, 0); ret = checkout_entry(ce, state, NULL); - free(ce); + discard_cache_entry(ce); return ret; } @@ -489,7 +489,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, * index. */ struct cache_entry *ce2 = - make_cache_entry(rmode, roid.hash, + make_cache_entry(&wtindex, rmode, &roid, dst_path, 0, 0); add_index_entry(&wtindex, ce2, diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 9ee6a4d2e8..223499d7ca 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -230,13 +230,13 @@ static void export_blob(const struct object_id *oid) if (is_null_oid(oid)) return; - object = lookup_object(oid->hash); + object = lookup_object(the_repository, oid->hash); if (object && object->flags & SHOWN) return; if (anonymize) { buf = anonymize_blob(&size); - object = (struct object *)lookup_blob(oid); + object = (struct object *)lookup_blob(the_repository, oid); eaten = 0; } else { buf = read_object_file(oid, &type, &size); @@ -244,7 +244,8 @@ static void export_blob(const struct object_id *oid) die ("Could not read blob %s", oid_to_hex(oid)); if (check_object_signature(oid, buf, size, type_name(type)) < 0) die("sha1 mismatch in blob %s", oid_to_hex(oid)); - object = parse_object_buffer(oid, type, size, buf, &eaten); + object = parse_object_buffer(the_repository, oid, type, + size, buf, &eaten); } if (!object) @@ -402,7 +403,8 @@ static void show_filemodify(struct diff_queue_struct *q, anonymize_sha1(&spec->oid) : spec->oid.hash)); else { - struct object *object = lookup_object(spec->oid.hash); + struct object *object = lookup_object(the_repository, + spec->oid.hash); printf("M %06o :%d ", spec->mode, get_object_mark(object)); } @@ -801,7 +803,7 @@ static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name) /* handle nested tags */ while (tag && tag->object.type == OBJ_TAG) { - parse_object(&tag->object.oid); + parse_object(the_repository, &tag->object.oid); string_list_append(&extra_refs, full_name)->util = tag; tag = (struct tag *)tag->tagged; } @@ -961,7 +963,7 @@ static void import_marks(char *input_file) /* only commits */ continue; - commit = lookup_commit(&oid); + commit = lookup_commit(the_repository, &oid); if (!commit) die("not a commit? can't happen: %s", oid_to_hex(&oid)); diff --git a/builtin/fetch.c b/builtin/fetch.c index d9bb72bf49..34d2bd123b 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -64,6 +64,7 @@ static int shown_url = 0; static struct refspec refmap = REFSPEC_INIT_FETCH; static struct list_objects_filter_options filter_options; static struct string_list server_options = STRING_LIST_INIT_DUP; +static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP; static int git_fetch_config(const char *k, const char *v, void *cb) { @@ -162,6 +163,8 @@ static struct option builtin_fetch_options[] = { TRANSPORT_FAMILY_IPV4), OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"), TRANSPORT_FAMILY_IPV6), + OPT_STRING_LIST(0, "negotiation-tip", &negotiation_tip, N_("revision"), + N_("report that we have only objects reachable from this object")), OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options), OPT_END() }; @@ -242,9 +245,9 @@ static int will_fetch(struct ref **head, const unsigned char *sha1) return 0; } -static void find_non_local_tags(struct transport *transport, - struct ref **head, - struct ref ***tail) +static void find_non_local_tags(const struct ref *refs, + struct ref **head, + struct ref ***tail) { struct string_list existing_refs = STRING_LIST_INIT_DUP; struct string_list remote_refs = STRING_LIST_INIT_NODUP; @@ -252,7 +255,7 @@ static void find_non_local_tags(struct transport *transport, struct string_list_item *item = NULL; for_each_ref(add_existing, &existing_refs); - for (ref = transport_get_remote_refs(transport, NULL); ref; ref = ref->next) { + for (ref = refs; ref; ref = ref->next) { if (!starts_with(ref->name, "refs/tags/")) continue; @@ -326,7 +329,8 @@ static void find_non_local_tags(struct transport *transport, string_list_clear(&remote_refs, 0); } -static struct ref *get_ref_map(struct transport *transport, +static struct ref *get_ref_map(struct remote *remote, + const struct ref *remote_refs, struct refspec *rs, int tags, int *autotags) { @@ -334,26 +338,11 @@ static struct ref *get_ref_map(struct transport *transport, struct ref *rm; struct ref *ref_map = NULL; struct ref **tail = &ref_map; - struct argv_array ref_prefixes = ARGV_ARRAY_INIT; /* opportunistically-updated references: */ struct ref *orefs = NULL, **oref_tail = &orefs; - const struct ref *remote_refs; - - if (rs->nr) - refspec_ref_prefixes(rs, &ref_prefixes); - else if (transport->remote && transport->remote->fetch.nr) - refspec_ref_prefixes(&transport->remote->fetch, &ref_prefixes); - - if (ref_prefixes.argc && - (tags == TAGS_SET || (tags == TAGS_DEFAULT && !rs->nr))) { - argv_array_push(&ref_prefixes, "refs/tags/"); - } - - remote_refs = transport_get_remote_refs(transport, &ref_prefixes); - - argv_array_clear(&ref_prefixes); + struct string_list existing_refs = STRING_LIST_INIT_DUP; if (rs->nr) { struct refspec *fetch_refspec; @@ -390,7 +379,7 @@ static struct ref *get_ref_map(struct transport *transport, if (refmap.nr) fetch_refspec = &refmap; else - fetch_refspec = &transport->remote->fetch; + fetch_refspec = &remote->fetch; for (i = 0; i < fetch_refspec->nr; i++) get_fetch_map(ref_map, &fetch_refspec->items[i], &oref_tail, 1); @@ -398,7 +387,6 @@ static struct ref *get_ref_map(struct transport *transport, die("--refmap option is only meaningful with command-line refspec(s)."); } else { /* Use the defaults */ - struct remote *remote = transport->remote; struct branch *branch = branch_get(NULL); int has_merge = branch_has_merge_config(branch); if (remote && @@ -437,7 +425,7 @@ static struct ref *get_ref_map(struct transport *transport, /* also fetch all tags */ get_fetch_map(remote_refs, tag_refspec, &tail, 0); else if (tags == TAGS_DEFAULT && *autotags) - find_non_local_tags(transport, &ref_map, &tail); + find_non_local_tags(remote_refs, &ref_map, &tail); /* Now append any refs to be updated opportunistically: */ *tail = orefs; @@ -446,7 +434,23 @@ static struct ref *get_ref_map(struct transport *transport, tail = &rm->next; } - return ref_remove_duplicates(ref_map); + ref_map = ref_remove_duplicates(ref_map); + + for_each_ref(add_existing, &existing_refs); + for (rm = ref_map; rm; rm = rm->next) { + if (rm->peer_ref) { + struct string_list_item *peer_item = + string_list_lookup(&existing_refs, + rm->peer_ref->name); + if (peer_item) { + struct object_id *old_oid = peer_item->util; + oidcpy(&rm->peer_ref->old_oid, old_oid); + } + } + } + string_list_clear(&existing_refs, 1); + + return ref_map; } #define STORE_REF_ERROR_OTHER 1 @@ -671,8 +675,10 @@ static int update_local_ref(struct ref *ref, return r; } - current = lookup_commit_reference_gently(&ref->old_oid, 1); - updated = lookup_commit_reference_gently(&ref->new_oid, 1); + current = lookup_commit_reference_gently(the_repository, + &ref->old_oid, 1); + updated = lookup_commit_reference_gently(the_repository, + &ref->new_oid, 1); if (!current || !updated) { const char *msg; const char *what; @@ -756,7 +762,7 @@ static int iterate_ref_map(void *cb_data, struct object_id *oid) } static int store_updated_refs(const char *raw_url, const char *remote_name, - struct ref *ref_map) + int connectivity_checked, struct ref *ref_map) { FILE *fp; struct commit *commit; @@ -778,10 +784,12 @@ static int store_updated_refs(const char *raw_url, const char *remote_name, else url = xstrdup("foreign"); - rm = ref_map; - if (check_connected(iterate_ref_map, &rm, NULL)) { - rc = error(_("%s did not send all necessary objects\n"), url); - goto abort; + if (!connectivity_checked) { + rm = ref_map; + if (check_connected(iterate_ref_map, &rm, NULL)) { + rc = error(_("%s did not send all necessary objects\n"), url); + goto abort; + } } prepare_format_display(ref_map); @@ -805,7 +813,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name, continue; } - commit = lookup_commit_reference_gently(&rm->old_oid, + commit = lookup_commit_reference_gently(the_repository, + &rm->old_oid, 1); if (!commit) rm->fetch_head_status = FETCH_HEAD_NOT_FOR_MERGE; @@ -933,15 +942,32 @@ static int quickfetch(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_refs(struct transport *transport, struct ref *ref_map, + struct ref **updated_remote_refs) { int ret = quickfetch(ref_map); if (ret) - ret = transport_fetch_refs(transport, ref_map); + ret = transport_fetch_refs(transport, ref_map, + updated_remote_refs); if (!ret) - ret |= store_updated_refs(transport->url, - transport->remote->name, - ref_map); + /* + * 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 = store_updated_refs(transport->url, + transport->remote->name, + connectivity_checked, + ref_map); transport_unlock_pack(transport); return ret; } @@ -1037,6 +1063,40 @@ static void set_option(struct transport *transport, const char *name, const char name, transport->url); } + +static int add_oid(const char *refname, const struct object_id *oid, int flags, + void *cb_data) +{ + struct oid_array *oids = cb_data; + + oid_array_append(oids, oid); + return 0; +} + +static void add_negotiation_tips(struct git_transport_options *smart_options) +{ + struct oid_array *oids = xcalloc(1, sizeof(*oids)); + int i; + + for (i = 0; i < negotiation_tip.nr; i++) { + const char *s = negotiation_tip.items[i].string; + int old_nr; + if (!has_glob_specials(s)) { + struct object_id oid; + if (get_oid(s, &oid)) + die("%s is not a valid object", s); + oid_array_append(oids, &oid); + continue; + } + old_nr = oids->nr; + for_each_glob_ref(add_oid, s, oids); + if (old_nr == oids->nr) + warning("Ignoring --negotiation-tip=%s because it does not match any refs", + s); + } + smart_options->negotiation_tips = oids; +} + static struct transport *prepare_transport(struct remote *remote, int deepen) { struct transport *transport; @@ -1063,6 +1123,12 @@ static struct transport *prepare_transport(struct remote *remote, int deepen) filter_options.filter_spec); set_option(transport, TRANS_OPT_FROM_PROMISOR, "1"); } + if (negotiation_tip.nr) { + if (transport->smart_options) + add_negotiation_tips(transport->smart_options); + else + warning("Ignoring --negotiation-tip because the protocol does not support it."); + } return transport; } @@ -1087,7 +1153,8 @@ 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); - fetch_refs(transport, ref_map); + if (!fetch_refs(transport, ref_map, NULL)) + consume_refs(transport, ref_map); if (gsecondary) { transport_disconnect(gsecondary); @@ -1098,13 +1165,12 @@ static void backfill_tags(struct transport *transport, struct ref *ref_map) static int do_fetch(struct transport *transport, struct refspec *rs) { - struct string_list existing_refs = STRING_LIST_INIT_DUP; struct ref *ref_map; - struct ref *rm; int autotags = (transport->remote->fetch_tags == 1); int retcode = 0; - - for_each_ref(add_existing, &existing_refs); + const struct ref *remote_refs; + struct ref *updated_remote_refs = NULL; + struct argv_array ref_prefixes = ARGV_ARRAY_INIT; if (tags == TAGS_DEFAULT) { if (transport->remote->fetch_tags == 2) @@ -1120,22 +1186,24 @@ static int do_fetch(struct transport *transport, goto cleanup; } - ref_map = get_ref_map(transport, rs, tags, &autotags); - if (!update_head_ok) - check_not_current_branch(ref_map); + if (rs->nr) + refspec_ref_prefixes(rs, &ref_prefixes); + else if (transport->remote && transport->remote->fetch.nr) + refspec_ref_prefixes(&transport->remote->fetch, &ref_prefixes); - for (rm = ref_map; rm; rm = rm->next) { - if (rm->peer_ref) { - struct string_list_item *peer_item = - string_list_lookup(&existing_refs, - rm->peer_ref->name); - if (peer_item) { - struct object_id *old_oid = peer_item->util; - oidcpy(&rm->peer_ref->old_oid, old_oid); - } - } + if (ref_prefixes.argc && + (tags == TAGS_SET || (tags == TAGS_DEFAULT && !rs->nr))) { + argv_array_push(&ref_prefixes, "refs/tags/"); } + remote_refs = transport_get_remote_refs(transport, &ref_prefixes); + argv_array_clear(&ref_prefixes); + + ref_map = get_ref_map(transport->remote, remote_refs, rs, + tags, &autotags); + if (!update_head_ok) + check_not_current_branch(ref_map); + if (tags == TAGS_DEFAULT && autotags) transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1"); if (prune) { @@ -1152,7 +1220,24 @@ static int do_fetch(struct transport *transport, transport->url); } } - if (fetch_refs(transport, ref_map)) { + + if (fetch_refs(transport, ref_map, &updated_remote_refs)) { + free_refs(ref_map); + retcode = 1; + goto cleanup; + } + if (updated_remote_refs) { + /* + * Regenerate ref_map using the updated remote refs. This is + * to account for additional information which may be provided + * by the transport (e.g. shallow info). + */ + free_refs(ref_map); + ref_map = get_ref_map(transport->remote, updated_remote_refs, rs, + tags, &autotags); + free_refs(updated_remote_refs); + } + if (consume_refs(transport, ref_map)) { free_refs(ref_map); retcode = 1; goto cleanup; @@ -1164,14 +1249,13 @@ static int do_fetch(struct transport *transport, if (tags == TAGS_DEFAULT && autotags) { struct ref **tail = &ref_map; ref_map = NULL; - find_non_local_tags(transport, &ref_map, &tail); + find_non_local_tags(remote_refs, &ref_map, &tail); if (ref_map) backfill_tags(transport, ref_map); free_refs(ref_map); } cleanup: - string_list_clear(&existing_refs, 1); return retcode; } diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c index 1b526adb3a..ca9206fbbe 100644 --- a/builtin/fmt-merge-msg.c +++ b/builtin/fmt-merge-msg.c @@ -11,6 +11,7 @@ #include "branch.h" #include "fmt-merge-msg.h" #include "gpg-interface.h" +#include "repository.h" static const char * const fmt_merge_msg_usage[] = { N_("git fmt-merge-msg [-m <message>] [--log[=<n>] | --no-log] [--file <file>]"), @@ -109,14 +110,15 @@ static int handle_line(char *line, struct merge_parents *merge_parents) struct string_list_item *item; int pulling_head = 0; struct object_id oid; + const unsigned hexsz = the_hash_algo->hexsz; - if (len < GIT_SHA1_HEXSZ + 3 || line[GIT_SHA1_HEXSZ] != '\t') + if (len < hexsz + 3 || line[hexsz] != '\t') return 1; - if (starts_with(line + GIT_SHA1_HEXSZ + 1, "not-for-merge")) + if (starts_with(line + hexsz + 1, "not-for-merge")) return 0; - if (line[GIT_SHA1_HEXSZ + 1] != '\t') + if (line[hexsz + 1] != '\t') return 2; i = get_oid_hex(line, &oid); @@ -131,7 +133,7 @@ static int handle_line(char *line, struct merge_parents *merge_parents) if (line[len - 1] == '\n') line[len - 1] = 0; - line += GIT_SHA1_HEXSZ + 2; + line += hexsz + 2; /* * At this point, line points at the beginning of comment e.g. @@ -343,7 +345,9 @@ static void shortlog(const char *name, const struct object_id *oid = &origin_data->oid; int limit = opts->shortlog_len; - branch = deref_tag(parse_object(oid), oid_to_hex(oid), GIT_SHA1_HEXSZ); + branch = deref_tag(the_repository, parse_object(the_repository, oid), + oid_to_hex(oid), + the_hash_algo->hexsz); if (!branch || branch->type != OBJ_COMMIT) return; @@ -546,6 +550,7 @@ static void find_merge_parents(struct merge_parents *result, int len; char *p = in->buf + pos; char *newline = strchr(p, '\n'); + const char *q; struct object_id oid; struct commit *parent; struct object *obj; @@ -553,24 +558,23 @@ static void find_merge_parents(struct merge_parents *result, len = newline ? newline - p : strlen(p); pos += len + !!newline; - if (len < GIT_SHA1_HEXSZ + 3 || - get_oid_hex(p, &oid) || - p[GIT_SHA1_HEXSZ] != '\t' || - p[GIT_SHA1_HEXSZ + 1] != '\t') + if (parse_oid_hex(p, &oid, &q) || + q[0] != '\t' || + q[1] != '\t') continue; /* skip not-for-merge */ /* * Do not use get_merge_parent() here; we do not have * "name" here and we do not want to contaminate its * util field yet. */ - obj = parse_object(&oid); + obj = parse_object(the_repository, &oid); parent = (struct commit *)peel_to_type(NULL, 0, obj, OBJ_COMMIT); if (!parent) continue; commit_list_insert(parent, &parents); add_merge_parent(result, &obj->oid, &parent->object.oid); } - head_commit = lookup_commit(head); + head_commit = lookup_commit(the_repository, head); if (head_commit) commit_list_insert(head_commit, &parents); reduce_heads_replace(&parents); diff --git a/builtin/fsck.c b/builtin/fsck.c index 3ad4f160f9..c96f3f4fcc 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -18,6 +18,7 @@ #include "decorate.h" #include "packfile.h" #include "object-store.h" +#include "run-command.h" #define REACHABLE 0x0001 #define SEEN 0x0002 @@ -47,6 +48,7 @@ static int name_objects; #define ERROR_REACHABLE 02 #define ERROR_PACK 04 #define ERROR_REFS 010 +#define ERROR_COMMIT_GRAPH 020 static const char *describe_object(struct object *obj) { @@ -70,7 +72,7 @@ static const char *printable_type(struct object *obj) enum object_type type = oid_object_info(the_repository, &obj->oid, NULL); if (type > 0) - object_as_type(obj, type, 0); + object_as_type(the_repository, obj, type, 0); } ret = type_name(obj->type); @@ -392,7 +394,8 @@ static int fsck_obj_buffer(const struct object_id *oid, enum object_type type, * verify_packfile(), data_valid variable for details. */ struct object *obj; - obj = parse_object_buffer(oid, type, size, buffer, eaten); + obj = parse_object_buffer(the_repository, oid, type, size, buffer, + eaten); if (!obj) { errors_found |= ERROR_OBJECT; return error("%s: object corrupt or missing", oid_to_hex(oid)); @@ -410,7 +413,7 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid, struct object *obj; if (!is_null_oid(oid)) { - obj = lookup_object(oid->hash); + obj = lookup_object(the_repository, oid->hash); if (obj && (obj->flags & HAS_OBJ)) { if (timestamp && name_objects) add_decoration(fsck_walk_options.object_names, @@ -452,7 +455,7 @@ static int fsck_handle_ref(const char *refname, const struct object_id *oid, { struct object *obj; - obj = parse_object(oid); + obj = parse_object(the_repository, oid); if (!obj) { if (is_promisor_object(oid)) { /* @@ -525,7 +528,9 @@ static int fsck_loose(const struct object_id *oid, const char *path, void *data) if (!contents && type != OBJ_BLOB) BUG("read_loose_object streamed a non-blob"); - obj = parse_object_buffer(oid, type, size, contents, &eaten); + obj = parse_object_buffer(the_repository, oid, type, size, + contents, &eaten); + if (!obj) { errors_found |= ERROR_OBJECT; error("%s: object could not be parsed: %s", @@ -614,7 +619,7 @@ static int fsck_cache_tree(struct cache_tree *it) fprintf(stderr, "Checking cache tree\n"); if (0 <= it->entry_count) { - struct object *obj = parse_object(&it->oid); + struct object *obj = parse_object(the_repository, &it->oid); if (!obj) { error("%s: invalid sha1 pointer in cache-tree", oid_to_hex(&it->oid)); @@ -763,7 +768,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) const char *arg = argv[i]; struct object_id oid; if (!get_oid(arg, &oid)) { - struct object *obj = lookup_object(oid.hash); + struct object *obj = lookup_object(the_repository, + oid.hash); if (!obj || !(obj->flags & HAS_OBJ)) { if (is_promisor_object(&oid)) @@ -806,7 +812,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) mode = active_cache[i]->ce_mode; if (S_ISGITLINK(mode)) continue; - blob = lookup_blob(&active_cache[i]->oid); + blob = lookup_blob(the_repository, + &active_cache[i]->oid); if (!blob) continue; obj = &blob->object; @@ -822,5 +829,24 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) } check_connectivity(); + + if (!git_config_get_bool("core.commitgraph", &i) && i) { + struct child_process commit_graph_verify = CHILD_PROCESS_INIT; + const char *verify_argv[] = { "commit-graph", "verify", NULL, NULL, NULL }; + + commit_graph_verify.argv = verify_argv; + commit_graph_verify.git_cmd = 1; + if (run_command(&commit_graph_verify)) + errors_found |= ERROR_COMMIT_GRAPH; + + prepare_alt_odb(the_repository); + for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next) { + verify_argv[2] = "--object-dir"; + verify_argv[3] = alt->path; + if (run_command(&commit_graph_verify)) + errors_found |= ERROR_COMMIT_GRAPH; + } + } + return errors_found; } diff --git a/builtin/gc.c b/builtin/gc.c index ccfb1ceaeb..57069442b0 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -20,6 +20,7 @@ #include "sigchain.h" #include "argv-array.h" #include "commit.h" +#include "commit-graph.h" #include "packfile.h" #include "object-store.h" #include "pack.h" @@ -40,6 +41,7 @@ static int aggressive_depth = 50; static int aggressive_window = 250; static int gc_auto_threshold = 6700; static int gc_auto_pack_limit = 50; +static int gc_write_commit_graph; static int detach_auto = 1; static timestamp_t gc_log_expire_time; static const char *gc_log_expire = "1.day.ago"; @@ -129,6 +131,7 @@ static void gc_config(void) git_config_get_int("gc.aggressivedepth", &aggressive_depth); git_config_get_int("gc.auto", &gc_auto_threshold); git_config_get_int("gc.autopacklimit", &gc_auto_pack_limit); + git_config_get_bool("gc.writecommitgraph", &gc_write_commit_graph); git_config_get_bool("gc.autodetach", &detach_auto); git_config_get_expiry("gc.pruneexpire", &prune_expire); git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire); @@ -612,6 +615,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix) return -1; if (!repository_format_precious_objects) { + close_all_packs(the_repository->objects); if (run_command_v_opt(repack.argv, RUN_GIT_CMD)) return error(FAILED_RUN, repack.argv[0]); @@ -641,6 +645,9 @@ int cmd_gc(int argc, const char **argv, const char *prefix) if (pack_garbage.nr > 0) clean_pack_garbage(); + if (gc_write_commit_graph) + write_commit_graph_reachable(get_object_directory(), 0); + if (auto_gc && too_many_loose_objects()) warning(_("There are too many unreachable loose objects; " "run 'git prune' to remove them.")); diff --git a/builtin/grep.c b/builtin/grep.c index 61bcaf6e58..056161f0f8 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -647,7 +647,8 @@ static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec, for (i = 0; i < nr; i++) { struct object *real_obj; - real_obj = deref_tag(list->objects[i].item, NULL, 0); + real_obj = deref_tag(the_repository, list->objects[i].item, + NULL, 0); /* load the gitmodules file for this rev */ if (recurse_submodules) { @@ -843,6 +844,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix) OPT_BOOL_F('z', "null", &opt.null_following_name, N_("print NUL after filenames"), PARSE_OPT_NOCOMPLETE), + OPT_BOOL('o', "only-matching", &opt.only_matching, + N_("show only matching parts of a line")), OPT_BOOL('c', "count", &opt.count, N_("show the number of matches instead of matching lines")), OPT__COLOR(&opt.color, N_("highlight matches")), @@ -962,6 +965,10 @@ int cmd_grep(int argc, const char **argv, const char *prefix) if (!opt.pattern_list) die(_("no pattern given.")); + /* --only-matching has no effect with --invert. */ + if (opt.invert) + opt.only_matching = 0; + /* * We have to find "--" in a separate pass, because its presence * influences how we will parse arguments that come before it. diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 74fe2973e1..de311febe3 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -832,7 +832,7 @@ static void sha1_object(const void *data, struct object_entry *obj_entry, if (strict || do_fsck_object) { read_lock(); if (type == OBJ_BLOB) { - struct blob *blob = lookup_blob(oid); + struct blob *blob = lookup_blob(the_repository, oid); if (blob) blob->object.flags |= FLAG_CHECKED; else @@ -851,7 +851,8 @@ static void sha1_object(const void *data, struct object_entry *obj_entry, * we do not need to free the memory here, as the * buf is deleted by the caller. */ - obj = parse_object_buffer(oid, type, size, buf, + obj = parse_object_buffer(the_repository, oid, type, + size, buf, &eaten); if (!obj) die(_("invalid %s"), type_name(type)); diff --git a/builtin/log.c b/builtin/log.c index 805f89d7e1..574595132a 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -30,6 +30,7 @@ #include "gpg-interface.h" #include "progress.h" #include "commit-slab.h" +#include "repository.h" #define MAIL_DEFAULT_WRAP 72 @@ -619,7 +620,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) rev.shown_one = 1; if (ret) break; - o = parse_object(&t->tagged->oid); + o = parse_object(the_repository, &t->tagged->oid); if (!o) ret = error(_("Could not read object %s"), oid_to_hex(&t->tagged->oid)); @@ -906,8 +907,8 @@ static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids) o2 = rev->pending.objects[1].item; flags1 = o1->flags; flags2 = o2->flags; - c1 = lookup_commit_reference(&o1->oid); - c2 = lookup_commit_reference(&o2->oid); + c1 = lookup_commit_reference(the_repository, &o1->oid); + c2 = lookup_commit_reference(the_repository, &o2->oid); if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING)) die(_("Not a range.")); @@ -1864,7 +1865,8 @@ static int add_pending_commit(const char *arg, struct rev_info *revs, int flags) { struct object_id oid; if (get_oid(arg, &oid) == 0) { - struct commit *commit = lookup_commit_reference(&oid); + struct commit *commit = lookup_commit_reference(the_repository, + &oid); if (commit) { commit->object.flags |= flags; add_pending_object(revs, &commit->object, arg); diff --git a/builtin/merge-base.c b/builtin/merge-base.c index 3b7600150b..08d91b1f0c 100644 --- a/builtin/merge-base.c +++ b/builtin/merge-base.c @@ -6,6 +6,7 @@ #include "diff.h" #include "revision.h" #include "parse-options.h" +#include "repository.h" static int show_merge_base(struct commit **rev, int rev_nr, int show_all) { @@ -42,7 +43,7 @@ static struct commit *get_commit_reference(const char *arg) if (get_oid(arg, &revkey)) die("Not a valid object name %s", arg); - r = lookup_commit_reference(&revkey); + r = lookup_commit_reference(the_repository, &revkey); if (!r) die("Not a valid commit name %s", arg); @@ -123,7 +124,7 @@ static void add_one_commit(struct object_id *oid, struct rev_collect *revs) if (is_null_oid(oid)) return; - commit = lookup_commit(oid); + commit = lookup_commit(the_repository, oid); if (!commit || (commit->object.flags & TMP_MARK) || parse_commit(commit)) @@ -171,7 +172,7 @@ static int handle_fork_point(int argc, const char **argv) if (get_oid(commitname, &oid)) die("Not a valid object name: '%s'", commitname); - derived = lookup_commit_reference(&oid); + derived = lookup_commit_reference(the_repository, &oid); memset(&revs, 0, sizeof(revs)); revs.initial = 1; for_each_reflog_ent(refname, collect_one_reflog_ent, &revs); diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c index 0dd9021958..9b2f707c29 100644 --- a/builtin/merge-recursive.c +++ b/builtin/merge-recursive.c @@ -9,10 +9,10 @@ static const char builtin_merge_recursive_usage[] = static const char *better_branch_name(const char *branch) { - static char githead_env[8 + GIT_SHA1_HEXSZ + 1]; + static char githead_env[8 + GIT_MAX_HEXSZ + 1]; char *name; - if (strlen(branch) != GIT_SHA1_HEXSZ) + if (strlen(branch) != the_hash_algo->hexsz) return branch; xsnprintf(githead_env, sizeof(githead_env), "GITHEAD_%s", branch); name = getenv(githead_env); diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index 8a8d579752..f8023bae1e 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -2,6 +2,7 @@ #include "tree-walk.h" #include "xdiff-interface.h" #include "object-store.h" +#include "repository.h" #include "blob.h" #include "exec-cmd.h" #include "merge-blobs.h" @@ -170,7 +171,7 @@ static struct merge_list *create_entry(unsigned stage, unsigned mode, const stru res->stage = stage; res->path = path; res->mode = mode; - res->blob = lookup_blob(oid); + res->blob = lookup_blob(the_repository, oid); return res; } diff --git a/builtin/merge.c b/builtin/merge.c index d1b547d973..77e1694a78 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -111,6 +111,35 @@ static int option_parse_message(const struct option *opt, return 0; } +static int option_read_message(struct parse_opt_ctx_t *ctx, + const struct option *opt, int unset) +{ + struct strbuf *buf = opt->value; + const char *arg; + + if (unset) + BUG("-F cannot be negated"); + + if (ctx->opt) { + arg = ctx->opt; + ctx->opt = NULL; + } else if (ctx->argc > 1) { + ctx->argc--; + arg = *++ctx->argv; + } else + return opterror(opt, "requires a value", 0); + + if (buf->len) + strbuf_addch(buf, '\n'); + if (ctx->prefix && !is_absolute_path(arg)) + arg = prefix_filename(ctx->prefix, arg); + if (strbuf_read_file(buf, arg, 0) < 0) + return error(_("could not read file '%s'"), arg); + have_message = 1; + + return 0; +} + static struct strategy *get_strategy(const char *name) { int i; @@ -228,6 +257,9 @@ static struct option builtin_merge_options[] = { OPT_CALLBACK('m', "message", &merge_msg, N_("message"), N_("merge commit message (for a non-fast-forward merge)"), option_parse_message), + { OPTION_LOWLEVEL_CALLBACK, 'F', "file", &merge_msg, N_("path"), + N_("read message from file"), PARSE_OPT_NONEG, + (parse_opt_cb *) option_read_message }, OPT__VERBOSITY(&verbosity), OPT_BOOL(0, "abort", &abort_current_merge, N_("abort the current in-progress merge")), @@ -1035,6 +1067,7 @@ static void handle_fetch_head(struct commit_list **remotes, struct strbuf *merge const char *filename; int fd, pos, npos; struct strbuf fetch_head_file = STRBUF_INIT; + const unsigned hexsz = the_hash_algo->hexsz; if (!merge_names) merge_names = &fetch_head_file; @@ -1060,16 +1093,16 @@ static void handle_fetch_head(struct commit_list **remotes, struct strbuf *merge else npos = merge_names->len; - if (npos - pos < GIT_SHA1_HEXSZ + 2 || + if (npos - pos < hexsz + 2 || get_oid_hex(merge_names->buf + pos, &oid)) commit = NULL; /* bad */ - else if (memcmp(merge_names->buf + pos + GIT_SHA1_HEXSZ, "\t\t", 2)) + else if (memcmp(merge_names->buf + pos + hexsz, "\t\t", 2)) continue; /* not-for-merge */ else { - char saved = merge_names->buf[pos + GIT_SHA1_HEXSZ]; - merge_names->buf[pos + GIT_SHA1_HEXSZ] = '\0'; + char saved = merge_names->buf[pos + hexsz]; + merge_names->buf[pos + hexsz] = '\0'; commit = get_merge_parent(merge_names->buf + pos); - merge_names->buf[pos + GIT_SHA1_HEXSZ] = saved; + merge_names->buf[pos + hexsz] = saved; } if (!commit) { if (ptr) diff --git a/builtin/name-rev.c b/builtin/name-rev.c index 0eb440359d..f1cb45c227 100644 --- a/builtin/name-rev.c +++ b/builtin/name-rev.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "cache.h" +#include "repository.h" #include "config.h" #include "commit.h" #include "tag.h" @@ -203,7 +204,7 @@ static int tipcmp(const void *a_, const void *b_) static int name_ref(const char *path, const struct object_id *oid, int flags, void *cb_data) { - struct object *o = parse_object(oid); + struct object *o = parse_object(the_repository, oid); struct name_ref_data *data = cb_data; int can_abbreviate_output = data->tags_only && data->name_only; int deref = 0; @@ -261,7 +262,7 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo struct tag *t = (struct tag *) o; if (!t->tagged) break; /* broken repository */ - o = parse_object(&t->tagged->oid); + o = parse_object(the_repository, &t->tagged->oid); deref = 1; taggerdate = t->date; } @@ -378,7 +379,8 @@ static void name_rev_line(char *p, struct name_ref_data *data) *(p+1) = 0; if (!get_oid(p - (GIT_SHA1_HEXSZ - 1), &oid)) { struct object *o = - lookup_object(oid.hash); + lookup_object(the_repository, + oid.hash); if (o) name = get_rev_name(o, &buf); } @@ -451,9 +453,10 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) } commit = NULL; - object = parse_object(&oid); + object = parse_object(the_repository, &oid); if (object) { - struct object *peeled = deref_tag(object, *argv, 0); + struct object *peeled = deref_tag(the_repository, + object, *argv, 0); if (peeled && peeled->type == OBJ_COMMIT) commit = (struct commit *)peeled; } diff --git a/builtin/notes.c b/builtin/notes.c index a0a1840040..c05cd004ab 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -12,6 +12,7 @@ #include "builtin.h" #include "notes.h" #include "object-store.h" +#include "repository.h" #include "blob.h" #include "pretty.h" #include "refs.h" @@ -711,7 +712,7 @@ static int merge_commit(struct notes_merge_options *o) if (get_oid("NOTES_MERGE_PARTIAL", &oid)) die(_("failed to read ref NOTES_MERGE_PARTIAL")); - else if (!(partial = lookup_commit_reference(&oid))) + else if (!(partial = lookup_commit_reference(the_repository, &oid))) die(_("could not find commit from NOTES_MERGE_PARTIAL.")); else if (parse_commit(partial)) die(_("could not parse commit from NOTES_MERGE_PARTIAL.")); diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index ebc8cefb53..4391504a91 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -2474,7 +2474,7 @@ static void add_tag_chain(const struct object_id *oid) if (packlist_find(&to_pack, oid->hash, NULL)) return; - tag = lookup_tag(oid); + tag = lookup_tag(the_repository, oid); while (1) { if (!tag || parse_tag(tag) || !tag->tagged) die("unable to pack objects reachable from tag %s", diff --git a/builtin/prune.c b/builtin/prune.c index 70ec35aa05..72b0621b76 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -40,7 +40,7 @@ static int prune_object(const struct object_id *oid, const char *fullpath, * Do we know about this object? * It must have been reachable */ - if (lookup_object(oid->hash)) + if (lookup_object(the_repository, oid->hash)) return 0; if (lstat(fullpath, &st)) { diff --git a/builtin/pull.c b/builtin/pull.c index 7197b22b16..4e78935392 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -765,10 +765,13 @@ static int get_octopus_merge_base(struct object_id *merge_base, { struct commit_list *revs = NULL, *result; - commit_list_insert(lookup_commit_reference(curr_head), &revs); - commit_list_insert(lookup_commit_reference(merge_head), &revs); + commit_list_insert(lookup_commit_reference(the_repository, curr_head), + &revs); + commit_list_insert(lookup_commit_reference(the_repository, merge_head), + &revs); if (!is_null_oid(fork_point)) - commit_list_insert(lookup_commit_reference(fork_point), &revs); + commit_list_insert(lookup_commit_reference(the_repository, fork_point), + &revs); result = get_octopus_merge_bases(revs); free_commit_list(revs); @@ -944,9 +947,11 @@ int cmd_pull(int argc, const char **argv, const char *prefix) struct commit_list *list = NULL; struct commit *merge_head, *head; - head = lookup_commit_reference(&orig_head); + head = lookup_commit_reference(the_repository, + &orig_head); commit_list_insert(head, &list); - merge_head = lookup_commit_reference(&merge_heads.oid[0]); + merge_head = lookup_commit_reference(the_repository, + &merge_heads.oid[0]); if (is_descendant_of(merge_head, list)) { /* we can fast-forward this without invoking rebase */ opt_ff = "--ff-only"; diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 44c7c9ee82..c17ce94e12 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -630,8 +630,6 @@ static void prepare_push_cert_sha1(struct child_process *proc) return; if (!already_done) { - struct strbuf gpg_output = STRBUF_INIT; - struct strbuf gpg_status = STRBUF_INIT; int bogs /* beginning_of_gpg_sig */; already_done = 1; @@ -640,22 +638,11 @@ static void prepare_push_cert_sha1(struct child_process *proc) oidclr(&push_cert_oid); memset(&sigcheck, '\0', sizeof(sigcheck)); - sigcheck.result = 'N'; bogs = parse_signature(push_cert.buf, push_cert.len); - if (verify_signed_buffer(push_cert.buf, bogs, - push_cert.buf + bogs, push_cert.len - bogs, - &gpg_output, &gpg_status) < 0) { - ; /* error running gpg */ - } else { - sigcheck.payload = push_cert.buf; - sigcheck.gpg_output = gpg_output.buf; - sigcheck.gpg_status = gpg_status.buf; - parse_gpg_output(&sigcheck); - } + check_signature(push_cert.buf, bogs, push_cert.buf + bogs, + push_cert.len - bogs, &sigcheck); - strbuf_release(&gpg_output); - strbuf_release(&gpg_status); nonce_status = check_nonce(push_cert.buf, bogs); } if (!is_null_oid(&push_cert_oid)) { @@ -1108,8 +1095,8 @@ static const char *update(struct command *cmd, struct shallow_info *si) struct object *old_object, *new_object; struct commit *old_commit, *new_commit; - old_object = parse_object(old_oid); - new_object = parse_object(new_oid); + old_object = parse_object(the_repository, old_oid); + new_object = parse_object(the_repository, new_oid); if (!old_object || !new_object || old_object->type != OBJ_COMMIT || @@ -1132,7 +1119,7 @@ static const char *update(struct command *cmd, struct shallow_info *si) if (is_null_oid(new_oid)) { struct strbuf err = STRBUF_INIT; - if (!parse_object(old_oid)) { + if (!parse_object(the_repository, old_oid)) { old_oid = NULL; if (ref_exists(name)) { rp_warning("Allowing deletion of corrupt ref."); diff --git a/builtin/reflog.c b/builtin/reflog.c index 0091192995..3acef5a0ab 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -2,6 +2,7 @@ #include "config.h" #include "lockfile.h" #include "object-store.h" +#include "repository.h" #include "commit.h" #include "refs.h" #include "dir.h" @@ -65,7 +66,7 @@ static int tree_is_complete(const struct object_id *oid) int complete; struct tree *tree; - tree = lookup_tree(oid); + tree = lookup_tree(the_repository, oid); if (!tree) return 0; if (tree->object.flags & SEEN) @@ -129,7 +130,7 @@ static int commit_is_complete(struct commit *commit) struct commit_list *parent; c = (struct commit *)object_array_pop(&study); - if (!c->object.parsed && !parse_object(&c->object.oid)) + if (!c->object.parsed && !parse_object(the_repository, &c->object.oid)) c->object.flags |= INCOMPLETE; if (c->object.flags & INCOMPLETE) { @@ -195,7 +196,7 @@ static int keep_entry(struct commit **it, struct object_id *oid) if (is_null_oid(oid)) return 1; - commit = lookup_commit_reference_gently(oid, 1); + commit = lookup_commit_reference_gently(the_repository, oid, 1); if (!commit) return 0; @@ -264,7 +265,8 @@ static int unreachable(struct expire_reflog_policy_cb *cb, struct commit *commit if (is_null_oid(oid)) return 0; - commit = lookup_commit_reference_gently(oid, 1); + commit = lookup_commit_reference_gently(the_repository, oid, + 1); /* Not a commit -- keep it */ if (!commit) @@ -321,7 +323,7 @@ static int push_tip_to_list(const char *refname, const struct object_id *oid, struct commit *tip_commit; if (flags & REF_ISSYMREF) return 0; - tip_commit = lookup_commit_reference_gently(oid, 1); + tip_commit = lookup_commit_reference_gently(the_repository, oid, 1); if (!tip_commit) return 0; commit_list_insert(tip_commit, list); @@ -338,7 +340,8 @@ static void reflog_expiry_prepare(const char *refname, cb->tip_commit = NULL; cb->unreachable_expire_kind = UE_HEAD; } else { - cb->tip_commit = lookup_commit_reference_gently(oid, 1); + cb->tip_commit = lookup_commit_reference_gently(the_repository, + oid, 1); if (!cb->tip_commit) cb->unreachable_expire_kind = UE_ALWAYS; else diff --git a/builtin/replace.c b/builtin/replace.c index deabda2101..ef22d724bb 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -371,7 +371,7 @@ static int replace_parents(struct strbuf *buf, int argc, const char **argv) return error(_("Not a valid object name: '%s'"), argv[i]); } - if (!lookup_commit_reference(&oid)) { + if (!lookup_commit_reference(the_repository, &oid)) { strbuf_release(&new_parents); return error(_("could not parse %s"), argv[i]); } @@ -402,10 +402,10 @@ static int check_one_mergetag(struct commit *commit, int i; hash_object_file(extra->value, extra->len, type_name(OBJ_TAG), &tag_oid); - tag = lookup_tag(&tag_oid); + tag = lookup_tag(the_repository, &tag_oid); if (!tag) return error(_("bad mergetag in commit '%s'"), ref); - if (parse_tag_buffer(tag, extra->value, extra->len)) + if (parse_tag_buffer(the_repository, tag, extra->value, extra->len)) return error(_("malformed mergetag in commit '%s'"), ref); /* iterate over new parents */ @@ -443,7 +443,7 @@ static int create_graft(int argc, const char **argv, int force, int gentle) if (get_oid(old_ref, &old_oid) < 0) return error(_("Not a valid object name: '%s'"), old_ref); - commit = lookup_commit_reference(&old_oid); + commit = lookup_commit_reference(the_repository, &old_oid); if (!commit) return error(_("could not parse %s"), old_ref); diff --git a/builtin/reset.c b/builtin/reset.c index ffe41c924b..11cd0dcb8c 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -134,7 +134,7 @@ static void update_index_from_diff(struct diff_queue_struct *q, continue; } - ce = make_cache_entry(one->mode, one->oid.hash, one->path, + ce = make_cache_entry(&the_index, one->mode, &one->oid, one->path, 0, 0); if (!ce) die(_("make_cache_entry failed for path '%s'"), @@ -319,7 +319,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) struct commit *commit; if (get_oid_committish(rev, &oid)) die(_("Failed to resolve '%s' as a valid revision."), rev); - commit = lookup_commit_reference(&oid); + commit = lookup_commit_reference(the_repository, &oid); if (!commit) die(_("Could not parse object '%s'."), rev); oidcpy(&oid, &commit->object.oid); @@ -396,7 +396,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) update_ref_status = reset_refs(rev, &oid); if (reset_type == HARD && !update_ref_status && !quiet) - print_new_head_line(lookup_commit_reference(&oid)); + print_new_head_line(lookup_commit_reference(the_repository, &oid)); } if (!pathspec.nr) remove_branch_state(); diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 6fcb0ff6d5..5b07f3f4a2 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -240,7 +240,7 @@ static int finish_object(struct object *obj, const char *name, void *cb_data) return 1; } if (info->revs->verify_objects && !obj->parsed && obj->type != OBJ_COMMIT) - parse_object(&obj->oid); + parse_object(the_repository, &obj->oid); return 0; } diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 2a6cb298bd..0f09bbbf65 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -280,8 +280,8 @@ static int try_difference(const char *arg) if (symmetric) { struct commit_list *exclude; struct commit *a, *b; - a = lookup_commit_reference(&start_oid); - b = lookup_commit_reference(&end_oid); + a = lookup_commit_reference(the_repository, &start_oid); + b = lookup_commit_reference(the_repository, &end_oid); if (!a || !b) { *dotdot = '.'; return 0; @@ -333,7 +333,7 @@ static int try_parent_shorthands(const char *arg) *dotdot = 0; if (get_oid_committish(arg, &oid) || - !(commit = lookup_commit_reference(&oid))) { + !(commit = lookup_commit_reference(the_repository, &oid))) { *dotdot = '^'; return 0; } diff --git a/builtin/show-branch.c b/builtin/show-branch.c index f2e985c00a..4b9d3c0059 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -378,7 +378,8 @@ static void sort_ref_range(int bottom, int top) static int append_ref(const char *refname, const struct object_id *oid, int allow_dups) { - struct commit *commit = lookup_commit_reference_gently(oid, 1); + struct commit *commit = lookup_commit_reference_gently(the_repository, + oid, 1); int i; if (!commit) @@ -830,7 +831,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) MAX_REVS), MAX_REVS); if (get_oid(ref_name[num_rev], &revkey)) die(_("'%s' is not a valid ref."), ref_name[num_rev]); - commit = lookup_commit_reference(&revkey); + commit = lookup_commit_reference(the_repository, &revkey); if (!commit) die(_("cannot find commit %s (%s)"), ref_name[num_rev], oid_to_hex(&revkey)); diff --git a/builtin/tag.c b/builtin/tag.c index 9919b03b2d..9a19ffb49f 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -313,7 +313,7 @@ static void create_reflog_msg(const struct object_id *oid, struct strbuf *sb) } free(buf); - if ((c = lookup_commit_reference(oid)) != NULL) + if ((c = lookup_commit_reference(the_repository, oid)) != NULL) strbuf_addf(sb, ", %s", show_date(c->date, 0, DATE_MODE(SHORT))); break; case OBJ_TREE: diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index cf585fcc5e..716408e3a9 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -254,7 +254,7 @@ static void write_object(unsigned nr, enum object_type type, added_object(nr, type, buf, size); free(buf); - blob = lookup_blob(&obj_list[nr].oid); + blob = lookup_blob(the_repository, &obj_list[nr].oid); if (blob) blob->object.flags |= FLAG_WRITTEN; else @@ -265,7 +265,8 @@ static void write_object(unsigned nr, enum object_type type, int eaten; hash_object_file(buf, size, type_name(type), &obj_list[nr].oid); added_object(nr, type, buf, size); - obj = parse_object_buffer(&obj_list[nr].oid, type, size, buf, + obj = parse_object_buffer(the_repository, &obj_list[nr].oid, + type, size, buf, &eaten); if (!obj) die("invalid %s", type_name(type)); @@ -331,7 +332,7 @@ static int resolve_against_held(unsigned nr, const struct object_id *base, { struct object *obj; struct obj_buffer *obj_buffer; - obj = lookup_object(base->hash); + obj = lookup_object(the_repository, base->hash); if (!obj) return 0; obj_buffer = lookup_object_buffer(obj); diff --git a/builtin/update-index.c b/builtin/update-index.c index a8709a26ec..f5c0b6a1d2 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -268,15 +268,14 @@ static int process_lstat_error(const char *path, int err) static int add_one_path(const struct cache_entry *old, const char *path, int len, struct stat *st) { - int option, size; + int option; struct cache_entry *ce; /* Was the old index entry already up-to-date? */ if (old && !ce_stage(old) && !ce_match_stat(old, st, 0)) return 0; - size = cache_entry_size(len); - ce = xcalloc(1, size); + ce = make_empty_cache_entry(&the_index, len); memcpy(ce->name, path, len); ce->ce_flags = create_ce_flags(0); ce->ce_namelen = len; @@ -285,13 +284,13 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len if (index_path(&ce->oid, path, st, info_only ? 0 : HASH_WRITE_OBJECT)) { - free(ce); + discard_cache_entry(ce); return -1; } option = allow_add ? ADD_CACHE_OK_TO_ADD : 0; option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0; if (add_cache_entry(ce, option)) { - free(ce); + discard_cache_entry(ce); return error("%s: cannot add to the index - missing --add option?", path); } return 0; @@ -402,15 +401,14 @@ static int process_path(const char *path, struct stat *st, int stat_errno) static int add_cacheinfo(unsigned int mode, const struct object_id *oid, const char *path, int stage) { - int size, len, option; + int len, option; struct cache_entry *ce; if (!verify_path(path, mode)) return error("Invalid path '%s'", path); len = strlen(path); - size = cache_entry_size(len); - ce = xcalloc(1, size); + ce = make_empty_cache_entry(&the_index, len); oidcpy(&ce->oid, oid); memcpy(ce->name, path, len); @@ -492,6 +490,7 @@ static void update_one(const char *path) static void read_index_info(int nul_term_line) { + const int hexsz = the_hash_algo->hexsz; struct strbuf buf = STRBUF_INIT; struct strbuf uq = STRBUF_INIT; strbuf_getline_fn getline_fn; @@ -529,7 +528,7 @@ static void read_index_info(int nul_term_line) mode = ul; tab = strchr(ptr, '\t'); - if (!tab || tab - ptr < GIT_SHA1_HEXSZ + 1) + if (!tab || tab - ptr < hexsz + 1) goto bad_line; if (tab[-2] == ' ' && '0' <= tab[-1] && tab[-1] <= '3') { @@ -542,8 +541,8 @@ static void read_index_info(int nul_term_line) ptr = tab + 1; /* point at the head of path */ } - if (get_oid_hex(tab - GIT_SHA1_HEXSZ, &oid) || - tab[-(GIT_SHA1_HEXSZ + 1)] != ' ') + if (get_oid_hex(tab - hexsz, &oid) || + tab[-(hexsz + 1)] != ' ') goto bad_line; path_name = ptr; @@ -571,7 +570,7 @@ static void read_index_info(int nul_term_line) * ptr[-1] points at tab, * ptr[-41] is at the beginning of sha1 */ - ptr[-(GIT_SHA1_HEXSZ + 2)] = ptr[-1] = 0; + ptr[-(hexsz + 2)] = ptr[-1] = 0; if (add_cacheinfo(mode, &oid, path_name, stage)) die("git update-index: unable to update %s", path_name); @@ -599,7 +598,6 @@ static struct cache_entry *read_one_ent(const char *which, { unsigned mode; struct object_id oid; - int size; struct cache_entry *ce; if (get_tree_entry(ent, path, &oid, &mode)) { @@ -612,8 +610,7 @@ static struct cache_entry *read_one_ent(const char *which, error("%s: not a blob in %s branch.", path, which); return NULL; } - size = cache_entry_size(namelen); - ce = xcalloc(1, size); + ce = make_empty_cache_entry(&the_index, namelen); oidcpy(&ce->oid, &oid); memcpy(ce->name, path, namelen); @@ -690,8 +687,8 @@ static int unresolve_one(const char *path) error("%s: cannot add their version to the index.", path); ret = -1; free_return: - free(ce_2); - free(ce_3); + discard_cache_entry(ce_2); + discard_cache_entry(ce_3); return ret; } @@ -758,7 +755,7 @@ static int do_reupdate(int ac, const char **av, ce->name, ce_namelen(ce), 0); if (old && ce->ce_mode == old->ce_mode && !oidcmp(&ce->oid, &old->oid)) { - free(old); + discard_cache_entry(old); continue; /* unchanged */ } /* Be careful. The working tree may not have the @@ -769,7 +766,7 @@ static int do_reupdate(int ac, const char **av, path = xstrdup(ce->name); update_one(path); free(path); - free(old); + discard_cache_entry(old); if (save_nr != active_nr) goto redo; } @@ -826,6 +823,7 @@ static int parse_new_style_cacheinfo(const char *arg, { unsigned long ul; char *endp; + const char *p; if (!arg) return -1; @@ -836,9 +834,9 @@ static int parse_new_style_cacheinfo(const char *arg, return -1; /* not a new-style cacheinfo */ *mode = ul; endp++; - if (get_oid_hex(endp, oid) || endp[GIT_SHA1_HEXSZ] != ',') + if (parse_oid_hex(endp, oid, &p) || *p != ',') return -1; - *path = endp + GIT_SHA1_HEXSZ + 1; + *path = p + 1; return 0; } diff --git a/builtin/verify-commit.c b/builtin/verify-commit.c index f6922da16d..7772c07ed7 100644 --- a/builtin/verify-commit.c +++ b/builtin/verify-commit.c @@ -9,6 +9,7 @@ #include "config.h" #include "builtin.h" #include "object-store.h" +#include "repository.h" #include "commit.h" #include "run-command.h" #include <signal.h> @@ -27,7 +28,8 @@ static int run_gpg_verify(const struct object_id *oid, const char *buf, unsigned memset(&signature_check, 0, sizeof(signature_check)); - ret = check_commit_signature(lookup_commit(oid), &signature_check); + ret = check_commit_signature(lookup_commit(the_repository, oid), + &signature_check); print_signature_buffer(&signature_check, flags); signature_check_clear(&signature_check); diff --git a/builtin/worktree.c b/builtin/worktree.c index 5c7d2bb180..a763dbdccb 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -412,7 +412,7 @@ static const char *dwim_branch(const char *path, const char **new_branch) if (guess_remote) { struct object_id oid; const char *remote = - unique_tracking_name(*new_branch, &oid); + unique_tracking_name(*new_branch, &oid, NULL); return remote; } return NULL; @@ -484,7 +484,7 @@ static int add(int ac, const char **av, const char *prefix) commit = lookup_commit_reference_by_name(branch); if (!commit) { - remote = unique_tracking_name(branch, &oid); + remote = unique_tracking_name(branch, &oid, NULL); if (remote) { new_branch = branch; branch = remote; |