diff options
Diffstat (limited to 'builtin/rev-list.c')
-rw-r--r-- | builtin/rev-list.c | 179 |
1 files changed, 117 insertions, 62 deletions
diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 30fd8e8..7780372 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -1,16 +1,18 @@ -#include "cache.h" +#include "builtin.h" #include "config.h" #include "commit.h" #include "diff.h" +#include "environment.h" +#include "gettext.h" +#include "hex.h" #include "revision.h" #include "list-objects.h" -#include "list-objects-filter.h" #include "list-objects-filter-options.h" #include "object.h" -#include "object-store.h" -#include "pack.h" +#include "object-name.h" +#include "object-file.h" +#include "object-store-ll.h" #include "pack-bitmap.h" -#include "builtin.h" #include "log-tree.h" #include "graph.h" #include "bisect.h" @@ -20,7 +22,8 @@ #include "packfile.h" static const char rev_list_usage[] = -"git rev-list [<options>] <commit-id>... [-- <path>...]\n" +"git rev-list [<options>] <commit>... [--] [<path>...]\n" +"\n" " limiting output:\n" " --max-count=<n>\n" " --max-age=<epoch>\n" @@ -37,6 +40,7 @@ static const char rev_list_usage[] = " --tags\n" " --remotes\n" " --stdin\n" +" --exclude-hidden=[fetch|receive|uploadpack]\n" " --quiet\n" " ordering output:\n" " --topo-order\n" @@ -46,6 +50,7 @@ static const char rev_list_usage[] = " --parents\n" " --children\n" " --objects | --objects-edge\n" +" --disk-usage[=human]\n" " --unpacked\n" " --header | --pretty\n" " --[no-]object-names\n" @@ -81,6 +86,7 @@ static int arg_show_object_names = 1; static int show_disk_usage; static off_t total_disk_usage; +static int human_readable; static off_t get_object_disk_usage(struct object *obj) { @@ -92,7 +98,48 @@ static off_t get_object_disk_usage(struct object *obj) return size; } -static void finish_commit(struct commit *commit); +static inline void finish_object__ma(struct object *obj) +{ + /* + * Whether or not we try to dynamically fetch missing objects + * from the server, we currently DO NOT have the object. We + * can either print, allow (ignore), or conditionally allow + * (ignore) them. + */ + switch (arg_missing_action) { + case MA_ERROR: + die("missing %s object '%s'", + type_name(obj->type), oid_to_hex(&obj->oid)); + return; + + case MA_ALLOW_ANY: + return; + + case MA_PRINT: + oidset_insert(&missing_objects, &obj->oid); + return; + + case MA_ALLOW_PROMISOR: + if (is_promisor_object(&obj->oid)) + return; + die("unexpected missing %s object '%s'", + type_name(obj->type), oid_to_hex(&obj->oid)); + return; + + default: + BUG("unhandled missing_action"); + return; + } +} + +static void finish_commit(struct commit *commit) +{ + free_commit_list(commit->parents); + commit->parents = NULL; + free_commit_buffer(the_repository->parsed_objects, + commit); +} + static void show_commit(struct commit *commit, void *data) { struct rev_list_info *info = data; @@ -100,6 +147,12 @@ static void show_commit(struct commit *commit, void *data) display_progress(progress, ++progress_counter); + if (revs->do_not_die_on_missing_objects && + oidset_contains(&revs->missing_commits, &commit->object.oid)) { + finish_object__ma(&commit->object); + return; + } + if (show_disk_usage) total_disk_usage += get_object_disk_usage(&commit->object); @@ -130,7 +183,7 @@ static void show_commit(struct commit *commit, void *data) if (!revs->graph) fputs(get_revision_mark(revs, commit), stdout); if (revs->abbrev_commit && revs->abbrev) - fputs(find_unique_abbrev(&commit->object.oid, revs->abbrev), + fputs(repo_find_unique_abbrev(the_repository, &commit->object.oid, revs->abbrev), stdout); else fputs(oid_to_hex(&commit->object.oid), stdout); @@ -166,6 +219,7 @@ static void show_commit(struct commit *commit, void *data) ctx.fmt = revs->commit_format; ctx.output_encoding = get_log_output_encoding(); ctx.color = revs->diffopt.use_color; + ctx.rev = revs; pretty_print_commit(&ctx, commit, &buf); if (buf.len) { if (revs->commit_format != CMIT_FMT_ONELINE) @@ -211,49 +265,8 @@ static void show_commit(struct commit *commit, void *data) finish_commit(commit); } -static void finish_commit(struct commit *commit) -{ - free_commit_list(commit->parents); - commit->parents = NULL; - free_commit_buffer(the_repository->parsed_objects, - commit); -} - -static inline void finish_object__ma(struct object *obj) -{ - /* - * Whether or not we try to dynamically fetch missing objects - * from the server, we currently DO NOT have the object. We - * can either print, allow (ignore), or conditionally allow - * (ignore) them. - */ - switch (arg_missing_action) { - case MA_ERROR: - die("missing %s object '%s'", - type_name(obj->type), oid_to_hex(&obj->oid)); - return; - - case MA_ALLOW_ANY: - return; - - case MA_PRINT: - oidset_insert(&missing_objects, &obj->oid); - return; - - case MA_ALLOW_PROMISOR: - if (is_promisor_object(&obj->oid)) - return; - die("unexpected missing %s object '%s'", - type_name(obj->type), oid_to_hex(&obj->oid)); - return; - - default: - BUG("unhandled missing_action"); - return; - } -} - -static int finish_object(struct object *obj, const char *name, void *cb_data) +static int finish_object(struct object *obj, const char *name UNUSED, + void *cb_data) { struct rev_list_info *info = cb_data; if (oid_object_info_extended(the_repository, &obj->oid, NULL, 0) < 0) { @@ -358,16 +371,27 @@ static int show_bisect_vars(struct rev_list_info *info, int reaches, int all) static int show_object_fast( const struct object_id *oid, - enum object_type type, - int exclude, - uint32_t name_hash, - struct packed_git *found_pack, - off_t found_offset) + enum object_type type UNUSED, + int exclude UNUSED, + uint32_t name_hash UNUSED, + struct packed_git *found_pack UNUSED, + off_t found_offset UNUSED) { fprintf(stdout, "%s\n", oid_to_hex(oid)); return 1; } +static void print_disk_usage(off_t size) +{ + struct strbuf sb = STRBUF_INIT; + if (human_readable) + strbuf_humanise_bytes(&sb, size); + else + strbuf_addf(&sb, "%"PRIuMAX, (uintmax_t)size); + puts(sb.buf); + strbuf_release(&sb); +} + static inline int parse_missing_action_value(const char *value) { if (!strcmp(value, "error")) { @@ -473,6 +497,7 @@ static int try_bitmap_disk_usage(struct rev_info *revs, int filter_provided_objects) { struct bitmap_index *bitmap_git; + off_t size_from_bitmap; if (!show_disk_usage) return -1; @@ -481,8 +506,8 @@ static int try_bitmap_disk_usage(struct rev_info *revs, if (!bitmap_git) return -1; - printf("%"PRIuMAX"\n", - (uintmax_t)get_disk_usage_from_bitmap(bitmap_git, revs)); + size_from_bitmap = get_disk_usage_from_bitmap(bitmap_git, revs); + print_disk_usage(size_from_bitmap); return 0; } @@ -521,6 +546,18 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) * * Let "--missing" to conditionally set fetch_if_missing. */ + /* + * NEEDSWORK: These loops that attempt to find presence of + * options without understanding that the options they are + * skipping are broken (e.g., it would not know "--grep + * --exclude-promisor-objects" is not triggering + * "--exclude-promisor-objects" option). We really need + * setup_revisions() to have a mechanism to allow and disallow + * some sets of options for different commands (like rev-list, + * replay, etc). Such a mechanism should do an early parsing + * of options and be able to manage the `--missing=...` and + * `--exclude-promisor-objects` options below. + */ for (i = 1; i < argc; i++) { const char *arg = argv[i]; if (!strcmp(arg, "--exclude-promisor-objects")) { @@ -540,7 +577,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) } if (arg_missing_action) - revs.do_not_die_on_missing_tree = 1; + revs.do_not_die_on_missing_objects = 1; argc = setup_revisions(argc, argv, &revs, &s_r_opt); @@ -624,7 +661,21 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) continue; } - if (!strcmp(arg, "--disk-usage")) { + if (skip_prefix(arg, "--disk-usage", &arg)) { + if (*arg == '=') { + if (!strcmp(++arg, "human")) { + human_readable = 1; + } else + die(_("invalid value for '%s': '%s', the only allowed format is '%s'"), + "--disk-usage=<format>", arg, "human"); + } else if (*arg) { + /* + * Arguably should goto a label to continue chain of ifs? + * Doesn't matter unless we try to add --disk-usage-foo + * afterwards. + */ + usage(rev_list_usage); + } show_disk_usage = 1; info.flags |= REV_LIST_QUIET; continue; @@ -715,8 +766,12 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) if (arg_print_omitted) oidset_init(&omitted_objects, DEFAULT_OIDSET_SIZE); - if (arg_missing_action == MA_PRINT) + if (arg_missing_action == MA_PRINT) { oidset_init(&missing_objects, DEFAULT_OIDSET_SIZE); + /* Add missing tips */ + oidset_insert_from_set(&missing_objects, &revs.missing_commits); + oidset_clear(&revs.missing_commits); + } traverse_commit_list_filtered( &revs, show_commit, show_object, &info, @@ -753,7 +808,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) } if (show_disk_usage) - printf("%"PRIuMAX"\n", (uintmax_t)total_disk_usage); + print_disk_usage(total_disk_usage); cleanup: release_revisions(&revs); |