diff options
Diffstat (limited to 'builtin')
67 files changed, 863 insertions, 490 deletions
diff --git a/builtin/am.c b/builtin/am.c index 1338b606fe..390b463144 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1211,7 +1211,7 @@ static int parse_mail(struct am_state *state, const char *mail) int ret = 0; struct mailinfo mi; - setup_mailinfo(&mi); + setup_mailinfo(the_repository, &mi); if (state->utf8) mi.metainfo_charset = get_commit_output_encoding(); @@ -1786,7 +1786,7 @@ static int do_interactive(struct am_state *state) } strbuf_release(&msg); } else if (*reply == 'v' || *reply == 'V') { - const char *pager = git_pager(1); + const char *pager = git_pager(the_repository, 1); struct child_process cp = CHILD_PROCESS_INIT; if (!pager) @@ -2246,7 +2246,7 @@ static int show_patch(struct am_state *state, enum resume_type resume_mode) if (len < 0) die_errno(_("failed to read '%s'"), patch_path); - setup_pager(); + setup_pager(the_repository); write_in_full(1, sb.buf, sb.len); strbuf_release(&sb); return 0; @@ -2427,8 +2427,7 @@ int cmd_am(int argc, OPT_END() }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(usage, options); + show_usage_with_options_if_asked(argc, argv, usage, options); git_config(git_default_config, NULL); diff --git a/builtin/backfill.c b/builtin/backfill.c new file mode 100644 index 0000000000..33e1ea2f84 --- /dev/null +++ b/builtin/backfill.c @@ -0,0 +1,147 @@ +/* We need this macro to access core_apply_sparse_checkout */ +#define USE_THE_REPOSITORY_VARIABLE + +#include "builtin.h" +#include "git-compat-util.h" +#include "config.h" +#include "parse-options.h" +#include "repository.h" +#include "commit.h" +#include "dir.h" +#include "environment.h" +#include "hex.h" +#include "tree.h" +#include "tree-walk.h" +#include "object.h" +#include "object-store-ll.h" +#include "oid-array.h" +#include "oidset.h" +#include "promisor-remote.h" +#include "strmap.h" +#include "string-list.h" +#include "revision.h" +#include "trace2.h" +#include "progress.h" +#include "packfile.h" +#include "path-walk.h" + +static const char * const builtin_backfill_usage[] = { + N_("git backfill [--min-batch-size=<n>] [--[no-]sparse]"), + NULL +}; + +struct backfill_context { + struct repository *repo; + struct oid_array current_batch; + size_t min_batch_size; + int sparse; +}; + +static void backfill_context_clear(struct backfill_context *ctx) +{ + oid_array_clear(&ctx->current_batch); +} + +static void download_batch(struct backfill_context *ctx) +{ + promisor_remote_get_direct(ctx->repo, + ctx->current_batch.oid, + ctx->current_batch.nr); + oid_array_clear(&ctx->current_batch); + + /* + * 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); +} + +static int fill_missing_blobs(const char *path UNUSED, + struct oid_array *list, + enum object_type type, + void *data) +{ + struct backfill_context *ctx = data; + + if (type != OBJ_BLOB) + return 0; + + for (size_t i = 0; i < list->nr; i++) { + if (!has_object(ctx->repo, &list->oid[i], + OBJECT_INFO_FOR_PREFETCH)) + oid_array_append(&ctx->current_batch, &list->oid[i]); + } + + if (ctx->current_batch.nr >= ctx->min_batch_size) + download_batch(ctx); + + return 0; +} + +static int do_backfill(struct backfill_context *ctx) +{ + struct rev_info revs; + struct path_walk_info info = PATH_WALK_INFO_INIT; + int ret; + + if (ctx->sparse) { + CALLOC_ARRAY(info.pl, 1); + if (get_sparse_checkout_patterns(info.pl)) { + path_walk_info_clear(&info); + return error(_("problem loading sparse-checkout")); + } + } + + repo_init_revisions(ctx->repo, &revs, ""); + handle_revision_arg("HEAD", &revs, 0, 0); + + info.blobs = 1; + info.tags = info.commits = info.trees = 0; + + info.revs = &revs; + info.path_fn = fill_missing_blobs; + info.path_fn_data = ctx; + + ret = walk_objects_by_path(&info); + + /* Download the objects that did not fill a batch. */ + if (!ret) + download_batch(ctx); + + path_walk_info_clear(&info); + release_revisions(&revs); + return ret; +} + +int cmd_backfill(int argc, const char **argv, const char *prefix, struct repository *repo) +{ + int result; + struct backfill_context ctx = { + .repo = repo, + .current_batch = OID_ARRAY_INIT, + .min_batch_size = 50000, + .sparse = 0, + }; + struct option options[] = { + OPT_INTEGER(0, "min-batch-size", &ctx.min_batch_size, + N_("Minimum number of objects to request at a time")), + OPT_BOOL(0, "sparse", &ctx.sparse, + N_("Restrict the missing objects to the current sparse-checkout")), + OPT_END(), + }; + + show_usage_with_options_if_asked(argc, argv, + builtin_backfill_usage, options); + + argc = parse_options(argc, argv, prefix, options, builtin_backfill_usage, + 0); + + repo_config(repo, git_default_config, NULL); + + if (ctx.sparse < 0) + ctx.sparse = core_apply_sparse_checkout; + + result = do_backfill(&ctx); + backfill_context_clear(&ctx); + return result; +} diff --git a/builtin/blame.c b/builtin/blame.c index 7555c445ab..c470654c7e 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -1194,14 +1194,16 @@ parse_done: sb.found_guilty_entry = &found_guilty_entry; sb.found_guilty_entry_data = π if (show_progress) - pi.progress = start_delayed_progress(_("Blaming lines"), num_lines); + pi.progress = start_delayed_progress(the_repository, + _("Blaming lines"), + num_lines); assign_blame(&sb, opt); stop_progress(&pi.progress); if (!incremental) - setup_pager(); + setup_pager(the_repository); else goto cleanup; diff --git a/builtin/branch.c b/builtin/branch.c index 6e7b0cfddb..c150131bd9 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -473,7 +473,7 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin if (verify_ref_format(format)) die(_("unable to parse format string")); - filter_ahead_behind(the_repository, format, &array); + filter_ahead_behind(the_repository, &array); ref_array_sort(sorting, &array); if (column_active(colopts)) { @@ -784,8 +784,8 @@ int cmd_branch(int argc, filter.kind = FILTER_REFS_BRANCHES; filter.abbrev = -1; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_branch_usage, options); + show_usage_with_options_if_asked(argc, argv, + builtin_branch_usage, options); /* * Try to set sort keys from config. If config does not set any, @@ -884,7 +884,6 @@ int cmd_branch(int argc, string_list_clear(&output, 0); ref_sorting_release(sorting); ref_filter_clear(&filter); - ref_format_clear(&format); ret = 0; goto out; diff --git a/builtin/bugreport.c b/builtin/bugreport.c index 7c2df035c9..66d64bfd5a 100644 --- a/builtin/bugreport.c +++ b/builtin/bugreport.c @@ -12,10 +12,10 @@ #include "diagnose.h" #include "object-file.h" #include "setup.h" +#include "version.h" static void get_system_info(struct strbuf *sys_info) { - struct utsname uname_info; char *shell = NULL; /* get git version from native cmd */ @@ -24,16 +24,7 @@ static void get_system_info(struct strbuf *sys_info) /* system call for other version info */ strbuf_addstr(sys_info, "uname: "); - if (uname(&uname_info)) - strbuf_addf(sys_info, _("uname() failed with error '%s' (%d)\n"), - strerror(errno), - errno); - else - strbuf_addf(sys_info, "%s %s %s %s\n", - uname_info.sysname, - uname_info.release, - uname_info.version, - uname_info.machine); + get_uname_info(sys_info, 1); strbuf_addstr(sys_info, _("compiler info: ")); get_compiler_info(sys_info); @@ -167,7 +158,7 @@ int cmd_bugreport(int argc, strbuf_addftime(&zip_path, option_suffix, localtime_r(&now, &tm), 0, 0); strbuf_addstr(&zip_path, ".zip"); - if (create_diagnostics_archive(&zip_path, diagnose)) + if (create_diagnostics_archive(the_repository, &zip_path, diagnose)) die_errno(_("unable to create diagnostics archive %s"), zip_path.buf); strbuf_release(&zip_path); diff --git a/builtin/check-mailmap.c b/builtin/check-mailmap.c index df00b5ee13..be2cebe121 100644 --- a/builtin/check-mailmap.c +++ b/builtin/check-mailmap.c @@ -35,7 +35,7 @@ static void check_mailmap(struct string_list *mailmap, const char *contact) mail = ident.mail_begin; maillen = ident.mail_end - ident.mail_begin; } else { - name = NULL; + name = ""; namelen = 0; mail = contact; maillen = strlen(contact); diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c index cef1ffe3ce..5d80afeec0 100644 --- a/builtin/check-ref-format.c +++ b/builtin/check-ref-format.c @@ -64,8 +64,8 @@ int cmd_check_ref_format(int argc, BUG_ON_NON_EMPTY_PREFIX(prefix); - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(builtin_check_ref_format_usage); + show_usage_if_asked(argc, argv, + builtin_check_ref_format_usage); if (argc == 3 && !strcmp(argv[1], "--branch")) return check_ref_format_branch(argv[2]); diff --git a/builtin/checkout--worker.c b/builtin/checkout--worker.c index b81002a1df..da9345a44b 100644 --- a/builtin/checkout--worker.c +++ b/builtin/checkout--worker.c @@ -128,9 +128,9 @@ int cmd_checkout__worker(int argc, OPT_END() }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(checkout_worker_usage, - checkout_worker_options); + show_usage_with_options_if_asked(argc, argv, + checkout_worker_usage, + checkout_worker_options); git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, checkout_worker_options, diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c index a81501098d..e30086c7d4 100644 --- a/builtin/checkout-index.c +++ b/builtin/checkout-index.c @@ -250,9 +250,9 @@ int cmd_checkout_index(int argc, OPT_END() }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_checkout_index_usage, - builtin_checkout_index_options); + show_usage_with_options_if_asked(argc, argv, + builtin_checkout_index_usage, + builtin_checkout_index_options); git_config(git_default_config, NULL); prefix_length = prefix ? strlen(prefix) : 0; diff --git a/builtin/clone.c b/builtin/clone.c index fd001d800c..f9a2ecbe9c 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -56,42 +56,30 @@ * - dropping use-separate-remote and no-separate-remote compatibility * */ -static const char * const builtin_clone_usage[] = { - N_("git clone [<options>] [--] <repo> [<dir>]"), - NULL + +struct clone_opts { + int wants_head; + int detach; }; +#define CLONE_OPTS_INIT { \ + .wants_head = 1 /* default enabled */ \ +} static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1; static int option_local = -1, option_no_hardlinks, option_shared; -static int option_no_tags; +static int option_tags = 1; /* default enabled */ static int option_shallow_submodules; -static int option_reject_shallow = -1; /* unspecified */ static int config_reject_shallow = -1; /* unspecified */ -static int deepen; -static char *option_template, *option_depth, *option_since; -static char *option_origin = NULL; static char *remote_name = NULL; static char *option_branch = NULL; -static struct string_list option_not = STRING_LIST_INIT_NODUP; -static const char *real_git_dir; -static const char *ref_format; -static const char *option_upload_pack = "git-upload-pack"; static int option_verbosity; -static int option_progress = -1; -static int option_sparse_checkout; -static enum transport_family family; -static struct string_list option_config = STRING_LIST_INIT_NODUP; static struct string_list option_required_reference = STRING_LIST_INIT_NODUP; static struct string_list option_optional_reference = STRING_LIST_INIT_NODUP; -static int option_dissociate; static int max_jobs = -1; static struct string_list option_recurse_submodules = STRING_LIST_INIT_NODUP; static struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT; -static int option_filter_submodules = -1; /* unspecified */ static int config_filter_submodules = -1; /* unspecified */ -static struct string_list server_options = STRING_LIST_INIT_NODUP; static int option_remote_submodules; -static const char *bundle_uri; static int recurse_submodules_cb(const struct option *opt, const char *arg, int unset) @@ -107,78 +95,6 @@ static int recurse_submodules_cb(const struct option *opt, return 0; } -static struct option builtin_clone_options[] = { - OPT__VERBOSITY(&option_verbosity), - OPT_BOOL(0, "progress", &option_progress, - N_("force progress reporting")), - OPT_BOOL(0, "reject-shallow", &option_reject_shallow, - N_("don't clone shallow repository")), - OPT_BOOL('n', "no-checkout", &option_no_checkout, - N_("don't create a checkout")), - OPT_BOOL(0, "bare", &option_bare, N_("create a bare repository")), - OPT_HIDDEN_BOOL(0, "naked", &option_bare, - N_("create a bare repository")), - OPT_BOOL(0, "mirror", &option_mirror, - N_("create a mirror repository (implies --bare)")), - OPT_BOOL('l', "local", &option_local, - N_("to clone from a local repository")), - OPT_BOOL(0, "no-hardlinks", &option_no_hardlinks, - N_("don't use local hardlinks, always copy")), - OPT_BOOL('s', "shared", &option_shared, - N_("setup as shared repository")), - { OPTION_CALLBACK, 0, "recurse-submodules", &option_recurse_submodules, - N_("pathspec"), N_("initialize submodules in the clone"), - PARSE_OPT_OPTARG, recurse_submodules_cb, (intptr_t)"." }, - OPT_ALIAS(0, "recursive", "recurse-submodules"), - OPT_INTEGER('j', "jobs", &max_jobs, - N_("number of submodules cloned in parallel")), - OPT_STRING(0, "template", &option_template, N_("template-directory"), - N_("directory from which templates will be used")), - OPT_STRING_LIST(0, "reference", &option_required_reference, N_("repo"), - N_("reference repository")), - OPT_STRING_LIST(0, "reference-if-able", &option_optional_reference, - N_("repo"), N_("reference repository")), - OPT_BOOL(0, "dissociate", &option_dissociate, - N_("use --reference only while cloning")), - OPT_STRING('o', "origin", &option_origin, N_("name"), - N_("use <name> instead of 'origin' to track upstream")), - OPT_STRING('b', "branch", &option_branch, N_("branch"), - N_("checkout <branch> instead of the remote's HEAD")), - OPT_STRING('u', "upload-pack", &option_upload_pack, N_("path"), - N_("path to git-upload-pack on the remote")), - OPT_STRING(0, "depth", &option_depth, N_("depth"), - N_("create a shallow clone of that depth")), - OPT_STRING(0, "shallow-since", &option_since, N_("time"), - N_("create a shallow clone since a specific time")), - OPT_STRING_LIST(0, "shallow-exclude", &option_not, N_("ref"), - N_("deepen history of shallow clone, excluding ref")), - OPT_BOOL(0, "single-branch", &option_single_branch, - N_("clone only one branch, HEAD or --branch")), - OPT_BOOL(0, "no-tags", &option_no_tags, - N_("don't clone any tags, and make later fetches not to follow them")), - OPT_BOOL(0, "shallow-submodules", &option_shallow_submodules, - N_("any cloned submodules will be shallow")), - OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"), - N_("separate git dir from working tree")), - OPT_STRING(0, "ref-format", &ref_format, N_("format"), - N_("specify the reference format to use")), - OPT_STRING_LIST('c', "config", &option_config, N_("key=value"), - N_("set config inside the new repository")), - OPT_STRING_LIST(0, "server-option", &server_options, - N_("server-specific"), N_("option to transmit")), - OPT_IPVERSION(&family), - OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options), - OPT_BOOL(0, "also-filter-submodules", &option_filter_submodules, - N_("apply partial clone filters to submodules")), - OPT_BOOL(0, "remote-submodules", &option_remote_submodules, - N_("any cloned submodules will use their remote-tracking branch")), - OPT_BOOL(0, "sparse", &option_sparse_checkout, - N_("initialize sparse-checkout file to include only files at root")), - OPT_STRING(0, "bundle-uri", &bundle_uri, - N_("uri"), N_("a URI for downloading bundles before fetching from origin remote")), - OPT_END() -}; - static const char *get_repo_path_1(struct strbuf *path, int *is_bundle) { static const char *suffix[] = { "/.git", "", ".git/.git", ".git" }; @@ -521,51 +437,31 @@ static struct ref *find_remote_branch(const struct ref *refs, const char *branch return ref; } -static struct ref *wanted_peer_refs(const struct ref *refs, - struct refspec *refspec) +static struct ref *wanted_peer_refs(struct clone_opts *opts, + const struct ref *refs, + struct refspec *refspec) { - struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD")); - struct ref *local_refs = head; - struct ref **tail = head ? &head->next : &local_refs; - struct refspec_item tag_refspec; - - refspec_item_init(&tag_refspec, TAG_REFSPEC, 0); - - if (option_single_branch) { - struct ref *remote_head = NULL; - - if (!option_branch) - remote_head = guess_remote_head(head, refs, 0); - else { - free_one_ref(head); - local_refs = head = NULL; - tail = &local_refs; - remote_head = copy_ref(find_remote_branch(refs, option_branch)); - } - - if (!remote_head && option_branch) - warning(_("Could not find remote branch %s to clone."), - option_branch); - else { - int i; - for (i = 0; i < refspec->nr; i++) - get_fetch_map(remote_head, &refspec->items[i], - &tail, 0); - - /* if --branch=tag, pull the requested tag explicitly */ - get_fetch_map(remote_head, &tag_refspec, &tail, 0); - } - free_refs(remote_head); - } else { - int i; - for (i = 0; i < refspec->nr; i++) - get_fetch_map(refs, &refspec->items[i], &tail, 0); + struct ref *local_refs = NULL; + struct ref **tail = &local_refs; + struct ref *to_free = NULL; + + if (opts->wants_head) { + struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD")); + if (head) + tail_link_ref(head, &tail); + if (option_single_branch) + refs = to_free = guess_remote_head(head, refs, 0); + } else if (option_single_branch) { + local_refs = NULL; + tail = &local_refs; + refs = to_free = copy_ref(find_remote_branch(refs, option_branch)); } - if (!option_mirror && !option_single_branch && !option_no_tags) - get_fetch_map(refs, &tag_refspec, &tail, 0); + for (size_t i = 0; i < refspec->nr; i++) + get_fetch_map(refs, &refspec->items[i], &tail, 0); + + free_one_ref(to_free); - refspec_item_clear(&tag_refspec); return local_refs; } @@ -654,7 +550,7 @@ static void update_remote_refs(const struct ref *refs, if (refs) { write_remote_refs(mapped_refs); - if (option_single_branch && !option_no_tags) + if (option_single_branch && option_tags) write_followtags(refs, msg); } @@ -670,11 +566,11 @@ static void update_remote_refs(const struct ref *refs, } } -static void update_head(const struct ref *our, const struct ref *remote, +static void update_head(struct clone_opts *opts, const struct ref *our, const struct ref *remote, const char *unborn, const char *msg) { const char *head; - if (our && skip_prefix(our->name, "refs/heads/", &head)) { + if (our && !opts->detach && skip_prefix(our->name, "refs/heads/", &head)) { /* Local default branch link */ if (refs_update_symref(get_main_ref_store(the_repository), "HEAD", our->name, NULL) < 0) die(_("unable to update HEAD")); @@ -685,8 +581,9 @@ static void update_head(const struct ref *our, const struct ref *remote, install_branch_config(0, head, remote_name, our->name); } } else if (our) { - struct commit *c = lookup_commit_reference(the_repository, - &our->old_oid); + struct commit *c = lookup_commit_or_die(&our->old_oid, + our->name); + /* --branch specifies a non-branch (i.e. tags), detach HEAD */ refs_update_ref(get_main_ref_store(the_repository), msg, "HEAD", &c->object.oid, NULL, REF_NO_DEREF, @@ -989,10 +886,108 @@ int cmd_clone(int argc, int hash_algo; enum ref_storage_format ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN; const int do_not_override_repo_unix_permissions = -1; + int option_reject_shallow = -1; /* unspecified */ + int deepen = 0; + char *option_template = NULL, *option_depth = NULL, *option_since = NULL; + char *option_origin = NULL; + struct string_list option_not = STRING_LIST_INIT_NODUP; + const char *real_git_dir = NULL; + const char *ref_format = NULL; + const char *option_upload_pack = "git-upload-pack"; + int option_progress = -1; + int option_sparse_checkout = 0; + enum transport_family family = TRANSPORT_FAMILY_ALL; + struct string_list option_config = STRING_LIST_INIT_DUP; + int option_dissociate = 0; + int option_filter_submodules = -1; /* unspecified */ + struct string_list server_options = STRING_LIST_INIT_NODUP; + const char *bundle_uri = NULL; + char *option_rev = NULL; + + struct clone_opts opts = CLONE_OPTS_INIT; struct transport_ls_refs_options transport_ls_refs_options = TRANSPORT_LS_REFS_OPTIONS_INIT; + struct option builtin_clone_options[] = { + OPT__VERBOSITY(&option_verbosity), + OPT_BOOL(0, "progress", &option_progress, + N_("force progress reporting")), + OPT_BOOL(0, "reject-shallow", &option_reject_shallow, + N_("don't clone shallow repository")), + OPT_BOOL('n', "no-checkout", &option_no_checkout, + N_("don't create a checkout")), + OPT_BOOL(0, "bare", &option_bare, N_("create a bare repository")), + OPT_HIDDEN_BOOL(0, "naked", &option_bare, + N_("create a bare repository")), + OPT_BOOL(0, "mirror", &option_mirror, + N_("create a mirror repository (implies --bare)")), + OPT_BOOL('l', "local", &option_local, + N_("to clone from a local repository")), + OPT_BOOL(0, "no-hardlinks", &option_no_hardlinks, + N_("don't use local hardlinks, always copy")), + OPT_BOOL('s', "shared", &option_shared, + N_("setup as shared repository")), + { OPTION_CALLBACK, 0, "recurse-submodules", &option_recurse_submodules, + N_("pathspec"), N_("initialize submodules in the clone"), + PARSE_OPT_OPTARG, recurse_submodules_cb, (intptr_t)"." }, + OPT_ALIAS(0, "recursive", "recurse-submodules"), + OPT_INTEGER('j', "jobs", &max_jobs, + N_("number of submodules cloned in parallel")), + OPT_STRING(0, "template", &option_template, N_("template-directory"), + N_("directory from which templates will be used")), + OPT_STRING_LIST(0, "reference", &option_required_reference, N_("repo"), + N_("reference repository")), + OPT_STRING_LIST(0, "reference-if-able", &option_optional_reference, + N_("repo"), N_("reference repository")), + OPT_BOOL(0, "dissociate", &option_dissociate, + N_("use --reference only while cloning")), + OPT_STRING('o', "origin", &option_origin, N_("name"), + N_("use <name> instead of 'origin' to track upstream")), + OPT_STRING('b', "branch", &option_branch, N_("branch"), + N_("checkout <branch> instead of the remote's HEAD")), + OPT_STRING(0, "revision", &option_rev, N_("rev"), + N_("clone single revision <rev> and check out")), + OPT_STRING('u', "upload-pack", &option_upload_pack, N_("path"), + N_("path to git-upload-pack on the remote")), + OPT_STRING(0, "depth", &option_depth, N_("depth"), + N_("create a shallow clone of that depth")), + OPT_STRING(0, "shallow-since", &option_since, N_("time"), + N_("create a shallow clone since a specific time")), + OPT_STRING_LIST(0, "shallow-exclude", &option_not, N_("ref"), + N_("deepen history of shallow clone, excluding ref")), + OPT_BOOL(0, "single-branch", &option_single_branch, + N_("clone only one branch, HEAD or --branch")), + OPT_BOOL(0, "tags", &option_tags, + N_("clone tags, and make later fetches not to follow them")), + OPT_BOOL(0, "shallow-submodules", &option_shallow_submodules, + N_("any cloned submodules will be shallow")), + OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"), + N_("separate git dir from working tree")), + OPT_STRING(0, "ref-format", &ref_format, N_("format"), + N_("specify the reference format to use")), + OPT_STRING_LIST('c', "config", &option_config, N_("key=value"), + N_("set config inside the new repository")), + OPT_STRING_LIST(0, "server-option", &server_options, + N_("server-specific"), N_("option to transmit")), + OPT_IPVERSION(&family), + OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options), + OPT_BOOL(0, "also-filter-submodules", &option_filter_submodules, + N_("apply partial clone filters to submodules")), + OPT_BOOL(0, "remote-submodules", &option_remote_submodules, + N_("any cloned submodules will use their remote-tracking branch")), + OPT_BOOL(0, "sparse", &option_sparse_checkout, + N_("initialize sparse-checkout file to include only files at root")), + OPT_STRING(0, "bundle-uri", &bundle_uri, + N_("uri"), N_("a URI for downloading bundles before fetching from origin remote")), + OPT_END() + }; + + const char * const builtin_clone_usage[] = { + N_("git clone [<options>] [--] <repo> [<dir>]"), + NULL + }; + packet_trace_identity("clone"); git_config(git_clone_config, NULL); @@ -1019,8 +1014,10 @@ int cmd_clone(int argc, die(_("unknown ref storage format '%s'"), ref_format); } - if (option_mirror) + if (option_mirror) { option_bare = 1; + option_tags = 0; + } if (option_bare) { if (real_git_dir) @@ -1138,8 +1135,8 @@ int cmd_clone(int argc, for_each_string_list_item(item, &option_recurse_submodules) { strbuf_addf(&sb, "submodule.active=%s", item->string); - string_list_append(&option_config, - strbuf_detach(&sb, NULL)); + string_list_append(&option_config, sb.buf); + strbuf_reset(&sb); } if (!git_config_get_bool("submodule.stickyRecursiveClone", &val) && @@ -1161,6 +1158,8 @@ int cmd_clone(int argc, string_list_append(&option_config, "submodule.alternateErrorStrategy=info"); } + + strbuf_release(&sb); } /* @@ -1285,7 +1284,7 @@ int cmd_clone(int argc, strbuf_addstr(&branch_top, src_ref_prefix); git_config_set("core.bare", "true"); - } else { + } else if (!option_rev) { strbuf_addf(&branch_top, "refs/remotes/%s/", remote_name); } @@ -1293,7 +1292,7 @@ int cmd_clone(int argc, git_config_set(key.buf, repo); strbuf_reset(&key); - if (option_no_tags) { + if (!option_tags) { strbuf_addf(&key, "remote.%s.tagOpt", remote_name); git_config_set(key.buf, "--no-tags"); strbuf_reset(&key); @@ -1304,8 +1303,9 @@ int cmd_clone(int argc, remote = remote_get_early(remote_name); - refspec_appendf(&remote->fetch, "+%s*:%s*", src_ref_prefix, - branch_top.buf); + if (!option_rev) + refspec_appendf(&remote->fetch, "+%s*:%s*", src_ref_prefix, + branch_top.buf); path = get_repo_path(remote->url.v[0], &is_bundle); is_local = option_local != 0 && path && !is_bundle; @@ -1348,6 +1348,11 @@ int cmd_clone(int argc, transport_set_option(transport, TRANS_OPT_KEEP, "yes"); + die_for_incompatible_opt2(!!option_rev, "--revision", + !!option_branch, "--branch"); + die_for_incompatible_opt2(!!option_rev, "--revision", + option_mirror, "--mirror"); + if (reject_shallow) transport_set_option(transport, TRANS_OPT_REJECT_SHALLOW, "1"); if (option_depth) @@ -1359,9 +1364,13 @@ int cmd_clone(int argc, if (option_not.nr) transport_set_option(transport, TRANS_OPT_DEEPEN_NOT, (const char *)&option_not); - if (option_single_branch) + if (option_single_branch) { transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1"); + if (option_branch) + opts.wants_head = 0; + } + if (option_upload_pack) transport_set_option(transport, TRANS_OPT_UPLOADPACK, option_upload_pack); @@ -1380,15 +1389,38 @@ int cmd_clone(int argc, if (transport->smart_options && !deepen && !filter_options.choice) transport->smart_options->check_self_contained_and_connected = 1; - strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD"); + if (option_rev) { + option_tags = 0; + option_single_branch = 0; + opts.wants_head = 0; + opts.detach = 1; + + refspec_append(&remote->fetch, option_rev); + } + + if (option_tags || option_branch) + /* + * Add tags refspec when user asked for tags (implicitly) or + * specified --branch, whose argument might be a tag. + */ + refspec_append(&remote->fetch, TAG_REFSPEC); + refspec_ref_prefixes(&remote->fetch, &transport_ls_refs_options.ref_prefixes); if (option_branch) expand_ref_prefix(&transport_ls_refs_options.ref_prefixes, option_branch); - if (!option_no_tags) - strvec_push(&transport_ls_refs_options.ref_prefixes, - "refs/tags/"); + + /* + * As part of transport_get_remote_refs() the server tells us the hash + * algorithm, which we require to initialize the repo. But calling that + * function without any ref prefix, will cause the server to announce + * all known refs. If the argument passed to --revision was a hex oid, + * ref_prefixes will be empty so we fall back to asking about HEAD to + * reduce traffic from the server. + */ + if (opts.wants_head || transport_ls_refs_options.ref_prefixes.nr == 0) + strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD"); refs = transport_get_remote_refs(transport, &transport_ls_refs_options); @@ -1465,7 +1497,7 @@ int cmd_clone(int argc, } if (refs) - mapped_refs = wanted_peer_refs(refs, &remote->fetch); + mapped_refs = wanted_peer_refs(&opts, refs, &remote->fetch); if (mapped_refs) { /* @@ -1498,6 +1530,11 @@ int cmd_clone(int argc, if (!our_head_points_at) die(_("Remote branch %s not found in upstream %s"), option_branch, remote_name); + } else if (option_rev) { + our_head_points_at = mapped_refs; + if (!our_head_points_at) + die(_("Remote revision %s not found in upstream %s"), + option_rev, remote_name); } else if (remote_head_points_at) { our_head_points_at = remote_head_points_at; } else if (remote_head) { @@ -1536,8 +1573,9 @@ int cmd_clone(int argc, free(to_free); } - write_refspec_config(src_ref_prefix, our_head_points_at, - remote_head_points_at, &branch_top); + if (!option_rev) + write_refspec_config(src_ref_prefix, our_head_points_at, + remote_head_points_at, &branch_top); if (filter_options.choice) partial_clone_register(remote_name, &filter_options); @@ -1553,7 +1591,7 @@ int cmd_clone(int argc, branch_top.buf, reflog_msg.buf, transport, !is_local); - update_head(our_head_points_at, remote_head, unborn_head, reflog_msg.buf); + update_head(&opts, our_head_points_at, remote_head, unborn_head, reflog_msg.buf); /* * We want to show progress for recursive submodule clones iff @@ -1578,6 +1616,10 @@ int cmd_clone(int argc, err = checkout(submodule_progress, filter_submodules, ref_storage_format); + string_list_clear(&option_not, 0); + string_list_clear(&option_config, 0); + string_list_clear(&server_options, 0); + free(remote_name); strbuf_release(&reflog_msg); strbuf_release(&branch_top); diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index bd70d052e7..8ca75262c5 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -305,6 +305,7 @@ static int graph_write(int argc, const char **argv, const char *prefix, oidset_init(&commits, 0); if (opts.progress) progress = start_delayed_progress( + the_repository, _("Collecting commits from input"), 0); while (strbuf_getline(&buf, stdin) != EOF) { diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index 2ca1a57ebb..38457600a4 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -119,8 +119,8 @@ int cmd_commit_tree(int argc, git_config(git_default_config, NULL); - if (argc < 2 || !strcmp(argv[1], "-h")) - usage_with_options(commit_tree_usage, options); + show_usage_with_options_if_asked(argc, argv, + commit_tree_usage, options); argc = parse_options(argc, argv, prefix, options, commit_tree_usage, 0); diff --git a/builtin/commit.c b/builtin/commit.c index ef5e622c07..9fb405dd4a 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -44,7 +44,7 @@ #include "trailer.h" static const char * const builtin_commit_usage[] = { - N_("git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" + N_("git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" @@ -1559,8 +1559,8 @@ struct repository *repo UNUSED) OPT_END(), }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_status_usage, builtin_status_options); + show_usage_with_options_if_asked(argc, argv, + builtin_status_usage, builtin_status_options); prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; @@ -1736,8 +1736,8 @@ int cmd_commit(int argc, struct strbuf err = STRBUF_INIT; int ret = 0; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_commit_usage, builtin_commit_options); + show_usage_with_options_if_asked(argc, argv, + builtin_commit_usage, builtin_commit_options); prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/credential-cache--daemon.c b/builtin/credential-cache--daemon.c index bc22f5c6d2..e707618e74 100644 --- a/builtin/credential-cache--daemon.c +++ b/builtin/credential-cache--daemon.c @@ -142,9 +142,9 @@ static void serve_one_client(FILE *in, FILE *out) fprintf(out, "username=%s\n", e->item.username); if (e->item.password) fprintf(out, "password=%s\n", e->item.password); - if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_HELPER) && e->item.authtype) + if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_RESPONSE) && e->item.authtype) fprintf(out, "authtype=%s\n", e->item.authtype); - if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_HELPER) && e->item.credential) + if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_RESPONSE) && e->item.credential) fprintf(out, "credential=%s\n", e->item.credential); if (e->item.password_expiry_utc != TIME_MAX) fprintf(out, "password_expiry_utc=%"PRItime"\n", diff --git a/builtin/credential.c b/builtin/credential.c index 14c8c6608b..2e11b15dde 100644 --- a/builtin/credential.c +++ b/builtin/credential.c @@ -18,7 +18,8 @@ int cmd_credential(int argc, git_config(git_default_config, NULL); - if (argc != 2 || !strcmp(argv[1], "-h")) + show_usage_if_asked(argc, argv, usage_msg); + if (argc != 2) usage(usage_msg); op = argv[1]; @@ -32,15 +33,15 @@ int cmd_credential(int argc, die("unable to read credential from stdin"); if (!strcmp(op, "fill")) { - credential_fill(&c, 0); + credential_fill(the_repository, &c, 0); credential_next_state(&c); credential_write(&c, stdout, CREDENTIAL_OP_RESPONSE); } else if (!strcmp(op, "approve")) { credential_set_all_capabilities(&c, CREDENTIAL_OP_HELPER); - credential_approve(&c); + credential_approve(the_repository, &c); } else if (!strcmp(op, "reject")) { credential_set_all_capabilities(&c, CREDENTIAL_OP_HELPER); - credential_reject(&c); + credential_reject(the_repository, &c); } else { usage(usage_msg); } diff --git a/builtin/diagnose.c b/builtin/diagnose.c index 66a22d918e..33c39bd598 100644 --- a/builtin/diagnose.c +++ b/builtin/diagnose.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "abspath.h" #include "gettext.h" @@ -58,7 +60,7 @@ int cmd_diagnose(int argc, } /* Prepare diagnostics */ - if (create_diagnostics_archive(&zip_path, mode)) + if (create_diagnostics_archive(the_repository, &zip_path, mode)) die_errno(_("unable to create diagnostics archive %s"), zip_path.buf); diff --git a/builtin/diff-files.c b/builtin/diff-files.c index 604b04bb2c..99b1749723 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -29,8 +29,7 @@ int cmd_diff_files(int argc, int result; unsigned options = 0; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(diff_files_usage); + show_usage_if_asked(argc, argv, diff_files_usage); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ diff --git a/builtin/diff-index.c b/builtin/diff-index.c index ebc824602e..81c0bc8ed7 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -26,8 +26,7 @@ int cmd_diff_index(int argc, int i; int result; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(diff_cache_usage); + show_usage_if_asked(argc, argv, diff_cache_usage); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index 40804e7b48..e31cc797fe 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -122,8 +122,7 @@ int cmd_diff_tree(int argc, int read_stdin = 0; int merge_base = 0; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(diff_tree_usage); + show_usage_if_asked(argc, argv, diff_tree_usage); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ diff --git a/builtin/difftool.c b/builtin/difftool.c index 03a8bb92a9..41cd00066c 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -12,8 +12,6 @@ * Copyright (C) 2016 Johannes Schindelin */ -#define USE_THE_REPOSITORY_VARIABLE - #include "builtin.h" #include "abspath.h" @@ -36,18 +34,27 @@ #include "entry.h" #include "setup.h" -static int trust_exit_code; - static const char *const builtin_difftool_usage[] = { N_("git difftool [<options>] [<commit> [<commit>]] [--] [<path>...]"), NULL }; +struct difftool_options { + int has_symlinks; + int symlinks; + int trust_exit_code; +}; + static int difftool_config(const char *var, const char *value, const struct config_context *ctx, void *cb) { + struct difftool_options *dt_options = (struct difftool_options *)cb; if (!strcmp(var, "difftool.trustexitcode")) { - trust_exit_code = git_config_bool(var, value); + dt_options->trust_exit_code = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "core.symlinks")) { + dt_options->has_symlinks = git_config_bool(var, value); return 0; } @@ -63,7 +70,8 @@ static int print_tool_help(void) return run_command(&cmd); } -static int parse_index_info(char *p, int *mode1, int *mode2, +static int parse_index_info(struct repository *repo, + char *p, int *mode1, int *mode2, struct object_id *oid1, struct object_id *oid2, char *status) { @@ -75,11 +83,11 @@ static int parse_index_info(char *p, int *mode1, int *mode2, *mode2 = (int)strtol(p + 1, &p, 8); if (*p != ' ') return error("expected ' ', got '%c'", *p); - if (parse_oid_hex(++p, oid1, (const char **)&p)) + if (parse_oid_hex_algop(++p, oid1, (const char **)&p, repo->hash_algo)) return error("expected object ID, got '%s'", p); if (*p != ' ') return error("expected ' ', got '%c'", *p); - if (parse_oid_hex(++p, oid2, (const char **)&p)) + if (parse_oid_hex_algop(++p, oid2, (const char **)&p, repo->hash_algo)) return error("expected object ID, got '%s'", p); if (*p != ' ') return error("expected ' ', got '%c'", *p); @@ -106,7 +114,8 @@ static void add_path(struct strbuf *buf, size_t base_len, const char *path) /* * Determine whether we can simply reuse the file in the worktree. */ -static int use_wt_file(const char *workdir, const char *name, +static int use_wt_file(struct repository *repo, + const char *workdir, const char *name, struct object_id *oid) { struct strbuf buf = STRBUF_INIT; @@ -121,7 +130,7 @@ static int use_wt_file(const char *workdir, const char *name, int fd = open(buf.buf, O_RDONLY); if (fd >= 0 && - !index_fd(the_repository->index, &wt_oid, fd, &st, OBJ_BLOB, name, 0)) { + !index_fd(repo->index, &wt_oid, fd, &st, OBJ_BLOB, name, 0)) { if (is_null_oid(oid)) { oidcpy(oid, &wt_oid); use = 1; @@ -212,13 +221,14 @@ static int path_entry_cmp(const void *cmp_data UNUSED, return strcmp(a->path, key ? key : b->path); } -static void changed_files(struct hashmap *result, const char *index_path, +static void changed_files(struct repository *repo, + struct hashmap *result, const char *index_path, const char *workdir) { struct child_process update_index = CHILD_PROCESS_INIT; struct child_process diff_files = CHILD_PROCESS_INIT; struct strbuf buf = STRBUF_INIT; - const char *git_dir = absolute_path(repo_get_git_dir(the_repository)); + const char *git_dir = absolute_path(repo_get_git_dir(repo)); FILE *fp; strvec_pushl(&update_index.args, @@ -291,13 +301,15 @@ static int ensure_leading_directories(char *path) * to compare the readlink(2) result as text, even on a filesystem that is * capable of doing a symbolic link. */ -static char *get_symlink(const struct object_id *oid, const char *path) +static char *get_symlink(struct repository *repo, + struct difftool_options *dt_options, + const struct object_id *oid, const char *path) { char *data; if (is_null_oid(oid)) { /* The symlink is unknown to Git so read from the filesystem */ struct strbuf link = STRBUF_INIT; - if (has_symlinks) { + if (dt_options->has_symlinks) { if (strbuf_readlink(&link, path, strlen(path))) die(_("could not read symlink %s"), path); } else if (strbuf_read_file(&link, path, 128)) @@ -307,8 +319,7 @@ static char *get_symlink(const struct object_id *oid, const char *path) } else { enum object_type type; unsigned long size; - data = repo_read_object_file(the_repository, oid, &type, - &size); + data = repo_read_object_file(repo, oid, &type, &size); if (!data) die(_("could not read object %s for symlink %s"), oid_to_hex(oid), path); @@ -355,7 +366,9 @@ static void write_standin_files(struct pair_entry *entry, write_file_in_directory(rdir, rdir_len, entry->path, entry->right); } -static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, +static int run_dir_diff(struct repository *repo, + struct difftool_options *dt_options, + const char *extcmd, const char *prefix, struct child_process *child) { struct strbuf info = STRBUF_INIT, lpath = STRBUF_INIT; @@ -375,7 +388,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, struct hashmap symlinks2 = HASHMAP_INIT(pair_cmp, NULL); struct hashmap_iter iter; struct pair_entry *entry; - struct index_state wtindex = INDEX_STATE_INIT(the_repository); + struct index_state wtindex = INDEX_STATE_INIT(repo); struct checkout lstate, rstate; int err = 0; struct child_process cmd = CHILD_PROCESS_INIT; @@ -383,7 +396,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, struct hashmap tmp_modified = HASHMAP_INIT(path_entry_cmp, NULL); int indices_loaded = 0; - workdir = repo_get_work_tree(the_repository); + workdir = repo_get_work_tree(repo); /* Setup temp directories */ tmp = getenv("TMPDIR"); @@ -438,8 +451,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, "not supported in\n" "directory diff mode ('-d' and '--dir-diff').")); - if (parse_index_info(info.buf, &lmode, &rmode, &loid, &roid, - &status)) + if (parse_index_info(repo, info.buf, &lmode, &rmode, &loid, &roid, &status)) break; if (strbuf_getline_nul(&lpath, fp)) break; @@ -469,13 +481,13 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, } if (S_ISLNK(lmode)) { - char *content = get_symlink(&loid, src_path); + char *content = get_symlink(repo, dt_options, &loid, src_path); add_left_or_right(&symlinks2, src_path, content, 0); free(content); } if (S_ISLNK(rmode)) { - char *content = get_symlink(&roid, dst_path); + char *content = get_symlink(repo, dt_options, &roid, dst_path); add_left_or_right(&symlinks2, dst_path, content, 1); free(content); } @@ -500,7 +512,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, } hashmap_add(&working_tree_dups, &entry->entry); - if (!use_wt_file(workdir, dst_path, &roid)) { + if (!use_wt_file(repo, workdir, dst_path, &roid)) { if (checkout_path(rmode, &roid, dst_path, &rstate)) { ret = error("could not write '%s'", @@ -528,7 +540,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, goto finish; } add_path(&wtdir, wtdir_len, dst_path); - if (symlinks) { + if (dt_options->symlinks) { if (symlink(wtdir.buf, rdir.buf)) { ret = error_errno("could not symlink '%s' to '%s'", wtdir.buf, rdir.buf); goto finish; @@ -614,7 +626,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, if (lstat(rdir.buf, &st)) continue; - if ((symlinks && S_ISLNK(st.st_mode)) || !S_ISREG(st.st_mode)) + if ((dt_options->symlinks && S_ISLNK(st.st_mode)) || !S_ISREG(st.st_mode)) continue; if (!indices_loaded) { @@ -626,9 +638,9 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, ret = error("could not write %s", buf.buf); goto finish; } - changed_files(&wt_modified, buf.buf, workdir); + changed_files(repo, &wt_modified, buf.buf, workdir); strbuf_setlen(&rdir, rdir_len); - changed_files(&tmp_modified, buf.buf, rdir.buf); + changed_files(repo, &tmp_modified, buf.buf, rdir.buf); add_path(&rdir, rdir_len, name); indices_loaded = 1; } @@ -702,11 +714,15 @@ static int run_file_diff(int prompt, const char *prefix, int cmd_difftool(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { - int use_gui_tool = -1, dir_diff = 0, prompt = -1, symlinks = 0, - tool_help = 0, no_index = 0; + int use_gui_tool = -1, dir_diff = 0, prompt = -1, tool_help = 0, no_index = 0; static char *difftool_cmd = NULL, *extcmd = NULL; + struct difftool_options dt_options = { + .has_symlinks = 1, + .symlinks = 1, + .trust_exit_code = 0 + }; struct option builtin_difftool_options[] = { OPT_BOOL('g', "gui", &use_gui_tool, N_("use `diff.guitool` instead of `diff.tool`")), @@ -717,14 +733,14 @@ int cmd_difftool(int argc, 0, PARSE_OPT_NONEG), OPT_SET_INT_F(0, "prompt", &prompt, NULL, 1, PARSE_OPT_NONEG | PARSE_OPT_HIDDEN), - OPT_BOOL(0, "symlinks", &symlinks, + OPT_BOOL(0, "symlinks", &dt_options.symlinks, N_("use symlinks in dir-diff mode")), OPT_STRING('t', "tool", &difftool_cmd, N_("tool"), N_("use the specified diff tool")), OPT_BOOL(0, "tool-help", &tool_help, N_("print a list of diff tools that may be used with " "`--tool`")), - OPT_BOOL(0, "trust-exit-code", &trust_exit_code, + OPT_BOOL(0, "trust-exit-code", &dt_options.trust_exit_code, N_("make 'git-difftool' exit when an invoked diff " "tool returns a non-zero exit code")), OPT_STRING('x', "extcmd", &extcmd, N_("command"), @@ -734,8 +750,9 @@ int cmd_difftool(int argc, }; struct child_process child = CHILD_PROCESS_INIT; - git_config(difftool_config, NULL); - symlinks = has_symlinks; + if (repo) + repo_config(repo, difftool_config, &dt_options); + dt_options.symlinks = dt_options.has_symlinks; argc = parse_options(argc, argv, prefix, builtin_difftool_options, builtin_difftool_usage, PARSE_OPT_KEEP_UNKNOWN_OPT | @@ -749,8 +766,8 @@ int cmd_difftool(int argc, if (!no_index){ setup_work_tree(); - setenv(GIT_DIR_ENVIRONMENT, absolute_path(repo_get_git_dir(the_repository)), 1); - setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(repo_get_work_tree(the_repository)), 1); + setenv(GIT_DIR_ENVIRONMENT, absolute_path(repo_get_git_dir(repo)), 1); + setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(repo_get_work_tree(repo)), 1); } else if (dir_diff) die(_("options '%s' and '%s' cannot be used together"), "--dir-diff", "--no-index"); @@ -783,7 +800,7 @@ int cmd_difftool(int argc, } setenv("GIT_DIFFTOOL_TRUST_EXIT_CODE", - trust_exit_code ? "true" : "false", 1); + dt_options.trust_exit_code ? "true" : "false", 1); /* * In directory diff mode, 'git-difftool--helper' is called once @@ -799,6 +816,6 @@ int cmd_difftool(int argc, strvec_pushv(&child.args, argv); if (dir_diff) - return run_dir_diff(extcmd, symlinks, prefix, &child); + return run_dir_diff(repo, &dt_options, extcmd, prefix, &child); return run_file_diff(prompt, prefix, &child); } diff --git a/builtin/fast-import.c b/builtin/fast-import.c index 0f86392761..d6a368a566 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -798,8 +798,8 @@ static const char *create_index(void) if (c != last) die("internal consistency error creating the index"); - tmpfile = write_idx_file(NULL, idx, object_count, &pack_idx_opts, - pack_data->hash); + tmpfile = write_idx_file(the_hash_algo, NULL, idx, object_count, + &pack_idx_opts, pack_data->hash); free(idx); return tmpfile; } @@ -878,9 +878,10 @@ static void end_packfile(void) close_pack_windows(pack_data); finalize_hashfile(pack_file, cur_pack_oid.hash, FSYNC_COMPONENT_PACK, 0); - fixup_pack_header_footer(pack_data->pack_fd, pack_data->hash, - pack_data->pack_name, object_count, - cur_pack_oid.hash, pack_size); + fixup_pack_header_footer(the_hash_algo, pack_data->pack_fd, + pack_data->hash, pack_data->pack_name, + object_count, cur_pack_oid.hash, + pack_size); if (object_count <= unpack_limit) { if (!loosen_small_pack(pack_data)) { @@ -953,15 +954,15 @@ static int store_object( unsigned char hdr[96]; struct object_id oid; unsigned long hdrlen, deltalen; - git_hash_ctx c; + struct git_hash_ctx c; git_zstream s; hdrlen = format_object_header((char *)hdr, sizeof(hdr), type, dat->len); the_hash_algo->init_fn(&c); - the_hash_algo->update_fn(&c, hdr, hdrlen); - the_hash_algo->update_fn(&c, dat->buf, dat->len); - the_hash_algo->final_oid_fn(&oid, &c); + git_hash_update(&c, hdr, hdrlen); + git_hash_update(&c, dat->buf, dat->len); + git_hash_final_oid(&oid, &c); if (oidout) oidcpy(oidout, &oid); @@ -1095,7 +1096,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark) struct object_id oid; unsigned long hdrlen; off_t offset; - git_hash_ctx c; + struct git_hash_ctx c; git_zstream s; struct hashfile_checkpoint checkpoint; int status = Z_OK; @@ -1106,14 +1107,14 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark) || (pack_size + PACK_SIZE_THRESHOLD + len) < pack_size) cycle_packfile(); - the_hash_algo->unsafe_init_fn(&checkpoint.ctx); + hashfile_checkpoint_init(pack_file, &checkpoint); hashfile_checkpoint(pack_file, &checkpoint); offset = checkpoint.offset; hdrlen = format_object_header((char *)out_buf, out_sz, OBJ_BLOB, len); the_hash_algo->init_fn(&c); - the_hash_algo->update_fn(&c, out_buf, hdrlen); + git_hash_update(&c, out_buf, hdrlen); crc32_begin(pack_file); @@ -1131,7 +1132,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark) if (!n && feof(stdin)) die("EOF in data (%" PRIuMAX " bytes remaining)", len); - the_hash_algo->update_fn(&c, in_buf, n); + git_hash_update(&c, in_buf, n); s.next_in = in_buf; s.avail_in = n; len -= n; @@ -1157,7 +1158,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark) } } git_deflate_end(&s); - the_hash_algo->final_oid_fn(&oid, &c); + git_hash_final_oid(&oid, &c); if (oidout) oidcpy(oidout, &oid); @@ -3565,8 +3566,7 @@ int cmd_fast_import(int argc, { unsigned int i; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(fast_import_usage); + show_usage_if_asked(argc, argv, fast_import_usage); reset_pack_idx_option(&pack_idx_opts); git_pack_config(); diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c index bed2816c2d..d07eec9e55 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -75,6 +75,8 @@ int cmd_fetch_pack(int argc, list_objects_filter_init(&args.filter_options); args.uploadpack = "git-upload-pack"; + show_usage_if_asked(argc, argv, fetch_pack_usage); + for (i = 1; i < argc && *argv[i] == '-'; i++) { const char *arg = argv[i]; diff --git a/builtin/fetch.c b/builtin/fetch.c index fe2b26c74a..1c740d5aac 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1617,13 +1617,13 @@ static void report_set_head(const char *remote, const char *head_name, strbuf_release(&buf_prefix); } -static int set_head(const struct ref *remote_refs, int follow_remote_head, - const char *no_warn_branch) +static int set_head(const struct ref *remote_refs, struct remote *remote) { - int result = 0, create_only, is_bare, was_detached; + int result = 0, create_only, baremirror, was_detached; struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT, b_local_head = STRBUF_INIT; - const char *remote = gtransport->remote->name; + int follow_remote_head = remote->follow_remote_head; + const char *no_warn_branch = remote->no_warn_branch; char *head_name = NULL; struct ref *ref, *matches; struct ref *fetch_map = NULL, **fetch_map_tail = &fetch_map; @@ -1655,17 +1655,17 @@ static int set_head(const struct ref *remote_refs, int follow_remote_head, if (!head_name) goto cleanup; - is_bare = is_bare_repository(); - create_only = follow_remote_head == FOLLOW_REMOTE_ALWAYS ? 0 : !is_bare; - if (is_bare) { + baremirror = is_bare_repository() && remote->mirror; + create_only = follow_remote_head == FOLLOW_REMOTE_ALWAYS ? 0 : !baremirror; + if (baremirror) { strbuf_addstr(&b_head, "HEAD"); strbuf_addf(&b_remote_head, "refs/heads/%s", head_name); } else { - strbuf_addf(&b_head, "refs/remotes/%s/HEAD", remote); - strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote, head_name); + strbuf_addf(&b_head, "refs/remotes/%s/HEAD", remote->name); + strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote->name, head_name); } /* make sure it's valid */ - if (!is_bare && !refs_ref_exists(refs, b_remote_head.buf)) { + if (!baremirror && !refs_ref_exists(refs, b_remote_head.buf)) { result = 1; goto cleanup; } @@ -1678,7 +1678,7 @@ static int set_head(const struct ref *remote_refs, int follow_remote_head, if (verbosity >= 0 && follow_remote_head == FOLLOW_REMOTE_WARN && (!no_warn_branch || strcmp(no_warn_branch, head_name))) - report_set_head(remote, head_name, &b_local_head, was_detached); + report_set_head(remote->name, head_name, &b_local_head, was_detached); cleanup: free(head_name); @@ -1924,8 +1924,7 @@ static int do_fetch(struct transport *transport, "you need to specify exactly one branch with the --set-upstream option")); } } - if (set_head(remote_refs, transport->remote->follow_remote_head, - transport->remote->no_warn_branch)) + if (set_head(remote_refs, transport->remote)) ; /* * Way too many cases where this can go wrong diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 715745a262..8085ebd8fe 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -108,7 +108,6 @@ int cmd_for_each_ref(int argc, filter_and_format_refs(&filter, flags, sorting, &format); ref_filter_clear(&filter); - ref_format_clear(&format); ref_sorting_release(sorting); strvec_clear(&vec); return 0; diff --git a/builtin/fsck.c b/builtin/fsck.c index 0196c54eb6..7a4dcb0716 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -197,7 +197,8 @@ static int traverse_reachable(void) unsigned int nr = 0; int result = 0; if (show_progress) - progress = start_delayed_progress(_("Checking connectivity"), 0); + progress = start_delayed_progress(the_repository, + _("Checking connectivity"), 0); while (pending.nr) { result |= traverse_one_object(object_array_pop(&pending)); display_progress(progress, ++nr); @@ -703,7 +704,8 @@ static void fsck_object_dir(const char *path) fprintf_ln(stderr, _("Checking object directory")); if (show_progress) - progress = start_progress(_("Checking object directories"), 256); + progress = start_progress(the_repository, + _("Checking object directories"), 256); for_each_loose_file_in_objdir(path, fsck_loose, fsck_cruft, fsck_subdir, &cb_data); @@ -879,7 +881,8 @@ static int check_pack_rev_indexes(struct repository *r, int show_progress) if (show_progress) { for (struct packed_git *p = get_all_packs(r); p; p = p->next) pack_count++; - progress = start_delayed_progress("Verifying reverse pack-indexes", pack_count); + progress = start_delayed_progress(the_repository, + "Verifying reverse pack-indexes", pack_count); pack_count = 0; } @@ -989,7 +992,8 @@ int cmd_fsck(int argc, total += p->num_objects; } - progress = start_progress(_("Checking objects"), total); + progress = start_progress(the_repository, + _("Checking objects"), total); } for (p = get_all_packs(the_repository); p; p = p->next) { diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index 029dc64d6c..0820e524f1 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -1598,8 +1598,8 @@ int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix UNUSED OPT_END() }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_fsmonitor__daemon_usage, options); + show_usage_with_options_if_asked(argc, argv, + builtin_fsmonitor__daemon_usage, options); die(_("fsmonitor--daemon not supported on this platform")); } diff --git a/builtin/gc.c b/builtin/gc.c index a9b1c36de2..409d454a4b 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -139,6 +139,7 @@ struct gc_config { char *prune_worktrees_expire; char *repack_filter; char *repack_filter_to; + char *repack_expire_to; unsigned long big_pack_threshold; unsigned long max_delta_cache_size; /* @@ -445,7 +446,8 @@ static int keep_one_pack(struct string_list_item *item, void *data UNUSED) static void add_repack_all_option(struct gc_config *cfg, struct string_list *keep_pack) { - if (cfg->prune_expire && !strcmp(cfg->prune_expire, "now")) + if (cfg->prune_expire && !strcmp(cfg->prune_expire, "now") + && !(cfg->cruft_packs && cfg->repack_expire_to)) strvec_push(&repack, "-a"); else if (cfg->cruft_packs) { strvec_push(&repack, "--cruft"); @@ -454,6 +456,8 @@ static void add_repack_all_option(struct gc_config *cfg, if (cfg->max_cruft_size) strvec_pushf(&repack, "--max-cruft-size=%lu", cfg->max_cruft_size); + if (cfg->repack_expire_to) + strvec_pushf(&repack, "--expire-to=%s", cfg->repack_expire_to); } else { strvec_push(&repack, "-A"); if (cfg->prune_expire) @@ -688,7 +692,6 @@ struct repository *repo UNUSED) const char *prune_expire_sentinel = "sentinel"; const char *prune_expire_arg = prune_expire_sentinel; int ret; - struct option builtin_gc_options[] = { OPT__QUIET(&quiet, N_("suppress progress reporting")), { OPTION_STRING, 0, "prune", &prune_expire_arg, N_("date"), @@ -707,11 +710,13 @@ struct repository *repo UNUSED) PARSE_OPT_NOCOMPLETE), OPT_BOOL(0, "keep-largest-pack", &keep_largest_pack, N_("repack all other packs except the largest pack")), + OPT_STRING(0, "expire-to", &cfg.repack_expire_to, N_("dir"), + N_("pack prefix to store a pack containing pruned objects")), OPT_END() }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_gc_usage, builtin_gc_options); + show_usage_with_options_if_asked(argc, argv, + builtin_gc_usage, builtin_gc_options); strvec_pushl(&reflog, "reflog", "expire", "--all", NULL); strvec_pushl(&repack, "repack", "-d", "-l", NULL); @@ -1909,7 +1914,7 @@ static int get_random_minute(void) if (getenv("GIT_TEST_MAINT_SCHEDULER")) return 13; - return git_rand() % 60; + return git_rand(0) % 60; } static int is_launchctl_available(void) diff --git a/builtin/get-tar-commit-id.c b/builtin/get-tar-commit-id.c index 6bec0d1854..e4cd1627b4 100644 --- a/builtin/get-tar-commit-id.c +++ b/builtin/get-tar-commit-id.c @@ -13,7 +13,7 @@ static const char builtin_get_tar_commit_id_usage[] = #define HEADERSIZE (2 * RECORDSIZE) int cmd_get_tar_commit_id(int argc, - const char **argv UNUSED, + const char **argv, const char *prefix, struct repository *repo UNUSED) { @@ -27,6 +27,8 @@ int cmd_get_tar_commit_id(int argc, BUG_ON_NON_EMPTY_PREFIX(prefix); + show_usage_if_asked(argc, argv, builtin_get_tar_commit_id_usage); + if (argc != 1) usage(builtin_get_tar_commit_id_usage); diff --git a/builtin/grep.c b/builtin/grep.c index d00ee76f24..d1427290f7 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -1084,7 +1084,7 @@ int cmd_grep(int argc, } if (show_in_pager == default_pager) - show_in_pager = git_pager(1); + show_in_pager = git_pager(the_repository, 1); if (show_in_pager) { opt.color = 0; opt.name_only = 1; @@ -1246,7 +1246,7 @@ int cmd_grep(int argc, } if (!show_in_pager && !opt.status_only) - setup_pager(); + setup_pager(the_repository); die_for_incompatible_opt3(!use_index, "--no-index", untracked, "--untracked", diff --git a/builtin/help.c b/builtin/help.c index 05136279cf..c257079ceb 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -658,7 +658,7 @@ int cmd_help(int argc, case HELP_ACTION_ALL: opt_mode_usage(argc, "--all", help_format); if (verbose) { - setup_pager(); + setup_pager(the_repository); list_all_cmds_help(show_external_commands, show_aliases); return 0; @@ -692,7 +692,7 @@ int cmd_help(int argc, return 0; case HELP_ACTION_CONFIG: opt_mode_usage(argc, "--config", help_format); - setup_pager(); + setup_pager(the_repository); list_config_help(SHOW_CONFIG_HUMAN); printf("\n%s\n", _("'git help config' for more information")); return 0; diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 0b62b2589f..52cc97d52c 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -151,7 +151,7 @@ static unsigned int input_offset, input_len; static off_t consumed_bytes; static off_t max_input_size; static unsigned deepest_delta; -static git_hash_ctx input_ctx; +static struct git_hash_ctx input_ctx; static uint32_t input_crc32; static int input_fd, output_fd; static const char *curr_pack; @@ -282,7 +282,8 @@ static unsigned check_objects(void) max = get_max_object_index(); if (verbose) - progress = start_delayed_progress(_("Checking objects"), max); + progress = start_delayed_progress(the_repository, + _("Checking objects"), max); for (i = 0; i < max; i++) { foreign_nr += check_object(get_indexed_object(i)); @@ -300,7 +301,7 @@ static void flush(void) if (input_offset) { if (output_fd >= 0) write_or_die(output_fd, input_buffer, input_offset); - the_hash_algo->update_fn(&input_ctx, input_buffer, input_offset); + git_hash_update(&input_ctx, input_buffer, input_offset); memmove(input_buffer, input_buffer + input_offset, input_len); input_offset = 0; } @@ -379,16 +380,18 @@ static const char *open_pack_file(const char *pack_name) static void parse_pack_header(void) { - struct pack_header *hdr = fill(sizeof(struct pack_header)); + unsigned char *hdr = fill(sizeof(struct pack_header)); /* Header consistency check */ - if (hdr->hdr_signature != htonl(PACK_SIGNATURE)) + if (get_be32(hdr) != PACK_SIGNATURE) die(_("pack signature mismatch")); - if (!pack_version_ok(hdr->hdr_version)) + hdr += 4; + if (!pack_version_ok_native(get_be32(hdr))) die(_("pack version %"PRIu32" unsupported"), - ntohl(hdr->hdr_version)); + get_be32(hdr)); + hdr += 4; - nr_objects = ntohl(hdr->hdr_entries); + nr_objects = get_be32(hdr); use(sizeof(struct pack_header)); } @@ -472,14 +475,14 @@ static void *unpack_entry_data(off_t offset, unsigned long size, int status; git_zstream stream; void *buf; - git_hash_ctx c; + struct git_hash_ctx c; char hdr[32]; int hdrlen; if (!is_delta_type(type)) { hdrlen = format_object_header(hdr, sizeof(hdr), type, size); the_hash_algo->init_fn(&c); - the_hash_algo->update_fn(&c, hdr, hdrlen); + git_hash_update(&c, hdr, hdrlen); } else oid = NULL; if (type == OBJ_BLOB && size > big_file_threshold) @@ -499,7 +502,7 @@ static void *unpack_entry_data(off_t offset, unsigned long size, status = git_inflate(&stream, 0); use(input_len - stream.avail_in); if (oid) - the_hash_algo->update_fn(&c, last_out, stream.next_out - last_out); + git_hash_update(&c, last_out, stream.next_out - last_out); if (buf == fixed_buf) { stream.next_out = buf; stream.avail_out = sizeof(fixed_buf); @@ -509,7 +512,7 @@ static void *unpack_entry_data(off_t offset, unsigned long size, bad_object(offset, _("inflate returned %d"), status); git_inflate_end(&stream); if (oid) - the_hash_algo->final_oid_fn(oid, &c); + git_hash_final_oid(oid, &c); return buf == fixed_buf ? NULL : buf; } @@ -1245,10 +1248,11 @@ static void parse_pack_objects(unsigned char *hash) struct ofs_delta_entry *ofs_delta = ofs_deltas; struct object_id ref_delta_oid; struct stat st; - git_hash_ctx tmp_ctx; + struct git_hash_ctx tmp_ctx; if (verbose) progress = start_progress( + the_repository, progress_title ? progress_title : from_stdin ? _("Receiving objects") : _("Indexing objects"), nr_objects); @@ -1282,9 +1286,8 @@ static void parse_pack_objects(unsigned char *hash) /* Check pack integrity */ flush(); - the_hash_algo->init_fn(&tmp_ctx); - the_hash_algo->clone_fn(&tmp_ctx, &input_ctx); - the_hash_algo->final_fn(hash, &tmp_ctx); + git_hash_clone(&tmp_ctx, &input_ctx); + git_hash_final(hash, &tmp_ctx); if (!hasheq(fill(the_hash_algo->rawsz), hash, the_repository->hash_algo)) die(_("pack is corrupted (SHA1 mismatch)")); use(the_hash_algo->rawsz); @@ -1329,7 +1332,8 @@ static void resolve_deltas(struct pack_idx_option *opts) QSORT(ref_deltas, nr_ref_deltas, compare_ref_delta_entry); if (verbose || show_resolving_progress) - progress = start_progress(_("Resolving deltas"), + progress = start_progress(the_repository, + _("Resolving deltas"), nr_ref_deltas + nr_ofs_deltas); nr_dispatched = 0; @@ -1387,7 +1391,7 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha strbuf_release(&msg); finalize_hashfile(f, tail_hash, FSYNC_COMPONENT_PACK, 0); hashcpy(read_hash, pack_hash, the_repository->hash_algo); - fixup_pack_header_footer(output_fd, pack_hash, + fixup_pack_header_footer(the_hash_algo, output_fd, pack_hash, curr_pack, nr_objects, read_hash, consumed_bytes-the_hash_algo->rawsz); if (!hasheq(read_hash, tail_hash, the_repository->hash_algo)) @@ -1897,8 +1901,7 @@ int cmd_index_pack(int argc, */ fetch_if_missing = 0; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(index_pack_usage); + show_usage_if_asked(argc, argv, index_pack_usage); disable_replace_refs(); fsck_options.walk = mark_link; @@ -1954,19 +1957,11 @@ int cmd_index_pack(int argc, warning(_("no threads support, ignoring %s"), arg); nr_threads = 1; } - } else if (starts_with(arg, "--pack_header=")) { - struct pack_header *hdr; - char *c; - - hdr = (struct pack_header *)input_buffer; - hdr->hdr_signature = htonl(PACK_SIGNATURE); - hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10)); - if (*c != ',') - die(_("bad %s"), arg); - hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10)); - if (*c) - die(_("bad %s"), arg); - input_len = sizeof(*hdr); + } else if (skip_prefix(arg, "--pack_header=", &arg)) { + if (parse_pack_header_option(arg, + input_buffer, + &input_len) < 0) + die(_("bad --pack_header: %s"), arg); } else if (!strcmp(arg, "-v")) { verbose = 1; } else if (!strcmp(arg, "--progress-title")) { @@ -2093,11 +2088,12 @@ int cmd_index_pack(int argc, ALLOC_ARRAY(idx_objects, nr_objects); for (i = 0; i < nr_objects; i++) idx_objects[i] = &objects[i].idx; - curr_index = write_idx_file(index_name, idx_objects, nr_objects, &opts, pack_hash); + curr_index = write_idx_file(the_hash_algo, index_name, idx_objects, + nr_objects, &opts, pack_hash); if (rev_index) - curr_rev_index = write_rev_file(rev_index_name, idx_objects, - nr_objects, pack_hash, - opts.flags); + curr_rev_index = write_rev_file(the_hash_algo, rev_index_name, + idx_objects, nr_objects, + pack_hash, opts.flags); free(idx_objects); if (!verify) diff --git a/builtin/log.c b/builtin/log.c index 75e1b34123..e41f88945e 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -6,7 +6,6 @@ */ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "builtin.h" #include "abspath.h" @@ -209,7 +208,6 @@ static void cmd_log_init_defaults(struct rev_info *rev, static void set_default_decoration_filter(struct decoration_filter *decoration_filter) { - int i; char *value = NULL; struct string_list *include = decoration_filter->include_ref_pattern; const struct string_list *config_exclude; @@ -243,7 +241,7 @@ static void set_default_decoration_filter(struct decoration_filter *decoration_f * No command-line or config options were given, so * populate with sensible defaults. */ - for (i = 0; i < ARRAY_SIZE(ref_namespace); i++) { + for (size_t i = 0; i < ARRAY_SIZE(ref_namespace); i++) { if (!ref_namespace[i].decoration) continue; @@ -369,7 +367,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, if (rev->line_level_traverse) line_log_init(rev, line_cb.prefix, &line_cb.args); - setup_pager(); + setup_pager(the_repository); } static void cmd_log_init(int argc, const char **argv, const char *prefix, @@ -717,14 +715,14 @@ static int show_tag_object(const struct object_id *oid, struct rev_info *rev) unsigned long size; enum object_type type; char *buf = repo_read_object_file(the_repository, oid, &type, &size); - int offset = 0; + unsigned long offset = 0; if (!buf) return error(_("could not read object %s"), oid_to_hex(oid)); assert(type == OBJ_TAG); while (offset < size && buf[offset] != '\n') { - int new_offset = offset + 1; + unsigned long new_offset = offset + 1; const char *ident; while (new_offset < size && buf[new_offset++] != '\n') ; /* do nothing */ @@ -1316,24 +1314,25 @@ static void print_signature(const char *signature, FILE *file) static char *find_branch_name(struct rev_info *rev) { - int i, positive = -1; struct object_id branch_oid; const struct object_id *tip_oid; const char *ref, *v; char *full_ref, *branch = NULL; + int interesting_found = 0; + size_t idx; - for (i = 0; i < rev->cmdline.nr; i++) { + for (size_t i = 0; i < rev->cmdline.nr; i++) { if (rev->cmdline.rev[i].flags & UNINTERESTING) continue; - if (positive < 0) - positive = i; - else + if (interesting_found) return NULL; + interesting_found = 1; + idx = i; } - if (positive < 0) + if (!interesting_found) return NULL; - ref = rev->cmdline.rev[positive].name; - tip_oid = &rev->cmdline.rev[positive].item->oid; + ref = rev->cmdline.rev[idx].name; + tip_oid = &rev->cmdline.rev[idx].item->oid; if (repo_dwim_ref(the_repository, ref, strlen(ref), &branch_oid, &full_ref, 0) && skip_prefix(full_ref, "refs/heads/", &v) && @@ -1746,11 +1745,12 @@ struct base_tree_info { static struct commit *get_base_commit(const struct format_config *cfg, struct commit **list, - int total) + size_t total) { struct commit *base = NULL; struct commit **rev; - int i = 0, rev_nr = 0, auto_select, die_on_failure, ret; + int auto_select, die_on_failure, ret; + size_t i = 0, rev_nr = 0; switch (cfg->auto_base) { case AUTO_BASE_NEVER: @@ -1885,13 +1885,12 @@ define_commit_slab(commit_base, int); static void prepare_bases(struct base_tree_info *bases, struct commit *base, struct commit **list, - int total) + size_t total) { struct commit *commit; struct rev_info revs; struct diff_options diffopt; struct commit_base commit_base; - int i; if (!base) return; @@ -1906,7 +1905,7 @@ static void prepare_bases(struct base_tree_info *bases, repo_init_revisions(the_repository, &revs, NULL); revs.max_parents = 1; revs.topo_order = 1; - for (i = 0; i < total; i++) { + for (size_t i = 0; i < total; i++) { list[i]->object.flags &= ~UNINTERESTING; add_pending_object(&revs, &list[i]->object, "rev_list"); *commit_base_at(&commit_base, list[i]) = 1; @@ -2007,7 +2006,7 @@ int cmd_format_patch(int argc, struct rev_info rev; char *to_free = NULL; struct setup_revision_opt s_r_opt; - int nr = 0, total, i; + size_t nr = 0, total, i; int use_stdout = 0; int start_number = -1; int just_numbers = 0; @@ -2183,7 +2182,7 @@ int cmd_format_patch(int argc, fmt_patch_suffix = cfg.fmt_patch_suffix; /* Make sure "0000-$sub.patch" gives non-negative length for $sub */ - if (cfg.log.fmt_patch_name_max <= strlen("0000-") + strlen(fmt_patch_suffix)) + if (cfg.log.fmt_patch_name_max <= cast_size_t_to_int(strlen("0000-") + strlen(fmt_patch_suffix))) cfg.log.fmt_patch_name_max = strlen("0000-") + strlen(fmt_patch_suffix); if (cover_from_description_arg) @@ -2296,7 +2295,7 @@ int cmd_format_patch(int argc, rev.commit_format = CMIT_FMT_MBOXRD; if (use_stdout) { - setup_pager(); + setup_pager(the_repository); } else if (!rev.diffopt.close_file) { int saved; @@ -2499,12 +2498,16 @@ int cmd_format_patch(int argc, rev.add_signoff = cfg.do_signoff; if (show_progress) - progress = start_delayed_progress(_("Generating patches"), total); - while (0 <= --nr) { + progress = start_delayed_progress(the_repository, + _("Generating patches"), total); + for (i = 0; i < nr; i++) { + size_t idx = nr - i - 1; int shown; - display_progress(progress, total - nr); - commit = list[nr]; - rev.nr = total - nr + (start_number - 1); + + display_progress(progress, total - idx); + commit = list[idx]; + rev.nr = total - idx + (start_number - 1); + /* Make the second and subsequent mails replies to the first */ if (cfg.thread) { /* Have we already had a message ID? */ diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 15499cd12b..a4431429b7 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -644,8 +644,8 @@ int cmd_ls_files(int argc, }; int ret = 0; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(ls_files_usage, builtin_ls_files_options); + show_usage_with_options_if_asked(argc, argv, + ls_files_usage, builtin_ls_files_options); prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c index e17dec27b1..8de7ba7de1 100644 --- a/builtin/mailinfo.c +++ b/builtin/mailinfo.c @@ -83,7 +83,7 @@ int cmd_mailinfo(int argc, OPT_END() }; - setup_mailinfo(&mi); + setup_mailinfo(the_repository, &mi); meta_charset.policy = CHARSET_DEFAULT; argc = parse_options(argc, argv, prefix, options, mailinfo_usage, 0); diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c index 41dd304731..264df6259a 100644 --- a/builtin/mailsplit.c +++ b/builtin/mailsplit.c @@ -284,6 +284,8 @@ int cmd_mailsplit(int argc, BUG_ON_NON_EMPTY_PREFIX(prefix); + show_usage_if_asked(argc, argv, git_mailsplit_usage); + for (argp = argv+1; *argp; argp++) { const char *arg = *argp; @@ -297,8 +299,6 @@ int cmd_mailsplit(int argc, continue; } else if ( arg[1] == 'f' ) { nr = strtol(arg+2, NULL, 10); - } else if ( arg[1] == 'h' ) { - usage(git_mailsplit_usage); } else if ( arg[1] == 'b' && !arg[2] ) { allow_bare = 1; } else if (!strcmp(arg, "--keep-cr")) { diff --git a/builtin/merge-base.c b/builtin/merge-base.c index a20c93b11a..123c81515e 100644 --- a/builtin/merge-base.c +++ b/builtin/merge-base.c @@ -8,7 +8,7 @@ #include "parse-options.h" #include "commit-reach.h" -static int show_merge_base(struct commit **rev, int rev_nr, int show_all) +static int show_merge_base(struct commit **rev, size_t rev_nr, int show_all) { struct commit_list *result = NULL, *r; @@ -149,7 +149,7 @@ int cmd_merge_base(int argc, struct repository *repo UNUSED) { struct commit **rev; - int rev_nr = 0; + size_t rev_nr = 0; int show_all = 0; int cmdmode = 0; int ret; diff --git a/builtin/merge-index.c b/builtin/merge-index.c index 342699edb7..3314fb1336 100644 --- a/builtin/merge-index.c +++ b/builtin/merge-index.c @@ -75,6 +75,9 @@ static void merge_all(void) } } +static const char usage_string[] = +"git merge-index [-o] [-q] <merge-program> (-a | [--] [<filename>...])"; + int cmd_merge_index(int argc, const char **argv, const char *prefix UNUSED, @@ -87,8 +90,10 @@ int cmd_merge_index(int argc, */ signal(SIGCHLD, SIG_DFL); + show_usage_if_asked(argc, argv, usage_string); + if (argc < 3) - usage("git merge-index [-o] [-q] <merge-program> (-a | [--] [<filename>...])"); + usage(usage_string); repo_read_index(the_repository); diff --git a/builtin/merge-ours.c b/builtin/merge-ours.c index 3ecd9172f1..97b8a792c7 100644 --- a/builtin/merge-ours.c +++ b/builtin/merge-ours.c @@ -23,8 +23,7 @@ int cmd_merge_ours(int argc, const char *prefix UNUSED, struct repository *repo UNUSED) { - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(builtin_merge_ours_usage); + show_usage_if_asked(argc, argv, builtin_merge_ours_usage); /* * The contents of the current index becomes the tree we diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c index 1dd295558b..abfc060e28 100644 --- a/builtin/merge-recursive.c +++ b/builtin/merge-recursive.c @@ -38,6 +38,12 @@ int cmd_merge_recursive(int argc, if (argv[0] && ends_with(argv[0], "-subtree")) o.subtree_shift = ""; + if (argc == 2 && !strcmp(argv[1], "-h")) { + struct strbuf msg = STRBUF_INIT; + strbuf_addf(&msg, builtin_merge_recursive_usage, argv[0]); + show_usage_if_asked(argc, argv, msg.buf); + } + if (argc < 4) usagef(builtin_merge_recursive_usage, argv[0]); diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index 9a6c8b4e4c..3ec7127b3a 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -18,6 +18,7 @@ #include "tree.h" #include "config.h" #include "strvec.h" +#include "write-or-die.h" static int line_termination = '\n'; @@ -575,7 +576,7 @@ int cmd_merge_tree(int argc, }; /* Init merge options */ - init_ui_merge_options(&o.merge_options, the_repository); + init_basic_merge_options(&o.merge_options, the_repository); /* Parse arguments */ original_argc = argc - 1; /* ignoring argv[0] */ @@ -600,7 +601,6 @@ int cmd_merge_tree(int argc, line_termination = '\0'; while (strbuf_getline_lf(&buf, stdin) != EOF) { struct strbuf **split; - int result; const char *input_merge_base = NULL; split = strbuf_split(&buf, ' '); @@ -617,15 +617,14 @@ int cmd_merge_tree(int argc, if (input_merge_base && split[2] && split[3] && !split[4]) { strbuf_rtrim(split[2]); strbuf_rtrim(split[3]); - result = real_merge(&o, input_merge_base, split[2]->buf, split[3]->buf, prefix); + real_merge(&o, input_merge_base, split[2]->buf, split[3]->buf, prefix); } else if (!input_merge_base && !split[2]) { - result = real_merge(&o, NULL, split[0]->buf, split[1]->buf, prefix); + real_merge(&o, NULL, split[0]->buf, split[1]->buf, prefix); } else { die(_("malformed input line: '%s'."), buf.buf); } + maybe_flush_or_die(stdout, "stdout"); - if (result < 0) - die(_("merging cannot continue; got unclean result of %d"), result); strbuf_list_free(split); } strbuf_release(&buf); diff --git a/builtin/merge.c b/builtin/merge.c index 5f67007bba..ba9faf126a 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -1300,8 +1300,8 @@ int cmd_merge(int argc, void *branch_to_free; int orig_argc = argc; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_merge_usage, builtin_merge_options); + show_usage_with_options_if_asked(argc, argv, + builtin_merge_usage, builtin_merge_options); prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 1c3b842651..58a9b16126 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -269,6 +269,43 @@ struct configured_exclusion { static struct oidmap configured_exclusions; static struct oidset excluded_by_config; +static int name_hash_version = -1; + +/** + * Check whether the name_hash_version chosen by user input is appropriate, + * and also validate whether it is compatible with other features. + */ +static void validate_name_hash_version(void) +{ + if (name_hash_version < 1 || name_hash_version > 2) + die(_("invalid --name-hash-version option: %d"), name_hash_version); + if (write_bitmap_index && name_hash_version != 1) { + warning(_("currently, --write-bitmap-index requires --name-hash-version=1")); + name_hash_version = 1; + } +} + +static inline uint32_t pack_name_hash_fn(const char *name) +{ + static int seen_version = -1; + + if (seen_version < 0) + seen_version = name_hash_version; + else if (seen_version != name_hash_version) + BUG("name hash version changed from %d to %d mid-process", + seen_version, name_hash_version); + + switch (name_hash_version) { + case 1: + return pack_name_hash(name); + + case 2: + return pack_name_hash_v2((const unsigned char *)name); + + default: + BUG("invalid name-hash version: %d", name_hash_version); + } +} /* * stats @@ -1264,7 +1301,8 @@ static void write_pack_file(void) struct object_entry **write_order; if (progress > pack_to_stdout) - progress_state = start_progress(_("Writing objects"), nr_result); + progress_state = start_progress(the_repository, + _("Writing objects"), nr_result); ALLOC_ARRAY(written_list, to_pack.nr_objects); write_order = compute_write_order(); @@ -1318,8 +1356,9 @@ static void write_pack_file(void) */ int fd = finalize_hashfile(f, hash, FSYNC_COMPONENT_PACK, 0); - fixup_pack_header_footer(fd, hash, pack_tmp_name, - nr_written, hash, offset); + fixup_pack_header_footer(the_hash_algo, fd, hash, + pack_tmp_name, nr_written, + hash, offset); close(fd); if (write_bitmap_index) { if (write_bitmap_index != WRITE_BITMAP_QUIET) @@ -1367,9 +1406,10 @@ static void write_pack_file(void) if (cruft) pack_idx_opts.flags |= WRITE_MTIMES; - stage_tmp_packfiles(&tmpname, pack_tmp_name, - written_list, nr_written, - &to_pack, &pack_idx_opts, hash, + stage_tmp_packfiles(the_hash_algo, &tmpname, + pack_tmp_name, written_list, + nr_written, &to_pack, + &pack_idx_opts, hash, &idx_tmp_name); if (write_bitmap_index) { @@ -1686,7 +1726,7 @@ static int add_object_entry(const struct object_id *oid, enum object_type type, return 0; } - create_object_entry(oid, type, pack_name_hash(name), + create_object_entry(oid, type, pack_name_hash_fn(name), exclude, name && no_try_delta(name), found_pack, found_offset); return 1; @@ -1900,7 +1940,7 @@ static void add_preferred_base_object(const char *name) { struct pbase_tree *it; size_t cmplen; - unsigned hash = pack_name_hash(name); + unsigned hash = pack_name_hash_fn(name); if (!num_preferred_base || check_pbase_path(hash)) return; @@ -2400,7 +2440,8 @@ static void get_object_details(void) struct object_entry **sorted_by_offset; if (progress) - progress_state = start_progress(_("Counting objects"), + progress_state = start_progress(the_repository, + _("Counting objects"), to_pack.nr_objects); CALLOC_ARRAY(sorted_by_offset, to_pack.nr_objects); @@ -3220,7 +3261,8 @@ static void prepare_pack(int window, int depth) unsigned nr_done = 0; if (progress) - progress_state = start_progress(_("Compressing objects"), + progress_state = start_progress(the_repository, + _("Compressing objects"), nr_deltas); QSORT(delta_list, n, type_size_sort); ll_find_deltas(delta_list, n, window+1, depth, &nr_done); @@ -3410,7 +3452,7 @@ static void show_object_pack_hint(struct object *object, const char *name, * here using a now in order to perhaps improve the delta selection * process. */ - oe->hash = pack_name_hash(name); + oe->hash = pack_name_hash_fn(name); oe->no_try_delta = name && no_try_delta(name); stdin_packs_hints_nr++; @@ -3560,7 +3602,7 @@ static void add_cruft_object_entry(const struct object_id *oid, enum object_type entry = packlist_find(&to_pack, oid); if (entry) { if (name) { - entry->hash = pack_name_hash(name); + entry->hash = pack_name_hash_fn(name); entry->no_try_delta = no_try_delta(name); } } else { @@ -3583,7 +3625,7 @@ static void add_cruft_object_entry(const struct object_id *oid, enum object_type return; } - entry = create_object_entry(oid, type, pack_name_hash(name), + entry = create_object_entry(oid, type, pack_name_hash_fn(name), 0, name && no_try_delta(name), pack, offset); } @@ -3648,7 +3690,8 @@ static void add_objects_in_unpacked_packs(void); static void enumerate_cruft_objects(void) { if (progress) - progress_state = start_progress(_("Enumerating cruft objects"), 0); + progress_state = start_progress(the_repository, + _("Enumerating cruft objects"), 0); add_objects_in_unpacked_packs(); add_unreachable_loose_objects(); @@ -3674,7 +3717,8 @@ static void enumerate_and_traverse_cruft_objects(struct string_list *fresh_packs revs.ignore_missing_links = 1; if (progress) - progress_state = start_progress(_("Enumerating cruft objects"), 0); + progress_state = start_progress(the_repository, + _("Enumerating cruft objects"), 0); ret = add_unseen_recent_objects_to_traversal(&revs, cruft_expiration, set_cruft_mtime, 1); stop_progress(&progress_state); @@ -3693,7 +3737,8 @@ static void enumerate_and_traverse_cruft_objects(struct string_list *fresh_packs if (prepare_revision_walk(&revs)) die(_("revision walk setup failed")); if (progress) - progress_state = start_progress(_("Traversing cruft objects"), 0); + progress_state = start_progress(the_repository, + _("Traversing cruft objects"), 0); nr_seen = 0; traverse_commit_list(&revs, show_cruft_commit, show_cruft_object, NULL); @@ -4060,6 +4105,15 @@ static int get_object_list_from_bitmap(struct rev_info *revs) if (!(bitmap_git = prepare_bitmap_walk(revs, 0))) return -1; + /* + * For now, force the name-hash version to be 1 since that + * is the version implied by the bitmap format. Later, the + * format can include this version explicitly in its format, + * allowing readers to know the version that was used during + * the bitmap write. + */ + name_hash_version = 1; + if (pack_options_allow_reuse()) reuse_partial_packfile_from_bitmap(bitmap_git, &reuse_packfiles, @@ -4435,6 +4489,8 @@ int cmd_pack_objects(int argc, OPT_STRING_LIST(0, "uri-protocol", &uri_protocols, N_("protocol"), N_("exclude any configured uploadpack.blobpackfileuri with this protocol")), + OPT_INTEGER(0, "name-hash-version", &name_hash_version, + N_("use the specified name-hash function to group similar objects")), OPT_END(), }; @@ -4590,6 +4646,11 @@ int cmd_pack_objects(int argc, if (pack_to_stdout || !rev_list_all) write_bitmap_index = 0; + if (name_hash_version < 0) + name_hash_version = (int)git_env_ulong("GIT_TEST_NAME_HASH_VERSION", 1); + + validate_name_hash_version(); + if (use_delta_islands) strvec_push(&rp, "--topo-order"); @@ -4625,7 +4686,8 @@ int cmd_pack_objects(int argc, prepare_packing_data(the_repository, &to_pack); if (progress && !cruft) - progress_state = start_progress(_("Enumerating objects"), 0); + progress_state = start_progress(the_repository, + _("Enumerating objects"), 0); if (stdin_packs) { /* avoids adding objects in excluded packs */ ignore_packed_keep_in_core = 1; diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index e046575871..3febe732f8 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -595,8 +595,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s struct strbuf idx_name = STRBUF_INIT; char buf[GIT_MAX_HEXSZ + 2]; /* hex hash + \n + \0 */ - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(pack_redundant_usage); + show_usage_if_asked(argc, argv, pack_redundant_usage); for (i = 1; i < argc; i++) { const char *arg = argv[i]; diff --git a/builtin/patch-id.c b/builtin/patch-id.c index f540d8daa7..cdef2ec10a 100644 --- a/builtin/patch-id.c +++ b/builtin/patch-id.c @@ -70,7 +70,7 @@ static size_t get_one_patchid(struct object_id *next_oid, struct object_id *resu int before = -1, after = -1; int diff_is_binary = 0; char pre_oid_str[GIT_MAX_HEXSZ + 1], post_oid_str[GIT_MAX_HEXSZ + 1]; - git_hash_ctx ctx; + struct git_hash_ctx ctx; the_hash_algo->init_fn(&ctx); oidclr(result, the_repository->hash_algo); @@ -85,7 +85,7 @@ static size_t get_one_patchid(struct object_id *next_oid, struct object_id *resu !skip_prefix(line, "From ", &p) && starts_with(line, "\\ ") && 12 < strlen(line)) { if (verbatim) - the_hash_algo->update_fn(&ctx, line, strlen(line)); + git_hash_update(&ctx, line, strlen(line)); continue; } @@ -104,10 +104,10 @@ static size_t get_one_patchid(struct object_id *next_oid, struct object_id *resu starts_with(line, "Binary files")) { diff_is_binary = 1; before = 0; - the_hash_algo->update_fn(&ctx, pre_oid_str, - strlen(pre_oid_str)); - the_hash_algo->update_fn(&ctx, post_oid_str, - strlen(post_oid_str)); + git_hash_update(&ctx, pre_oid_str, + strlen(pre_oid_str)); + git_hash_update(&ctx, post_oid_str, + strlen(post_oid_str)); if (stable) flush_one_hunk(result, &ctx); continue; @@ -165,7 +165,7 @@ static size_t get_one_patchid(struct object_id *next_oid, struct object_id *resu /* Add line to hash algo (possibly removing whitespace) */ len = verbatim ? strlen(line) : remove_space(line); patchlen += len; - the_hash_algo->update_fn(&ctx, line, len); + git_hash_update(&ctx, line, len); } if (!found_next) diff --git a/builtin/prune.c b/builtin/prune.c index aeff9ca1b3..1c357fffd8 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -64,7 +64,8 @@ static void perform_reachability_traversal(struct rev_info *revs) return; if (show_progress) - progress = start_delayed_progress(_("Checking connectivity"), 0); + progress = start_delayed_progress(the_repository, + _("Checking connectivity"), 0); mark_reachable_objects(revs, 1, expire, progress); stop_progress(&progress); initialized = 1; diff --git a/builtin/push.c b/builtin/push.c index 90de3746b5..92d530e5c4 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -78,7 +78,7 @@ static void refspec_append_mapped(struct refspec *refspec, const char *ref, .src = matched->name, }; - if (!query_refspecs(&remote->push, &query) && query.dst) { + if (!refspec_find_match(&remote->push, &query) && query.dst) { refspec_appendf(refspec, "%s%s:%s", query.force ? "+" : "", query.src, query.dst); diff --git a/builtin/rebase.c b/builtin/rebase.c index 0498fff3c9..6c9eaf3788 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -1223,9 +1223,9 @@ int cmd_rebase(int argc, }; int i; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_rebase_usage, - builtin_rebase_options); + show_usage_with_options_if_asked(argc, argv, + builtin_rebase_usage, + builtin_rebase_options); 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 c2e9103f11..129305700c 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -174,7 +174,7 @@ static int receive_pack_config(const char *var, const char *value, char *path; if (git_config_pathname(&path, var, value)) - return 1; + return -1; strbuf_addf(&fsck_msg_types, "%cskiplist=%s", fsck_msg_types.len ? ',' : '=', path); free(path); @@ -566,14 +566,14 @@ static void hmac_hash(unsigned char *out, unsigned char k_ipad[GIT_MAX_BLKSZ]; unsigned char k_opad[GIT_MAX_BLKSZ]; int i; - git_hash_ctx ctx; + struct git_hash_ctx ctx; /* RFC 2104 2. (1) */ memset(key, '\0', GIT_MAX_BLKSZ); if (the_hash_algo->blksz < key_len) { the_hash_algo->init_fn(&ctx); - the_hash_algo->update_fn(&ctx, key_in, key_len); - the_hash_algo->final_fn(key, &ctx); + git_hash_update(&ctx, key_in, key_len); + git_hash_final(key, &ctx); } else { memcpy(key, key_in, key_len); } @@ -586,15 +586,15 @@ static void hmac_hash(unsigned char *out, /* RFC 2104 2. (3) & (4) */ the_hash_algo->init_fn(&ctx); - the_hash_algo->update_fn(&ctx, k_ipad, sizeof(k_ipad)); - the_hash_algo->update_fn(&ctx, text, text_len); - the_hash_algo->final_fn(out, &ctx); + git_hash_update(&ctx, k_ipad, sizeof(k_ipad)); + git_hash_update(&ctx, text, text_len); + git_hash_final(out, &ctx); /* RFC 2104 2. (6) & (7) */ the_hash_algo->init_fn(&ctx); - the_hash_algo->update_fn(&ctx, k_opad, sizeof(k_opad)); - the_hash_algo->update_fn(&ctx, out, the_hash_algo->rawsz); - the_hash_algo->final_fn(out, &ctx); + git_hash_update(&ctx, k_opad, sizeof(k_opad)); + git_hash_update(&ctx, out, the_hash_algo->rawsz); + git_hash_final(out, &ctx); } static char *prepare_push_cert_nonce(const char *path, timestamp_t stamp) @@ -2239,7 +2239,7 @@ static const char *unpack(int err_fd, struct shallow_info *si) strvec_push(&child.args, alt_shallow_file); } - tmp_objdir = tmp_objdir_create("incoming"); + tmp_objdir = tmp_objdir_create(the_repository, "incoming"); if (!tmp_objdir) { if (err_fd > 0) close(err_fd); @@ -2304,7 +2304,7 @@ static const char *unpack(int err_fd, struct shallow_info *si) if (status) return "index-pack fork failed"; - lockfile = index_pack_lockfile(child.out, NULL); + lockfile = index_pack_lockfile(the_repository, child.out, NULL); if (lockfile) { pack_lockfile = register_tempfile(lockfile); free(lockfile); @@ -2628,7 +2628,7 @@ int cmd_receive_pack(int argc, } } if (auto_update_server_info) - update_server_info(0); + update_server_info(the_repository, 0); clear_shallow_info(&si); } if (use_sideband) diff --git a/builtin/refs.c b/builtin/refs.c index a29f195834..c459507d51 100644 --- a/builtin/refs.c +++ b/builtin/refs.c @@ -30,6 +30,9 @@ static int cmd_refs_migrate(int argc, const char **argv, const char *prefix, OPT_BIT(0, "dry-run", &flags, N_("perform a non-destructive dry-run"), REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN), + OPT_BIT(0, "no-reflog", &flags, + N_("drop reflogs entirely during the migration"), + REPO_MIGRATE_REF_STORAGE_FORMAT_SKIP_REFLOG), OPT_END(), }; struct strbuf errbuf = STRBUF_INIT; diff --git a/builtin/remote-ext.c b/builtin/remote-ext.c index 33c8ae0fc7..bd2037f27d 100644 --- a/builtin/remote-ext.c +++ b/builtin/remote-ext.c @@ -202,6 +202,8 @@ int cmd_remote_ext(int argc, { BUG_ON_NON_EMPTY_PREFIX(prefix); + show_usage_if_asked(argc, argv, usage_msg); + if (argc != 3) usage(usage_msg); diff --git a/builtin/remote-fd.c b/builtin/remote-fd.c index ae896eda57..39908546ba 100644 --- a/builtin/remote-fd.c +++ b/builtin/remote-fd.c @@ -64,6 +64,7 @@ int cmd_remote_fd(int argc, BUG_ON_NON_EMPTY_PREFIX(prefix); + show_usage_if_asked(argc, argv, usage_msg); if (argc != 3) usage(usage_msg); diff --git a/builtin/remote.c b/builtin/remote.c index 0435963286..816d482340 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -383,7 +383,7 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat states->remote->fetch.items[i].raw); for (ref = fetch_map; ref; ref = ref->next) { - if (omit_name_by_refspec(ref->name, &states->remote->fetch)) + if (refname_matches_negative_refspec_item(ref->name, &states->remote->fetch)) string_list_append(&states->skipped, abbrev_branch(ref->name)); else if (!ref->peer_ref || !refs_ref_exists(get_main_ref_store(the_repository), ref->peer_ref->name)) string_list_append(&states->new_refs, abbrev_branch(ref->name)); @@ -642,10 +642,12 @@ static int migrate_file(struct remote *remote) strbuf_addf(&buf, "remote.%s.fetch", remote->name); for (i = 0; i < remote->fetch.nr; i++) git_config_set_multivar(buf.buf, remote->fetch.items[i].raw, "^$", 0); +#ifndef WITH_BREAKING_CHANGES if (remote->origin == REMOTE_REMOTES) unlink_or_warn(git_path("remotes/%s", remote->name)); else if (remote->origin == REMOTE_BRANCHES) unlink_or_warn(git_path("branches/%s", remote->name)); +#endif /* WITH_BREAKING_CHANGES */ strbuf_release(&buf); return 0; @@ -820,7 +822,8 @@ static int mv(int argc, const char **argv, const char *prefix, * Count symrefs twice, since "renaming" them is done by * deleting and recreating them in two separate passes. */ - progress = start_progress(_("Renaming remote references"), + progress = start_progress(the_repository, + _("Renaming remote references"), rename.remote_branches->nr + rename.symrefs_nr); } for (i = 0; i < remote_branches.nr; i++) { diff --git a/builtin/repack.c b/builtin/repack.c index 0c6dad7df4..75e3752353 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -41,7 +41,9 @@ static int run_update_server_info = 1; static char *packdir, *packtmp_name, *packtmp; static const char *const git_repack_usage[] = { - N_("git repack [<options>]"), + N_("git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" + "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" + "[--write-midx] [--name-hash-version=<n>]"), NULL }; @@ -60,6 +62,7 @@ struct pack_objects_args { int no_reuse_object; int quiet; int local; + int name_hash_version; struct list_objects_filter_options filter_options; }; @@ -308,6 +311,8 @@ static void prepare_pack_objects(struct child_process *cmd, strvec_pushf(&cmd->args, "--no-reuse-delta"); if (args->no_reuse_object) strvec_pushf(&cmd->args, "--no-reuse-object"); + if (args->name_hash_version) + strvec_pushf(&cmd->args, "--name-hash-version=%d", args->name_hash_version); if (args->local) strvec_push(&cmd->args, "--local"); if (args->quiet) @@ -1205,6 +1210,8 @@ int cmd_repack(int argc, N_("pass --no-reuse-delta to git-pack-objects")), OPT_BOOL('F', NULL, &po_args.no_reuse_object, N_("pass --no-reuse-object to git-pack-objects")), + OPT_INTEGER(0, "name-hash-version", &po_args.name_hash_version, + N_("specify the name hash version to use for grouping similar objects by path")), OPT_NEGBIT('n', NULL, &run_update_server_info, N_("do not run git-update-server-info"), 1), OPT__QUIET(&po_args.quiet, N_("be quiet")), @@ -1370,9 +1377,12 @@ int cmd_repack(int argc, "--unpack-unreachable"); } else if (keep_unreachable) { strvec_push(&cmd.args, "--keep-unreachable"); - strvec_push(&cmd.args, "--pack-loose-unreachable"); } } + + if (keep_unreachable && delete_redundant && + !(pack_everything & PACK_CRUFT)) + strvec_push(&cmd.args, "--pack-loose-unreachable"); } else if (geometry.split_factor) { strvec_push(&cmd.args, "--stdin-packs"); strvec_push(&cmd.args, "--unpacked"); @@ -1565,7 +1575,7 @@ int cmd_repack(int argc, } if (run_update_server_info) - update_server_info(0); + update_server_info(the_repository, 0); if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0)) { unsigned flags = 0; diff --git a/builtin/replay.c b/builtin/replay.c index 1afc6d1ee0..032c172b65 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -163,9 +163,10 @@ static void determine_replay_mode(struct rev_cmdline_info *cmd_info, get_ref_information(cmd_info, &rinfo); if (!rinfo.positive_refexprs) die(_("need some commits to replay")); - if (onto_name && *advance_name) - die(_("--onto and --advance are incompatible")); - else if (onto_name) { + + die_for_incompatible_opt2(!!onto_name, "--onto", + !!*advance_name, "--advance"); + if (onto_name) { *onto = peel_committish(onto_name); if (rinfo.positive_refexprs < strset_get_size(&rinfo.positive_refs)) diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 3196da7b2d..bb26bee0d4 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -22,7 +22,10 @@ #include "progress.h" #include "reflog-walk.h" #include "oidset.h" +#include "oidmap.h" #include "packfile.h" +#include "quote.h" +#include "strbuf.h" static const char rev_list_usage[] = "git rev-list [<options>] <commit>... [--] [<path>...]\n" @@ -73,11 +76,17 @@ static unsigned progress_counter; static struct oidset omitted_objects; static int arg_print_omitted; /* print objects omitted by filter */ -static struct oidset missing_objects; +struct missing_objects_map_entry { + struct oidmap_entry entry; + const char *path; + unsigned type; +}; +static struct oidmap missing_objects; enum missing_action { MA_ERROR = 0, /* fail if any missing objects are encountered */ MA_ALLOW_ANY, /* silently allow ALL missing objects */ MA_PRINT, /* print ALL missing objects in special section */ + MA_PRINT_INFO, /* same as MA_PRINT but also prints missing object info */ MA_ALLOW_PROMISOR, /* silently allow all missing PROMISOR objects */ }; static enum missing_action arg_missing_action; @@ -101,7 +110,49 @@ static off_t get_object_disk_usage(struct object *obj) return size; } -static inline void finish_object__ma(struct object *obj) +static void add_missing_object_entry(struct object_id *oid, const char *path, + unsigned type) +{ + struct missing_objects_map_entry *entry; + + if (oidmap_get(&missing_objects, oid)) + return; + + CALLOC_ARRAY(entry, 1); + entry->entry.oid = *oid; + entry->type = type; + if (path) + entry->path = xstrdup(path); + oidmap_put(&missing_objects, entry); +} + +static void print_missing_object(struct missing_objects_map_entry *entry, + int print_missing_info) +{ + struct strbuf sb = STRBUF_INIT; + + if (!print_missing_info) { + printf("?%s\n", oid_to_hex(&entry->entry.oid)); + return; + } + + if (entry->path && *entry->path) { + struct strbuf path = STRBUF_INIT; + + strbuf_addstr(&sb, " path="); + quote_path(entry->path, NULL, &path, QUOTE_PATH_QUOTE_SP); + strbuf_addbuf(&sb, &path); + + strbuf_release(&path); + } + if (entry->type) + strbuf_addf(&sb, " type=%s", type_name(entry->type)); + + printf("?%s%s\n", oid_to_hex(&entry->entry.oid), sb.buf); + strbuf_release(&sb); +} + +static inline void finish_object__ma(struct object *obj, const char *name) { /* * Whether or not we try to dynamically fetch missing objects @@ -119,7 +170,8 @@ static inline void finish_object__ma(struct object *obj) return; case MA_PRINT: - oidset_insert(&missing_objects, &obj->oid); + case MA_PRINT_INFO: + add_missing_object_entry(&obj->oid, name, obj->type); return; case MA_ALLOW_PROMISOR: @@ -152,7 +204,7 @@ static void show_commit(struct commit *commit, void *data) if (revs->do_not_die_on_missing_objects && oidset_contains(&revs->missing_commits, &commit->object.oid)) { - finish_object__ma(&commit->object); + finish_object__ma(&commit->object, NULL); return; } @@ -268,12 +320,11 @@ static void show_commit(struct commit *commit, void *data) finish_commit(commit); } -static int finish_object(struct object *obj, const char *name UNUSED, - void *cb_data) +static int finish_object(struct object *obj, const char *name, void *cb_data) { struct rev_list_info *info = cb_data; if (oid_object_info_extended(the_repository, &obj->oid, NULL, 0) < 0) { - finish_object__ma(obj); + finish_object__ma(obj, name); return 1; } if (info->revs->verify_objects && !obj->parsed && obj->type != OBJ_COMMIT) @@ -414,6 +465,12 @@ static inline int parse_missing_action_value(const char *value) return 1; } + if (!strcmp(value, "print-info")) { + arg_missing_action = MA_PRINT_INFO; + fetch_if_missing = 0; + return 1; + } + if (!strcmp(value, "allow-promisor")) { arg_missing_action = MA_ALLOW_PROMISOR; fetch_if_missing = 0; @@ -542,8 +599,7 @@ int cmd_rev_list(int argc, const char *show_progress = NULL; int ret = 0; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(rev_list_usage); + show_usage_if_asked(argc, argv, rev_list_usage); git_config(git_default_config, NULL); repo_init_revisions(the_repository, &revs, prefix); @@ -735,7 +791,8 @@ int cmd_rev_list(int argc, revs.limited = 1; if (show_progress) - progress = start_delayed_progress(show_progress, 0); + progress = start_delayed_progress(the_repository, + show_progress, 0); if (use_bitmap_index) { if (!try_bitmap_count(&revs, filter_provided_objects)) @@ -781,10 +838,18 @@ int cmd_rev_list(int argc, if (arg_print_omitted) oidset_init(&omitted_objects, DEFAULT_OIDSET_SIZE); - if (arg_missing_action == MA_PRINT) { - oidset_init(&missing_objects, DEFAULT_OIDSET_SIZE); + if (arg_missing_action == MA_PRINT || + arg_missing_action == MA_PRINT_INFO) { + struct oidset_iter iter; + struct object_id *oid; + + oidmap_init(&missing_objects, DEFAULT_OIDSET_SIZE); + oidset_iter_init(&revs.missing_commits, &iter); + /* Add missing tips */ - oidset_insert_from_set(&missing_objects, &revs.missing_commits); + while ((oid = oidset_iter_next(&iter))) + add_missing_object_entry(oid, NULL, 0); + oidset_clear(&revs.missing_commits); } @@ -800,13 +865,20 @@ int cmd_rev_list(int argc, printf("~%s\n", oid_to_hex(oid)); oidset_clear(&omitted_objects); } - if (arg_missing_action == MA_PRINT) { - struct oidset_iter iter; - struct object_id *oid; - oidset_iter_init(&missing_objects, &iter); - while ((oid = oidset_iter_next(&iter))) - printf("?%s\n", oid_to_hex(oid)); - oidset_clear(&missing_objects); + if (arg_missing_action == MA_PRINT || + arg_missing_action == MA_PRINT_INFO) { + struct missing_objects_map_entry *entry; + struct oidmap_iter iter; + + oidmap_iter_init(&missing_objects, &iter); + + while ((entry = oidmap_iter_next(&iter))) { + print_missing_object(entry, arg_missing_action == + MA_PRINT_INFO); + free((void *)entry->path); + } + + oidmap_free(&missing_objects, true); } stop_progress(&progress); diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 949747a6b6..428c866c05 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -713,6 +713,8 @@ int cmd_rev_parse(int argc, int seen_end_of_options = 0; enum format_type format = FORMAT_DEFAULT; + show_usage_if_asked(argc, argv, builtin_rev_parse_usage); + if (argc > 1 && !strcmp("--parseopt", argv[1])) return cmd_parseopt(argc - 1, argv + 1, prefix); diff --git a/builtin/send-pack.c b/builtin/send-pack.c index 59b626aae8..8d461008e2 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -317,7 +317,7 @@ int cmd_send_pack(int argc, set_ref_status_for_push(remote_refs, args.send_mirror, args.force_update); - ret = send_pack(&args, fd, conn, remote_refs, &extra_have); + ret = send_pack(the_repository, &args, fd, conn, remote_refs, &extra_have); if (helper_status) print_helper_status(remote_refs); diff --git a/builtin/show-index.c b/builtin/show-index.c index 756d632b51..9d4ecf5e7b 100644 --- a/builtin/show-index.c +++ b/builtin/show-index.c @@ -9,7 +9,7 @@ #include "parse-options.h" static const char *const show_index_usage[] = { - "git show-index [--object-format=<hash-algorithm>]", + "git show-index [--object-format=<hash-algorithm>] < <pack-idx-file>", NULL }; diff --git a/builtin/tag.c b/builtin/tag.c index c4bd145831..e8a344b926 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -698,7 +698,6 @@ int cmd_tag(int argc, cleanup: ref_sorting_release(sorting); ref_filter_clear(&filter); - ref_format_clear(&format); strbuf_release(&buf); strbuf_release(&ref); strbuf_release(&reflog_msg); diff --git a/builtin/unpack-file.c b/builtin/unpack-file.c index 6da2825753..fb5fcbc40a 100644 --- a/builtin/unpack-file.c +++ b/builtin/unpack-file.c @@ -26,6 +26,9 @@ static char *create_temp_file(struct object_id *oid) return path; } +static const char usage_msg[] = +"git unpack-file <blob>"; + int cmd_unpack_file(int argc, const char **argv, const char *prefix UNUSED, @@ -33,8 +36,9 @@ int cmd_unpack_file(int argc, { struct object_id oid; - if (argc != 2 || !strcmp(argv[1], "-h")) - usage("git unpack-file <blob>"); + show_usage_if_asked(argc, argv, usage_msg); + if (argc != 2) + usage(usage_msg); if (repo_get_oid(the_repository, argv[1], &oid)) die("Not a valid object name %s", argv[1]); diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index 2197d6d933..8383bcf404 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -18,6 +18,7 @@ #include "progress.h" #include "decorate.h" #include "fsck.h" +#include "packfile.h" static int dry_run, quiet, recover, has_errors, strict; static const char unpack_usage[] = "git unpack-objects [-n] [-q] [-r] [--strict]"; @@ -27,7 +28,7 @@ static unsigned char buffer[4096]; static unsigned int offset, len; static off_t consumed_bytes; static off_t max_input_size; -static git_hash_ctx ctx; +static struct git_hash_ctx ctx; static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT; static struct progress *progress; @@ -69,7 +70,7 @@ static void *fill(int min) if (min > sizeof(buffer)) die("cannot fill %d bytes", min); if (offset) { - the_hash_algo->update_fn(&ctx, buffer, offset); + git_hash_update(&ctx, buffer, offset); memmove(buffer, buffer + offset, len); offset = 0; } @@ -578,19 +579,21 @@ static void unpack_one(unsigned nr) static void unpack_all(void) { int i; - struct pack_header *hdr = fill(sizeof(struct pack_header)); + unsigned char *hdr = fill(sizeof(struct pack_header)); - nr_objects = ntohl(hdr->hdr_entries); - - if (ntohl(hdr->hdr_signature) != PACK_SIGNATURE) + if (get_be32(hdr) != PACK_SIGNATURE) die("bad pack file"); - if (!pack_version_ok(hdr->hdr_version)) + hdr += 4; + if (!pack_version_ok_native(get_be32(hdr))) die("unknown pack file version %"PRIu32, - ntohl(hdr->hdr_version)); + get_be32(hdr)); + hdr += 4; + nr_objects = get_be32(hdr); use(sizeof(struct pack_header)); if (!quiet) - progress = start_progress(_("Unpacking objects"), nr_objects); + progress = start_progress(the_repository, + _("Unpacking objects"), nr_objects); CALLOC_ARRAY(obj_list, nr_objects); begin_odb_transaction(); for (i = 0; i < nr_objects; i++) { @@ -611,7 +614,7 @@ int cmd_unpack_objects(int argc, { int i; struct object_id oid; - git_hash_ctx tmp_ctx; + struct git_hash_ctx tmp_ctx; disable_replace_refs(); @@ -619,6 +622,8 @@ int cmd_unpack_objects(int argc, quiet = !isatty(2); + show_usage_if_asked(argc, argv, unpack_usage); + for (i = 1 ; i < argc; i++) { const char *arg = argv[i]; @@ -644,19 +649,10 @@ int cmd_unpack_objects(int argc, fsck_set_msg_types(&fsck_options, arg); continue; } - if (starts_with(arg, "--pack_header=")) { - struct pack_header *hdr; - char *c; - - hdr = (struct pack_header *)buffer; - hdr->hdr_signature = htonl(PACK_SIGNATURE); - hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10)); - if (*c != ',') - die("bad %s", arg); - hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10)); - if (*c) - die("bad %s", arg); - len = sizeof(*hdr); + if (skip_prefix(arg, "--pack_header=", &arg)) { + if (parse_pack_header_option(arg, + buffer, &len) < 0) + die(_("bad --pack_header: %s"), arg); continue; } if (skip_prefix(arg, "--max-input-size=", &arg)) { @@ -671,10 +667,9 @@ int cmd_unpack_objects(int argc, } the_hash_algo->init_fn(&ctx); unpack_all(); - the_hash_algo->update_fn(&ctx, buffer, offset); - the_hash_algo->init_fn(&tmp_ctx); - the_hash_algo->clone_fn(&tmp_ctx, &ctx); - the_hash_algo->final_oid_fn(&oid, &tmp_ctx); + git_hash_update(&ctx, buffer, offset); + git_hash_clone(&tmp_ctx, &ctx); + git_hash_final_oid(&oid, &tmp_ctx); if (strict) { write_rest(); if (fsck_finish(&fsck_options)) diff --git a/builtin/update-index.c b/builtin/update-index.c index 74bbad9f87..b2f6b1a3fb 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -1045,8 +1045,8 @@ int cmd_update_index(int argc, OPT_END() }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(update_index_usage, options); + show_usage_with_options_if_asked(argc, argv, + update_index_usage, options); git_config(git_default_config, NULL); diff --git a/builtin/update-server-info.c b/builtin/update-server-info.c index 6769611a02..d7467290a8 100644 --- a/builtin/update-server-info.c +++ b/builtin/update-server-info.c @@ -1,4 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -13,7 +12,7 @@ static const char * const update_server_info_usage[] = { int cmd_update_server_info(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { int force = 0; struct option options[] = { @@ -21,11 +20,12 @@ int cmd_update_server_info(int argc, OPT_END() }; - git_config(git_default_config, NULL); + if (repo) + repo_config(repo, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, update_server_info_usage, 0); if (argc > 0) usage_with_options(update_server_info_usage, options); - return !!update_server_info(force); + return !!update_server_info(repo, force); } diff --git a/builtin/upload-archive.c b/builtin/upload-archive.c index 9e9343f121..97d7c9522f 100644 --- a/builtin/upload-archive.c +++ b/builtin/upload-archive.c @@ -27,7 +27,8 @@ int cmd_upload_archive_writer(int argc, const char *arg_cmd = "argument "; int ret; - if (argc != 2 || !strcmp(argv[1], "-h")) + show_usage_if_asked(argc, argv, upload_archive_usage); + if (argc != 2) usage(upload_archive_usage); if (!enter_repo(argv[1], 0)) @@ -92,8 +93,7 @@ struct repository *repo UNUSED) BUG_ON_NON_EMPTY_PREFIX(prefix); - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(upload_archive_usage); + show_usage_if_asked(argc, argv, upload_archive_usage); /* * Set up sideband subprocess. diff --git a/builtin/upload-pack.c b/builtin/upload-pack.c index dd63d6eadf..c2bbc035ab 100644 --- a/builtin/upload-pack.c +++ b/builtin/upload-pack.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "exec-cmd.h" #include "gettext.h" @@ -63,9 +65,9 @@ int cmd_upload_pack(int argc, switch (determine_protocol_version_server()) { case protocol_v2: if (advertise_refs) - protocol_v2_advertise_capabilities(); + protocol_v2_advertise_capabilities(the_repository); else - protocol_v2_serve_loop(stateless_rpc); + protocol_v2_serve_loop(the_repository, stateless_rpc); break; case protocol_v1: /* diff --git a/builtin/var.c b/builtin/var.c index 1449656cc9..ada642a9fe 100644 --- a/builtin/var.c +++ b/builtin/var.c @@ -42,7 +42,7 @@ static char *sequence_editor(int ident_flag UNUSED) static char *pager(int ident_flag UNUSED) { - const char *pgm = git_pager(1); + const char *pgm = git_pager(the_repository, 1); if (!pgm) pgm = "cat"; @@ -221,6 +221,7 @@ int cmd_var(int argc, const struct git_var *git_var; char *val; + show_usage_if_asked(argc, argv, var_usage); if (argc != 2) usage(var_usage); diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c index a7f20618ff..f6b97048a5 100644 --- a/builtin/verify-tag.c +++ b/builtin/verify-tag.c @@ -69,6 +69,5 @@ int cmd_verify_tag(int argc, if (format.format) pretty_print_ref(name, &oid, &format); } - ref_format_clear(&format); return had_error; } |
