aboutsummaryrefslogtreecommitdiffstats
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/bisect.c38
-rw-r--r--builtin/checkout.c6
-rw-r--r--builtin/describe.c18
-rw-r--r--builtin/fast-export.c79
-rw-r--r--builtin/fast-import.c284
-rw-r--r--builtin/fetch.c13
-rw-r--r--builtin/fsck.c33
-rw-r--r--builtin/gc.c15
-rw-r--r--builtin/last-modified.c250
-rw-r--r--builtin/ls-remote.c2
-rw-r--r--builtin/name-rev.c17
-rw-r--r--builtin/pack-objects.c65
-rw-r--r--builtin/receive-pack.c13
-rw-r--r--builtin/remote.c44
-rw-r--r--builtin/replace.c21
-rw-r--r--builtin/repo.c377
-rw-r--r--builtin/rev-parse.c12
-rw-r--r--builtin/show-branch.c35
-rw-r--r--builtin/show-ref.c50
-rw-r--r--builtin/submodule--helper.c10
-rw-r--r--builtin/tag.c2
-rw-r--r--builtin/verify-tag.c2
-rw-r--r--builtin/worktree.c6
23 files changed, 975 insertions, 417 deletions
diff --git a/builtin/bisect.c b/builtin/bisect.c
index 993caf545d..4cc118fb57 100644
--- a/builtin/bisect.c
+++ b/builtin/bisect.c
@@ -27,13 +27,14 @@ static GIT_PATH_FUNC(git_path_bisect_first_parent, "BISECT_FIRST_PARENT")
static GIT_PATH_FUNC(git_path_bisect_run, "BISECT_RUN")
#define BUILTIN_GIT_BISECT_START_USAGE \
- N_("git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>]" \
- " [--no-checkout] [--first-parent] [<bad> [<good>...]] [--]" \
- " [<pathspec>...]")
-#define BUILTIN_GIT_BISECT_STATE_USAGE \
- N_("git bisect (good|bad) [<rev>...]")
+ N_("git bisect start [--term-(bad|new)=<term-new> --term-(good|old)=<term-old>]\n" \
+ " [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]")
+#define BUILTIN_GIT_BISECT_BAD_USAGE \
+ N_("git bisect (bad|new|<term-new>) [<rev>]")
+#define BUILTIN_GIT_BISECT_GOOD_USAGE \
+ N_("git bisect (good|old|<term-old>) [<rev>...]")
#define BUILTIN_GIT_BISECT_TERMS_USAGE \
- "git bisect terms [--term-good | --term-bad]"
+ "git bisect terms [--term-(good|old) | --term-(bad|new)]"
#define BUILTIN_GIT_BISECT_SKIP_USAGE \
N_("git bisect skip [(<rev>|<range>)...]")
#define BUILTIN_GIT_BISECT_NEXT_USAGE \
@@ -41,17 +42,20 @@ static GIT_PATH_FUNC(git_path_bisect_run, "BISECT_RUN")
#define BUILTIN_GIT_BISECT_RESET_USAGE \
N_("git bisect reset [<commit>]")
#define BUILTIN_GIT_BISECT_VISUALIZE_USAGE \
- "git bisect visualize"
+ "git bisect (visualize|view)"
#define BUILTIN_GIT_BISECT_REPLAY_USAGE \
N_("git bisect replay <logfile>")
#define BUILTIN_GIT_BISECT_LOG_USAGE \
"git bisect log"
#define BUILTIN_GIT_BISECT_RUN_USAGE \
N_("git bisect run <cmd> [<arg>...]")
+#define BUILTIN_GIT_BISECT_HELP_USAGE \
+ "git bisect help"
static const char * const git_bisect_usage[] = {
BUILTIN_GIT_BISECT_START_USAGE,
- BUILTIN_GIT_BISECT_STATE_USAGE,
+ BUILTIN_GIT_BISECT_BAD_USAGE,
+ BUILTIN_GIT_BISECT_GOOD_USAGE,
BUILTIN_GIT_BISECT_TERMS_USAGE,
BUILTIN_GIT_BISECT_SKIP_USAGE,
BUILTIN_GIT_BISECT_NEXT_USAGE,
@@ -60,6 +64,7 @@ static const char * const git_bisect_usage[] = {
BUILTIN_GIT_BISECT_REPLAY_USAGE,
BUILTIN_GIT_BISECT_LOG_USAGE,
BUILTIN_GIT_BISECT_RUN_USAGE,
+ BUILTIN_GIT_BISECT_HELP_USAGE,
NULL
};
@@ -358,10 +363,7 @@ static int check_and_set_terms(struct bisect_terms *terms, const char *cmd)
return 0;
}
-static int inc_nr(const char *refname UNUSED,
- const char *referent UNUSED,
- const struct object_id *oid UNUSED,
- int flag UNUSED, void *cb_data)
+static int inc_nr(const struct reference *ref UNUSED, void *cb_data)
{
unsigned int *nr = (unsigned int *)cb_data;
(*nr)++;
@@ -549,12 +551,11 @@ finish:
return res;
}
-static int add_bisect_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid,
- int flags UNUSED, void *cb)
+static int add_bisect_ref(const struct reference *ref, void *cb)
{
struct add_bisect_ref_data *data = cb;
- add_pending_oid(data->revs, refname, oid, data->object_flags);
+ add_pending_oid(data->revs, ref->name, ref->oid, data->object_flags);
return 0;
}
@@ -1165,12 +1166,9 @@ static int bisect_visualize(struct bisect_terms *terms, int argc,
return run_command(&cmd);
}
-static int get_first_good(const char *refname UNUSED,
- const char *referent UNUSED,
- const struct object_id *oid,
- int flag UNUSED, void *cb_data)
+static int get_first_good(const struct reference *ref, void *cb_data)
{
- oidcpy(cb_data, oid);
+ oidcpy(cb_data, ref->oid);
return 1;
}
diff --git a/builtin/checkout.c b/builtin/checkout.c
index f9453473fe..66b69df6e6 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1063,11 +1063,9 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
report_tracking(new_branch_info);
}
-static int add_pending_uninteresting_ref(const char *refname, const char *referent UNUSED,
- const struct object_id *oid,
- int flags UNUSED, void *cb_data)
+static int add_pending_uninteresting_ref(const struct reference *ref, void *cb_data)
{
- add_pending_oid(cb_data, refname, oid, UNINTERESTING);
+ add_pending_oid(cb_data, ref->name, ref->oid, UNINTERESTING);
return 0;
}
diff --git a/builtin/describe.c b/builtin/describe.c
index ffaf8d9f0a..443546aaac 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -154,20 +154,19 @@ static void add_to_known_names(const char *path,
}
}
-static int get_name(const char *path, const char *referent UNUSED, const struct object_id *oid,
- int flag UNUSED, void *cb_data UNUSED)
+static int get_name(const struct reference *ref, void *cb_data UNUSED)
{
int is_tag = 0;
struct object_id peeled;
int is_annotated, prio;
const char *path_to_match = NULL;
- if (skip_prefix(path, "refs/tags/", &path_to_match)) {
+ if (skip_prefix(ref->name, "refs/tags/", &path_to_match)) {
is_tag = 1;
} else if (all) {
if ((exclude_patterns.nr || patterns.nr) &&
- !skip_prefix(path, "refs/heads/", &path_to_match) &&
- !skip_prefix(path, "refs/remotes/", &path_to_match)) {
+ !skip_prefix(ref->name, "refs/heads/", &path_to_match) &&
+ !skip_prefix(ref->name, "refs/remotes/", &path_to_match)) {
/* Only accept reference of known type if there are match/exclude patterns */
return 0;
}
@@ -209,10 +208,10 @@ static int get_name(const char *path, const char *referent UNUSED, const struct
}
/* Is it annotated? */
- if (!peel_iterated_oid(the_repository, oid, &peeled)) {
- is_annotated = !oideq(oid, &peeled);
+ if (!reference_get_peeled_oid(the_repository, ref, &peeled)) {
+ is_annotated = !oideq(ref->oid, &peeled);
} else {
- oidcpy(&peeled, oid);
+ oidcpy(&peeled, ref->oid);
is_annotated = 0;
}
@@ -229,7 +228,8 @@ static int get_name(const char *path, const char *referent UNUSED, const struct
else
prio = 0;
- add_to_known_names(all ? path + 5 : path + 10, &peeled, prio, oid);
+ add_to_known_names(all ? ref->name + 5 : ref->name + 10,
+ &peeled, prio, ref->oid);
return 0;
}
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 7adbc55f0d..0421360ab7 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -65,7 +65,7 @@ static int parse_opt_sign_mode(const struct option *opt,
return 0;
if (parse_sign_mode(arg, val))
- return error("Unknown %s mode: %s", opt->long_name, arg);
+ return error(_("unknown %s mode: %s"), opt->long_name, arg);
return 0;
}
@@ -82,7 +82,7 @@ static int parse_opt_tag_of_filtered_mode(const struct option *opt,
else if (!strcmp(arg, "rewrite"))
*val = REWRITE;
else
- return error("Unknown tag-of-filtered mode: %s", arg);
+ return error(_("unknown tag-of-filtered mode: %s"), arg);
return 0;
}
@@ -107,7 +107,7 @@ static int parse_opt_reencode_mode(const struct option *opt,
if (!strcasecmp(arg, "abort"))
*val = REENCODE_ABORT;
else
- return error("Unknown reencoding mode: %s", arg);
+ return error(_("unknown reencoding mode: %s"), arg);
}
return 0;
@@ -318,16 +318,16 @@ static void export_blob(const struct object_id *oid)
} else {
buf = odb_read_object(the_repository->objects, oid, &type, &size);
if (!buf)
- die("could not read blob %s", oid_to_hex(oid));
+ die(_("could not read blob %s"), oid_to_hex(oid));
if (check_object_signature(the_repository, oid, buf, size,
type) < 0)
- die("oid mismatch in blob %s", oid_to_hex(oid));
+ die(_("oid mismatch in blob %s"), oid_to_hex(oid));
object = parse_object_buffer(the_repository, oid, type,
size, buf, &eaten);
}
if (!object)
- die("Could not read blob %s", oid_to_hex(oid));
+ die(_("could not read blob %s"), oid_to_hex(oid));
mark_next_object(object);
@@ -336,7 +336,7 @@ static void export_blob(const struct object_id *oid)
printf("original-oid %s\n", oid_to_hex(oid));
printf("data %"PRIuMAX"\n", (uintmax_t)size);
if (size && fwrite(buf, size, 1, stdout) != 1)
- die_errno("could not write blob '%s'", oid_to_hex(oid));
+ die_errno(_("could not write blob '%s'"), oid_to_hex(oid));
printf("\n");
show_progress();
@@ -499,10 +499,10 @@ static void show_filemodify(struct diff_queue_struct *q,
break;
default:
- die("Unexpected comparison status '%c' for %s, %s",
- q->queue[i]->status,
- ospec->path ? ospec->path : "none",
- spec->path ? spec->path : "none");
+ die(_("unexpected comparison status '%c' for %s, %s"),
+ q->queue[i]->status,
+ ospec->path ? ospec->path : _("none"),
+ spec->path ? spec->path : _("none"));
}
}
}
@@ -699,14 +699,14 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
author = strstr(commit_buffer_cursor, "\nauthor ");
if (!author)
- die("could not find author in commit %s",
+ die(_("could not find author in commit %s"),
oid_to_hex(&commit->object.oid));
author++;
commit_buffer_cursor = author_end = strchrnul(author, '\n');
committer = strstr(commit_buffer_cursor, "\ncommitter ");
if (!committer)
- die("could not find committer in commit %s",
+ die(_("could not find committer in commit %s"),
oid_to_hex(&commit->object.oid));
committer++;
commit_buffer_cursor = committer_end = strchrnul(committer, '\n');
@@ -781,8 +781,8 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
case REENCODE_NO:
break;
case REENCODE_ABORT:
- die("Encountered commit-specific encoding %.*s in commit "
- "%s; use --reencode=[yes|no] to handle it",
+ die(_("encountered commit-specific encoding %.*s in commit "
+ "%s; use --reencode=[yes|no] to handle it"),
(int)encoding_len, encoding,
oid_to_hex(&commit->object.oid));
}
@@ -798,11 +798,11 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
if (signatures.nr) {
switch (signed_commit_mode) {
case SIGN_ABORT:
- die("encountered signed commit %s; use "
- "--signed-commits=<mode> to handle it",
+ die(_("encountered signed commit %s; use "
+ "--signed-commits=<mode> to handle it"),
oid_to_hex(&commit->object.oid));
case SIGN_WARN_VERBATIM:
- warning("exporting %"PRIuMAX" signature(s) for commit %s",
+ warning(_("exporting %"PRIuMAX" signature(s) for commit %s"),
(uintmax_t)signatures.nr, oid_to_hex(&commit->object.oid));
/* fallthru */
case SIGN_VERBATIM:
@@ -812,7 +812,7 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
}
break;
case SIGN_WARN_STRIP:
- warning("stripping signature(s) from commit %s",
+ warning(_("stripping signature(s) from commit %s"),
oid_to_hex(&commit->object.oid));
/* fallthru */
case SIGN_STRIP:
@@ -890,7 +890,8 @@ static void handle_tag(const char *name, struct tag *tag)
tagged = ((struct tag *)tagged)->tagged;
}
if (tagged->type == OBJ_TREE) {
- warning("Omitting tag %s,\nsince tags of trees (or tags of tags of trees, etc.) are not supported.",
+ warning(_("omitting tag %s,\nsince tags of trees (or tags "
+ "of tags of trees, etc.) are not supported."),
oid_to_hex(&tag->object.oid));
return;
}
@@ -898,7 +899,7 @@ static void handle_tag(const char *name, struct tag *tag)
buf = odb_read_object(the_repository->objects, &tag->object.oid,
&type, &size);
if (!buf)
- die("could not read tag %s", oid_to_hex(&tag->object.oid));
+ die(_("could not read tag %s"), oid_to_hex(&tag->object.oid));
message = memmem(buf, size, "\n\n", 2);
if (message) {
message += 2;
@@ -935,17 +936,17 @@ static void handle_tag(const char *name, struct tag *tag)
if (sig_offset < message_size)
switch (signed_tag_mode) {
case SIGN_ABORT:
- die("encountered signed tag %s; use "
- "--signed-tags=<mode> to handle it",
+ die(_("encountered signed tag %s; use "
+ "--signed-tags=<mode> to handle it"),
oid_to_hex(&tag->object.oid));
case SIGN_WARN_VERBATIM:
- warning("exporting signed tag %s",
+ warning(_("exporting signed tag %s"),
oid_to_hex(&tag->object.oid));
/* fallthru */
case SIGN_VERBATIM:
break;
case SIGN_WARN_STRIP:
- warning("stripping signature from tag %s",
+ warning(_("stripping signature from tag %s"),
oid_to_hex(&tag->object.oid));
/* fallthru */
case SIGN_STRIP:
@@ -960,8 +961,8 @@ static void handle_tag(const char *name, struct tag *tag)
if (!tagged_mark) {
switch (tag_of_filtered_mode) {
case TAG_FILTERING_ABORT:
- die("tag %s tags unexported object; use "
- "--tag-of-filtered-object=<mode> to handle it",
+ die(_("tag %s tags unexported object; use "
+ "--tag-of-filtered-object=<mode> to handle it"),
oid_to_hex(&tag->object.oid));
case DROP:
/* Ignore this tag altogether */
@@ -969,7 +970,7 @@ static void handle_tag(const char *name, struct tag *tag)
return;
case REWRITE:
if (tagged->type == OBJ_TAG && !mark_tags) {
- die(_("Error: Cannot export nested tags unless --mark-tags is specified."));
+ die(_("cannot export nested tags unless --mark-tags is specified."));
} else if (tagged->type == OBJ_COMMIT) {
p = rewrite_commit((struct commit *)tagged);
if (!p) {
@@ -1025,7 +1026,7 @@ static struct commit *get_commit(struct rev_cmdline_entry *e, const char *full_n
tag = (struct tag *)tag->tagged;
}
if (!tag)
- die("Tag %s points nowhere?", e->name);
+ die(_("tag %s points nowhere?"), e->name);
return (struct commit *)tag;
}
default:
@@ -1063,7 +1064,7 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
commit = get_commit(e, full_name);
if (!commit) {
- warning("%s: Unexpected object of type %s, skipping.",
+ warning(_("%s: unexpected object of type %s, skipping."),
e->name,
type_name(e->item->type));
free(full_name);
@@ -1078,7 +1079,7 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
free(full_name);
continue;
default: /* OBJ_TAG (nested tags) is already handled */
- warning("Tag points to object of unexpected type %s, skipping.",
+ warning(_("tag points to object of unexpected type %s, skipping."),
type_name(commit->object.type));
free(full_name);
continue;
@@ -1174,7 +1175,7 @@ static void export_marks(char *file)
f = fopen_for_writing(file);
if (!f)
- die_errno("Unable to open marks file %s for writing.", file);
+ die_errno(_("unable to open marks file %s for writing."), file);
for (i = 0; i < idnums.size; i++) {
if (deco->base && deco->base->type == 1) {
@@ -1191,7 +1192,7 @@ static void export_marks(char *file)
e |= ferror(f);
e |= fclose(f);
if (e)
- error("Unable to write marks file %s.", file);
+ error(_("unable to write marks file %s."), file);
}
static void import_marks(char *input_file, int check_exists)
@@ -1214,20 +1215,20 @@ static void import_marks(char *input_file, int check_exists)
line_end = strchr(line, '\n');
if (line[0] != ':' || !line_end)
- die("corrupt mark line: %s", line);
+ die(_("corrupt mark line: %s"), line);
*line_end = '\0';
mark = strtoumax(line + 1, &mark_end, 10);
if (!mark || mark_end == line + 1
|| *mark_end != ' ' || get_oid_hex(mark_end + 1, &oid))
- die("corrupt mark line: %s", line);
+ die(_("corrupt mark line: %s"), line);
if (last_idnum < mark)
last_idnum = mark;
type = odb_read_object_info(the_repository->objects, &oid, NULL);
if (type < 0)
- die("object not found: %s", oid_to_hex(&oid));
+ die(_("object not found: %s"), oid_to_hex(&oid));
if (type != OBJ_COMMIT)
/* only commits */
@@ -1235,12 +1236,12 @@ static void import_marks(char *input_file, int check_exists)
commit = lookup_commit(the_repository, &oid);
if (!commit)
- die("not a commit? can't happen: %s", oid_to_hex(&oid));
+ die(_("not a commit? can't happen: %s"), oid_to_hex(&oid));
object = &commit->object;
if (object->flags & SHOWN)
- error("Object %s already has a mark", oid_to_hex(&oid));
+ error(_("object %s already has a mark"), oid_to_hex(&oid));
mark_object(object, mark);
@@ -1394,7 +1395,7 @@ int cmd_fast_export(int argc,
get_tags_and_duplicates(&revs.cmdline);
if (prepare_revision_walk(&revs))
- die("revision walk setup failed");
+ die(_("revision walk setup failed"));
revs.reverse = 1;
revs.diffopt.format_callback = show_filemodify;
diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 54d3e592c6..4cd0b079b6 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -339,12 +339,12 @@ static void write_crash_report(const char *err)
struct recent_command *rc;
if (!rpt) {
- error_errno("can't write crash report %s", loc);
+ error_errno(_("can't write crash report %s"), loc);
free(loc);
return;
}
- fprintf(stderr, "fast-import: dumping crash report to %s\n", loc);
+ fprintf(stderr, _("fast-import: dumping crash report to %s\n"), loc);
fprintf(rpt, "fast-import crash report:\n");
fprintf(rpt, " fast-import process: %"PRIuMAX"\n", (uintmax_t) getpid());
@@ -588,7 +588,7 @@ static void *find_mark(struct mark_set *s, uintmax_t idnum)
oe = s->data.marked[idnum];
}
if (!oe)
- die("mark :%" PRIuMAX " not declared", orig_idnum);
+ die(_("mark :%" PRIuMAX " not declared"), orig_idnum);
return oe;
}
@@ -628,9 +628,9 @@ static struct branch *new_branch(const char *name)
struct branch *b = lookup_branch(name);
if (b)
- die("Invalid attempt to create duplicate branch: %s", name);
+ die(_("invalid attempt to create duplicate branch: %s"), name);
if (check_refname_format(name, REFNAME_ALLOW_ONELEVEL))
- die("Branch name doesn't conform to GIT standards: %s", name);
+ die(_("branch name doesn't conform to Git standards: %s"), name);
b = mem_pool_calloc(&fi_mem_pool, 1, sizeof(struct branch));
b->name = mem_pool_strdup(&fi_mem_pool, name);
@@ -801,7 +801,7 @@ static const char *create_index(void)
*c++ = &e->idx;
last = idx + object_count;
if (c != last)
- die("internal consistency error creating the index");
+ die(_("internal consistency error creating the index"));
tmpfile = write_idx_file(the_repository, NULL, idx, object_count,
&pack_idx_opts, pack_data->hash);
@@ -819,18 +819,18 @@ static char *keep_pack(const char *curr_index_name)
keep_fd = safe_create_file_with_leading_directories(pack_data->repo,
name.buf);
if (keep_fd < 0)
- die_errno("cannot create keep file");
+ die_errno(_("cannot create keep file"));
write_or_die(keep_fd, keep_msg, strlen(keep_msg));
if (close(keep_fd))
- die_errno("failed to write keep file");
+ die_errno(_("failed to write keep file"));
odb_pack_name(pack_data->repo, &name, pack_data->hash, "pack");
if (finalize_object_file(pack_data->repo, pack_data->pack_name, name.buf))
- die("cannot store pack file");
+ die(_("cannot store pack file"));
odb_pack_name(pack_data->repo, &name, pack_data->hash, "idx");
if (finalize_object_file(pack_data->repo, curr_index_name, name.buf))
- die("cannot store index file");
+ die(_("cannot store index file"));
free((void *)curr_index_name);
return strbuf_detach(&name, NULL);
}
@@ -853,7 +853,7 @@ static int loosen_small_pack(const struct packed_git *p)
struct child_process unpack = CHILD_PROCESS_INIT;
if (lseek(p->pack_fd, 0, SEEK_SET) < 0)
- die_errno("Failed seeking to start of '%s'", p->pack_name);
+ die_errno(_("failed seeking to start of '%s'"), p->pack_name);
unpack.in = p->pack_fd;
unpack.git_cmd = 1;
@@ -903,7 +903,7 @@ static void end_packfile(void)
new_p = packfile_store_load_pack(pack_data->repo->objects->packfiles,
idx_name, 1);
if (!new_p)
- die("core git rejected index %s", idx_name);
+ die(_("core Git rejected index %s"), idx_name);
all_packs[pack_id] = new_p;
free(idx_name);
@@ -979,7 +979,7 @@ static int store_object(
if (e->idx.offset) {
duplicate_count_by_type[type]++;
return 1;
- } else if (find_oid_pack(&oid, packfile_store_get_packs(packs))) {
+ } else if (packfile_list_find_oid(packfile_store_get_packs(packs), &oid)) {
e->type = type;
e->pack_id = MAX_PACK_ID;
e->idx.offset = 1; /* just not zero! */
@@ -1090,7 +1090,7 @@ static int store_object(
static void truncate_pack(struct hashfile_checkpoint *checkpoint)
{
if (hashfile_truncate(pack_file, checkpoint))
- die_errno("cannot truncate pack to skip duplicate");
+ die_errno(_("cannot truncate pack to skip duplicate"));
pack_size = checkpoint->offset;
}
@@ -1138,7 +1138,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
size_t cnt = in_sz < len ? in_sz : (size_t)len;
size_t n = fread(in_buf, 1, cnt, stdin);
if (!n && feof(stdin))
- die("EOF in data (%" PRIuMAX " bytes remaining)", len);
+ die(_("EOF in data (%" PRIuMAX " bytes remaining)"), len);
git_hash_update(&c, in_buf, n);
s.next_in = in_buf;
@@ -1162,7 +1162,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
case Z_STREAM_END:
continue;
default:
- die("unexpected deflate failure: %d", status);
+ die(_("unexpected deflate failure: %d"), status);
}
}
git_deflate_end(&s);
@@ -1180,7 +1180,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
duplicate_count_by_type[OBJ_BLOB]++;
truncate_pack(&checkpoint);
- } else if (find_oid_pack(&oid, packfile_store_get_packs(packs))) {
+ } else if (packfile_list_find_oid(packfile_store_get_packs(packs), &oid)) {
e->type = OBJ_BLOB;
e->pack_id = MAX_PACK_ID;
e->idx.offset = 1; /* just not zero! */
@@ -1264,16 +1264,16 @@ static void load_tree(struct tree_entry *root)
myoe = find_object(oid);
if (myoe && myoe->pack_id != MAX_PACK_ID) {
if (myoe->type != OBJ_TREE)
- die("Not a tree: %s", oid_to_hex(oid));
+ die(_("not a tree: %s"), oid_to_hex(oid));
t->delta_depth = myoe->depth;
buf = gfi_unpack_entry(myoe, &size);
if (!buf)
- die("Can't load tree %s", oid_to_hex(oid));
+ die(_("can't load tree %s"), oid_to_hex(oid));
} else {
enum object_type type;
buf = odb_read_object(the_repository->objects, oid, &type, &size);
if (!buf || type != OBJ_TREE)
- die("Can't load tree %s", oid_to_hex(oid));
+ die(_("can't load tree %s"), oid_to_hex(oid));
}
c = buf;
@@ -1287,7 +1287,7 @@ static void load_tree(struct tree_entry *root)
e->tree = NULL;
c = parse_mode(c, &e->versions[1].mode);
if (!c)
- die("Corrupt mode in %s", oid_to_hex(oid));
+ die(_("corrupt mode in %s"), oid_to_hex(oid));
e->versions[0].mode = e->versions[1].mode;
e->name = to_atom(c, strlen(c));
c += e->name->str_len + 1;
@@ -1399,7 +1399,7 @@ static void tree_content_replace(
struct tree_content *newtree)
{
if (!S_ISDIR(mode))
- die("Root cannot be a non-directory");
+ die(_("root cannot be a non-directory"));
oidclr(&root->versions[0].oid, the_repository->hash_algo);
oidcpy(&root->versions[1].oid, oid);
if (root->tree)
@@ -1422,9 +1422,9 @@ static int tree_content_set(
slash1 = strchrnul(p, '/');
n = slash1 - p;
if (!n)
- die("Empty path component found in input");
+ die(_("empty path component found in input"));
if (!*slash1 && !S_ISDIR(mode) && subtree)
- die("Non-directories cannot have subtrees");
+ die(_("non-directories cannot have subtrees"));
if (!root->tree)
load_tree(root);
@@ -1576,7 +1576,7 @@ static int tree_content_get(
slash1 = strchrnul(p, '/');
n = slash1 - p;
if (!n && !allow_root)
- die("Empty path component found in input");
+ die(_("empty path component found in input"));
if (!root->tree)
load_tree(root);
@@ -1622,8 +1622,8 @@ static int update_branch(struct branch *b)
!strcmp(b->name + strlen(replace_prefix),
oid_to_hex(&b->oid))) {
if (!quiet)
- warning("Dropping %s since it would point to "
- "itself (i.e. to %s)",
+ warning(_("dropping %s since it would point to "
+ "itself (i.e. to %s)"),
b->name, oid_to_hex(&b->oid));
refs_delete_ref(get_main_ref_store(the_repository),
NULL, b->name, NULL, 0);
@@ -1646,14 +1646,14 @@ static int update_branch(struct branch *b)
new_cmit = lookup_commit_reference_gently(the_repository,
&b->oid, 0);
if (!old_cmit || !new_cmit)
- return error("Branch %s is missing commits.", b->name);
+ return error(_("branch %s is missing commits."), b->name);
ret = repo_in_merge_bases(the_repository, old_cmit, new_cmit);
if (ret < 0)
exit(128);
if (!ret) {
- warning("Not updating %s"
- " (new tip %s does not contain %s)",
+ warning(_("not updating %s"
+ " (new tip %s does not contain %s)"),
b->name, oid_to_hex(&b->oid),
oid_to_hex(&old_oid));
return -1;
@@ -1729,13 +1729,13 @@ static void dump_marks(void)
return;
if (safe_create_leading_directories_const(the_repository, export_marks_file)) {
- failure |= error_errno("unable to create leading directories of %s",
+ failure |= error_errno(_("unable to create leading directories of %s"),
export_marks_file);
return;
}
if (hold_lock_file_for_update(&mark_lock, export_marks_file, 0) < 0) {
- failure |= error_errno("Unable to write marks file %s",
+ failure |= error_errno(_("unable to write marks file %s"),
export_marks_file);
return;
}
@@ -1744,14 +1744,14 @@ static void dump_marks(void)
if (!f) {
int saved_errno = errno;
rollback_lock_file(&mark_lock);
- failure |= error("Unable to write marks file %s: %s",
+ failure |= error(_("unable to write marks file %s: %s"),
export_marks_file, strerror(saved_errno));
return;
}
for_each_mark(marks, 0, dump_marks_fn, f);
if (commit_lock_file(&mark_lock)) {
- failure |= error_errno("Unable to write file %s",
+ failure |= error_errno(_("unable to write file %s"),
export_marks_file);
return;
}
@@ -1765,7 +1765,7 @@ static void insert_object_entry(struct mark_set **s, struct object_id *oid, uint
enum object_type type = odb_read_object_info(the_repository->objects,
oid, NULL);
if (type < 0)
- die("object not found: %s", oid_to_hex(oid));
+ die(_("object not found: %s"), oid_to_hex(oid));
e = insert_object(oid);
e->type = type;
e->pack_id = MAX_PACK_ID;
@@ -1792,13 +1792,13 @@ static void read_mark_file(struct mark_set **s, FILE *f, mark_set_inserter_t ins
end = strchr(line, '\n');
if (line[0] != ':' || !end)
- die("corrupt mark line: %s", line);
+ die(_("corrupt mark line: %s"), line);
*end = 0;
mark = strtoumax(line + 1, &end, 10);
if (!mark || end == line + 1
|| *end != ' '
|| get_oid_hex_any(end + 1, &oid) == GIT_HASH_UNKNOWN)
- die("corrupt mark line: %s", line);
+ die(_("corrupt mark line: %s"), line);
inserter(s, &oid, mark);
}
}
@@ -1811,7 +1811,7 @@ static void read_marks(void)
else if (import_marks_file_ignore_missing && errno == ENOENT)
goto done; /* Marks file does not exist */
else
- die_errno("cannot read '%s'", import_marks_file);
+ die_errno(_("cannot read '%s'"), import_marks_file);
read_mark_file(&marks, f, insert_object_entry);
fclose(f);
done:
@@ -1897,7 +1897,7 @@ static int parse_data(struct strbuf *sb, uintmax_t limit, uintmax_t *len_res)
strbuf_reset(sb);
if (!skip_prefix(command_buf.buf, "data ", &data))
- die("Expected 'data n' command, found: %s", command_buf.buf);
+ die(_("expected 'data n' command, found: %s"), command_buf.buf);
if (skip_prefix(data, "<<", &data)) {
char *term = xstrdup(data);
@@ -1905,7 +1905,7 @@ static int parse_data(struct strbuf *sb, uintmax_t limit, uintmax_t *len_res)
for (;;) {
if (strbuf_getline_lf(&command_buf, stdin) == EOF)
- die("EOF in data (terminator '%s' not found)", term);
+ die(_("EOF in data (terminator '%s' not found)"), term);
if (term_len == command_buf.len
&& !strcmp(term, command_buf.buf))
break;
@@ -1923,12 +1923,12 @@ static int parse_data(struct strbuf *sb, uintmax_t limit, uintmax_t *len_res)
return 0;
}
if (length < len)
- die("data is too large to use in this context");
+ die(_("data is too large to use in this context"));
while (n < length) {
size_t s = strbuf_fread(sb, length - n, stdin);
if (!s && feof(stdin))
- die("EOF in data (%lu bytes remaining)",
+ die(_("EOF in data (%lu bytes remaining)"),
(unsigned long)(length - n));
n += s;
}
@@ -1985,15 +1985,15 @@ static char *parse_ident(const char *buf)
ltgt = buf + strcspn(buf, "<>");
if (*ltgt != '<')
- die("Missing < in ident string: %s", buf);
+ die(_("missing < in ident string: %s"), buf);
if (ltgt != buf && ltgt[-1] != ' ')
- die("Missing space before < in ident string: %s", buf);
+ die(_("missing space before < in ident string: %s"), buf);
ltgt = ltgt + 1 + strcspn(ltgt + 1, "<>");
if (*ltgt != '>')
- die("Missing > in ident string: %s", buf);
+ die(_("missing > in ident string: %s"), buf);
ltgt++;
if (*ltgt != ' ')
- die("Missing space after > in ident string: %s", buf);
+ die(_("missing space after > in ident string: %s"), buf);
ltgt++;
name_len = ltgt - buf;
strbuf_add(&ident, buf, name_len);
@@ -2001,19 +2001,19 @@ static char *parse_ident(const char *buf)
switch (whenspec) {
case WHENSPEC_RAW:
if (validate_raw_date(ltgt, &ident, 1) < 0)
- die("Invalid raw date \"%s\" in ident: %s", ltgt, buf);
+ die(_("invalid raw date \"%s\" in ident: %s"), ltgt, buf);
break;
case WHENSPEC_RAW_PERMISSIVE:
if (validate_raw_date(ltgt, &ident, 0) < 0)
- die("Invalid raw date \"%s\" in ident: %s", ltgt, buf);
+ die(_("invalid raw date \"%s\" in ident: %s"), ltgt, buf);
break;
case WHENSPEC_RFC2822:
if (parse_date(ltgt, &ident) < 0)
- die("Invalid rfc2822 date \"%s\" in ident: %s", ltgt, buf);
+ die(_("invalid rfc2822 date \"%s\" in ident: %s"), ltgt, buf);
break;
case WHENSPEC_NOW:
if (strcmp("now", ltgt))
- die("Date in ident must be 'now': %s", buf);
+ die(_("date in ident must be 'now': %s"), buf);
datestamp(&ident);
break;
}
@@ -2107,7 +2107,7 @@ static void construct_path_with_fanout(const char *hex_sha1,
{
unsigned int i = 0, j = 0;
if (fanout >= the_hash_algo->rawsz)
- die("Too large fanout (%u)", fanout);
+ die(_("too large fanout (%u)"), fanout);
while (fanout) {
path[i++] = hex_sha1[j++];
path[i++] = hex_sha1[j++];
@@ -2181,7 +2181,7 @@ static uintmax_t do_change_note_fanout(
/* Rename fullpath to realpath */
if (!tree_content_remove(orig_root, fullpath, &leaf, 0))
- die("Failed to remove path %s", fullpath);
+ die(_("failed to remove path %s"), fullpath);
tree_content_set(orig_root, realpath,
&leaf.versions[1].oid,
leaf.versions[1].mode,
@@ -2254,7 +2254,7 @@ static uintmax_t parse_mark_ref(const char *p, char **endptr)
p++;
mark = strtoumax(p, endptr, 10);
if (*endptr == p)
- die("No value after ':' in mark: %s", command_buf.buf);
+ die(_("no value after ':' in mark: %s"), command_buf.buf);
return mark;
}
@@ -2269,7 +2269,7 @@ static uintmax_t parse_mark_ref_eol(const char *p)
mark = parse_mark_ref(p, &end);
if (*end != '\0')
- die("Garbage after mark: %s", command_buf.buf);
+ die(_("garbage after mark: %s"), command_buf.buf);
return mark;
}
@@ -2284,7 +2284,7 @@ static uintmax_t parse_mark_ref_space(const char **p)
mark = parse_mark_ref(*p, &end);
if (*end++ != ' ')
- die("Missing space after mark: %s", command_buf.buf);
+ die(_("missing space after mark: %s"), command_buf.buf);
*p = end;
return mark;
}
@@ -2300,9 +2300,9 @@ static void parse_path(struct strbuf *sb, const char *p, const char **endp,
{
if (*p == '"') {
if (unquote_c_style(sb, p, endp))
- die("Invalid %s: %s", field, command_buf.buf);
+ die(_("invalid %s: %s"), field, command_buf.buf);
if (strlen(sb->buf) != sb->len)
- die("NUL in %s: %s", field, command_buf.buf);
+ die(_("NUL in %s: %s"), field, command_buf.buf);
} else {
/*
* Unless we are parsing the last field of a line,
@@ -2325,7 +2325,7 @@ static void parse_path_eol(struct strbuf *sb, const char *p, const char *field)
parse_path(sb, p, &end, 1, field);
if (*end)
- die("Garbage after %s: %s", field, command_buf.buf);
+ die(_("garbage after %s: %s"), field, command_buf.buf);
}
/*
@@ -2338,7 +2338,7 @@ static void parse_path_space(struct strbuf *sb, const char *p,
{
parse_path(sb, p, endp, 0, field);
if (**endp != ' ')
- die("Missing space after %s: %s", field, command_buf.buf);
+ die(_("missing space after %s: %s"), field, command_buf.buf);
(*endp)++;
}
@@ -2351,7 +2351,7 @@ static void file_change_m(const char *p, struct branch *b)
p = parse_mode(p, &mode);
if (!p)
- die("Corrupt mode: %s", command_buf.buf);
+ die(_("corrupt mode: %s"), command_buf.buf);
switch (mode) {
case 0644:
case 0755:
@@ -2364,7 +2364,7 @@ static void file_change_m(const char *p, struct branch *b)
/* ok */
break;
default:
- die("Corrupt mode: %s", command_buf.buf);
+ die(_("corrupt mode: %s"), command_buf.buf);
}
if (*p == ':') {
@@ -2375,10 +2375,10 @@ static void file_change_m(const char *p, struct branch *b)
oe = NULL; /* not used with inline_data, but makes gcc happy */
} else {
if (parse_mapped_oid_hex(p, &oid, &p))
- die("Invalid dataref: %s", command_buf.buf);
+ die(_("invalid dataref: %s"), command_buf.buf);
oe = find_object(&oid);
if (*p++ != ' ')
- die("Missing space after SHA1: %s", command_buf.buf);
+ die(_("missing space after SHA1: %s"), command_buf.buf);
}
strbuf_reset(&path);
@@ -2394,11 +2394,11 @@ static void file_change_m(const char *p, struct branch *b)
if (S_ISGITLINK(mode)) {
if (inline_data)
- die("Git links cannot be specified 'inline': %s",
+ die(_("Git links cannot be specified 'inline': %s"),
command_buf.buf);
else if (oe) {
if (oe->type != OBJ_COMMIT)
- die("Not a commit (actually a %s): %s",
+ die(_("not a commit (actually a %s): %s"),
type_name(oe->type), command_buf.buf);
}
/*
@@ -2407,7 +2407,7 @@ static void file_change_m(const char *p, struct branch *b)
*/
} else if (inline_data) {
if (S_ISDIR(mode))
- die("Directories cannot be specified 'inline': %s",
+ die(_("directories cannot be specified 'inline': %s"),
command_buf.buf);
while (read_next_command() != EOF) {
const char *v;
@@ -2425,11 +2425,11 @@ static void file_change_m(const char *p, struct branch *b)
odb_read_object_info(the_repository->objects,
&oid, NULL);
if (type < 0)
- die("%s not found: %s",
- S_ISDIR(mode) ? "Tree" : "Blob",
- command_buf.buf);
+ die(_("%s not found: %s"),
+ S_ISDIR(mode) ? _("tree") : _("blob"),
+ command_buf.buf);
if (type != expected)
- die("Not a %s (actually a %s): %s",
+ die(_("not a %s (actually a %s): %s"),
type_name(expected), type_name(type),
command_buf.buf);
}
@@ -2440,7 +2440,7 @@ static void file_change_m(const char *p, struct branch *b)
}
if (!verify_path(path.buf, mode))
- die("invalid path '%s'", path.buf);
+ die(_("invalid path '%s'"), path.buf);
tree_content_set(&b->branch_tree, path.buf, &oid, mode, NULL);
}
@@ -2470,7 +2470,7 @@ static void file_change_cr(const char *p, struct branch *b, int rename)
else
tree_content_get(&b->branch_tree, source.buf, &leaf, 1);
if (!leaf.versions[1].mode)
- die("Path %s not in branch", source.buf);
+ die(_("path %s not in branch"), source.buf);
if (!*dest.buf) { /* C "path/to/subdir" "" */
tree_content_replace(&b->branch_tree,
&leaf.versions[1].oid,
@@ -2479,7 +2479,7 @@ static void file_change_cr(const char *p, struct branch *b, int rename)
return;
}
if (!verify_path(dest.buf, leaf.versions[1].mode))
- die("invalid path '%s'", dest.buf);
+ die(_("invalid path '%s'"), dest.buf);
tree_content_set(&b->branch_tree, dest.buf,
&leaf.versions[1].oid,
leaf.versions[1].mode,
@@ -2521,23 +2521,23 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa
oe = NULL; /* not used with inline_data, but makes gcc happy */
} else {
if (parse_mapped_oid_hex(p, &oid, &p))
- die("Invalid dataref: %s", command_buf.buf);
+ die(_("invalid dataref: %s"), command_buf.buf);
oe = find_object(&oid);
if (*p++ != ' ')
- die("Missing space after SHA1: %s", command_buf.buf);
+ die(_("missing space after SHA1: %s"), command_buf.buf);
}
/* <commit-ish> */
s = lookup_branch(p);
if (s) {
if (is_null_oid(&s->oid))
- die("Can't add a note on empty branch.");
+ die(_("can't add a note on empty branch."));
oidcpy(&commit_oid, &s->oid);
} else if (*p == ':') {
uintmax_t commit_mark = parse_mark_ref_eol(p);
struct object_entry *commit_oe = find_mark(marks, commit_mark);
if (commit_oe->type != OBJ_COMMIT)
- die("Mark :%" PRIuMAX " not a commit", commit_mark);
+ die(_("mark :%" PRIuMAX " not a commit"), commit_mark);
oidcpy(&commit_oid, &commit_oe->idx.oid);
} else if (!repo_get_oid(the_repository, p, &commit_oid)) {
unsigned long size;
@@ -2545,25 +2545,25 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa
&commit_oid, OBJ_COMMIT, &size,
&commit_oid);
if (!buf || size < the_hash_algo->hexsz + 6)
- die("Not a valid commit: %s", p);
+ die(_("not a valid commit: %s"), p);
free(buf);
} else
- die("Invalid ref name or SHA1 expression: %s", p);
+ die(_("invalid ref name or SHA1 expression: %s"), p);
if (inline_data) {
read_next_command();
parse_and_store_blob(&last_blob, &oid, 0);
} else if (oe) {
if (oe->type != OBJ_BLOB)
- die("Not a blob (actually a %s): %s",
+ die(_("not a blob (actually a %s): %s"),
type_name(oe->type), command_buf.buf);
} else if (!is_null_oid(&oid)) {
enum object_type type = odb_read_object_info(the_repository->objects, &oid,
NULL);
if (type < 0)
- die("Blob not found: %s", command_buf.buf);
+ die(_("blob not found: %s"), command_buf.buf);
if (type != OBJ_BLOB)
- die("Not a blob (actually a %s): %s",
+ die(_("not a blob (actually a %s): %s"),
type_name(type), command_buf.buf);
}
@@ -2592,10 +2592,10 @@ static void file_change_deleteall(struct branch *b)
static void parse_from_commit(struct branch *b, char *buf, unsigned long size)
{
if (!buf || size < the_hash_algo->hexsz + 6)
- die("Not a valid commit: %s", oid_to_hex(&b->oid));
+ die(_("not a valid commit: %s"), oid_to_hex(&b->oid));
if (memcmp("tree ", buf, 5)
|| get_oid_hex(buf + 5, &b->branch_tree.versions[1].oid))
- die("The commit %s is corrupt", oid_to_hex(&b->oid));
+ die(_("the commit %s is corrupt"), oid_to_hex(&b->oid));
oidcpy(&b->branch_tree.versions[0].oid,
&b->branch_tree.versions[1].oid);
}
@@ -2625,7 +2625,7 @@ static int parse_objectish(struct branch *b, const char *objectish)
s = lookup_branch(objectish);
if (b == s)
- die("Can't create a branch from itself: %s", b->name);
+ die(_("can't create a branch from itself: %s"), b->name);
else if (s) {
struct object_id *t = &s->branch_tree.versions[1].oid;
oidcpy(&b->oid, &s->oid);
@@ -2635,7 +2635,7 @@ static int parse_objectish(struct branch *b, const char *objectish)
uintmax_t idnum = parse_mark_ref_eol(objectish);
struct object_entry *oe = find_mark(marks, idnum);
if (oe->type != OBJ_COMMIT)
- die("Mark :%" PRIuMAX " not a commit", idnum);
+ die(_("mark :%" PRIuMAX " not a commit"), idnum);
if (!oideq(&b->oid, &oe->idx.oid)) {
oidcpy(&b->oid, &oe->idx.oid);
if (oe->pack_id != MAX_PACK_ID) {
@@ -2652,7 +2652,7 @@ static int parse_objectish(struct branch *b, const char *objectish)
b->delete = 1;
}
else
- die("Invalid ref name or SHA1 expression: %s", objectish);
+ die(_("invalid ref name or SHA1 expression: %s"), objectish);
if (b->branch_tree.tree && !oideq(&oid, &b->branch_tree.versions[1].oid)) {
release_tree_content_recursive(b->branch_tree.tree);
@@ -2699,7 +2699,7 @@ static struct hash_list *parse_merge(unsigned int *count)
uintmax_t idnum = parse_mark_ref_eol(from);
struct object_entry *oe = find_mark(marks, idnum);
if (oe->type != OBJ_COMMIT)
- die("Mark :%" PRIuMAX " not a commit", idnum);
+ die(_("mark :%" PRIuMAX " not a commit"), idnum);
oidcpy(&n->oid, &oe->idx.oid);
} else if (!repo_get_oid(the_repository, from, &n->oid)) {
unsigned long size;
@@ -2707,10 +2707,10 @@ static struct hash_list *parse_merge(unsigned int *count)
&n->oid, OBJ_COMMIT,
&size, &n->oid);
if (!buf || size < the_hash_algo->hexsz + 6)
- die("Not a valid commit: %s", from);
+ die(_("not a valid commit: %s"), from);
free(buf);
} else
- die("Invalid ref name or SHA1 expression: %s", from);
+ die(_("invalid ref name or SHA1 expression: %s"), from);
n->next = NULL;
*tail = n;
@@ -2734,8 +2734,8 @@ static void parse_one_signature(struct signature_data *sig, const char *v)
char *space = strchr(args, ' ');
if (!space)
- die("Expected gpgsig format: 'gpgsig <hash-algo> <signature-format>', "
- "got 'gpgsig %s'", args);
+ die(_("expected gpgsig format: 'gpgsig <hash-algo> <signature-format>', "
+ "got 'gpgsig %s'"), args);
*space = '\0';
sig->hash_algo = args;
@@ -2744,13 +2744,13 @@ static void parse_one_signature(struct signature_data *sig, const char *v)
/* Validate hash algorithm */
if (strcmp(sig->hash_algo, "sha1") &&
strcmp(sig->hash_algo, "sha256"))
- die("Unknown git hash algorithm in gpgsig: '%s'", sig->hash_algo);
+ die(_("unknown git hash algorithm in gpgsig: '%s'"), sig->hash_algo);
/* Validate signature format */
if (!valid_signature_format(sig->sig_format))
- die("Invalid signature format in gpgsig: '%s'", sig->sig_format);
+ die(_("invalid signature format in gpgsig: '%s'"), sig->sig_format);
if (!strcmp(sig->sig_format, "unknown"))
- warning("'unknown' signature format in gpgsig");
+ warning(_("'unknown' signature format in gpgsig"));
/* Read signature data */
read_next_command();
@@ -2789,8 +2789,8 @@ static void store_signature(struct signature_data *stored_sig,
const char *hash_type)
{
if (stored_sig->hash_algo) {
- warning("multiple %s signatures found, "
- "ignoring additional signature",
+ warning(_("multiple %s signatures found, "
+ "ignoring additional signature"),
hash_type);
strbuf_release(&new_sig->data);
free(new_sig->hash_algo);
@@ -2845,15 +2845,15 @@ static void parse_new_commit(const char *arg)
read_next_command();
}
if (!committer)
- die("Expected committer but didn't get one");
+ die(_("expected committer but didn't get one"));
while (skip_prefix(command_buf.buf, "gpgsig ", &v)) {
switch (signed_commit_mode) {
/* First, modes that don't need the signature to be parsed */
case SIGN_ABORT:
- die("encountered signed commit; use "
- "--signed-commits=<mode> to handle it");
+ die(_("encountered signed commit; use "
+ "--signed-commits=<mode> to handle it"));
case SIGN_WARN_STRIP:
warning(_("stripping a commit signature"));
/* fallthru */
@@ -3025,11 +3025,11 @@ static void parse_new_tag(const char *arg)
/* from ... */
if (!skip_prefix(command_buf.buf, "from ", &from))
- die("Expected from command, got %s", command_buf.buf);
+ die(_("expected 'from' command, got '%s'"), command_buf.buf);
s = lookup_branch(from);
if (s) {
if (is_null_oid(&s->oid))
- die("Can't tag an empty branch.");
+ die(_("can't tag an empty branch."));
oidcpy(&oid, &s->oid);
type = OBJ_COMMIT;
} else if (*from == ':') {
@@ -3044,11 +3044,11 @@ static void parse_new_tag(const char *arg)
type = odb_read_object_info(the_repository->objects,
&oid, NULL);
if (type < 0)
- die("Not a valid object: %s", from);
+ die(_("not a valid object: %s"), from);
} else
type = oe->type;
} else
- die("Invalid ref name or SHA1 expression: %s", from);
+ die(_("invalid ref name or SHA1 expression: %s"), from);
read_next_command();
/* original-oid ... */
@@ -3139,7 +3139,7 @@ static void parse_reset_branch(const char *arg)
static void cat_blob_write(const char *buf, unsigned long size)
{
if (write_in_full(cat_blob_fd, buf, size) < 0)
- die_errno("Write to frontend failed");
+ die_errno(_("write to frontend failed"));
}
static void cat_blob(struct object_entry *oe, struct object_id *oid)
@@ -3168,9 +3168,9 @@ static void cat_blob(struct object_entry *oe, struct object_id *oid)
return;
}
if (!buf)
- die("Can't read object %s", oid_to_hex(oid));
+ die(_("can't read object %s"), oid_to_hex(oid));
if (type != OBJ_BLOB)
- die("Object %s is a %s but a blob was expected.",
+ die(_("object %s is a %s but a blob was expected."),
oid_to_hex(oid), type_name(type));
strbuf_reset(&line);
strbuf_addf(&line, "%s %s %"PRIuMAX"\n", oid_to_hex(oid),
@@ -3194,11 +3194,11 @@ static void parse_get_mark(const char *p)
/* get-mark SP <object> LF */
if (*p != ':')
- die("Not a mark: %s", p);
+ die(_("not a mark: %s"), p);
oe = find_mark(marks, parse_mark_ref_eol(p));
if (!oe)
- die("Unknown mark: %s", command_buf.buf);
+ die(_("unknown mark: %s"), command_buf.buf);
xsnprintf(output, sizeof(output), "%s\n", oid_to_hex(&oe->idx.oid));
cat_blob_write(output, the_hash_algo->hexsz + 1);
@@ -3213,13 +3213,13 @@ static void parse_cat_blob(const char *p)
if (*p == ':') {
oe = find_mark(marks, parse_mark_ref_eol(p));
if (!oe)
- die("Unknown mark: %s", command_buf.buf);
+ die(_("unknown mark: %s"), command_buf.buf);
oidcpy(&oid, &oe->idx.oid);
} else {
if (parse_mapped_oid_hex(p, &oid, &p))
- die("Invalid dataref: %s", command_buf.buf);
+ die(_("invalid dataref: %s"), command_buf.buf);
if (*p)
- die("Garbage after SHA1: %s", command_buf.buf);
+ die(_("garbage after SHA1: %s"), command_buf.buf);
oe = find_object(&oid);
}
@@ -3237,7 +3237,7 @@ static struct object_entry *dereference(struct object_entry *oe,
enum object_type type = odb_read_object_info(the_repository->objects,
oid, NULL);
if (type < 0)
- die("object not found: %s", oid_to_hex(oid));
+ die(_("object not found: %s"), oid_to_hex(oid));
/* cache it! */
oe = insert_object(oid);
oe->type = type;
@@ -3251,7 +3251,7 @@ static struct object_entry *dereference(struct object_entry *oe,
case OBJ_TAG:
break;
default:
- die("Not a tree-ish: %s", command_buf.buf);
+ die(_("not a tree-ish: %s"), command_buf.buf);
}
if (oe->pack_id != MAX_PACK_ID) { /* in a pack being written */
@@ -3262,19 +3262,19 @@ static struct object_entry *dereference(struct object_entry *oe,
&unused, &size);
}
if (!buf)
- die("Can't load object %s", oid_to_hex(oid));
+ die(_("can't load object %s"), oid_to_hex(oid));
/* Peel one layer. */
switch (oe->type) {
case OBJ_TAG:
if (size < hexsz + strlen("object ") ||
get_oid_hex(buf + strlen("object "), oid))
- die("Invalid SHA1 in tag: %s", command_buf.buf);
+ die(_("invalid SHA1 in tag: %s"), command_buf.buf);
break;
case OBJ_COMMIT:
if (size < hexsz + strlen("tree ") ||
get_oid_hex(buf + strlen("tree "), oid))
- die("Invalid SHA1 in commit: %s", command_buf.buf);
+ die(_("invalid SHA1 in commit: %s"), command_buf.buf);
}
free(buf);
@@ -3309,9 +3309,9 @@ static void build_mark_map(struct string_list *from, struct string_list *to)
for_each_string_list_item(fromp, from) {
top = string_list_lookup(to, fromp->string);
if (!fromp->util) {
- die(_("Missing from marks for submodule '%s'"), fromp->string);
+ die(_("missing from marks for submodule '%s'"), fromp->string);
} else if (!top || !top->util) {
- die(_("Missing to marks for submodule '%s'"), fromp->string);
+ die(_("missing to marks for submodule '%s'"), fromp->string);
}
build_mark_map_one(fromp->util, top->util);
}
@@ -3325,14 +3325,14 @@ static struct object_entry *parse_treeish_dataref(const char **p)
if (**p == ':') { /* <mark> */
e = find_mark(marks, parse_mark_ref_space(p));
if (!e)
- die("Unknown mark: %s", command_buf.buf);
+ die(_("unknown mark: %s"), command_buf.buf);
oidcpy(&oid, &e->idx.oid);
} else { /* <sha1> */
if (parse_mapped_oid_hex(*p, &oid, p))
- die("Invalid dataref: %s", command_buf.buf);
+ die(_("invalid dataref: %s"), command_buf.buf);
e = find_object(&oid);
if (*(*p)++ != ' ')
- die("Missing space after tree-ish: %s", command_buf.buf);
+ die(_("missing space after tree-ish: %s"), command_buf.buf);
}
while (!e || e->type != OBJ_TREE)
@@ -3376,7 +3376,7 @@ static void parse_ls(const char *p, struct branch *b)
/* ls SP (<tree-ish> SP)? <path> */
if (*p == '"') {
if (!b)
- die("Not in a commit: %s", command_buf.buf);
+ die(_("not in a commit: %s"), command_buf.buf);
root = &b->branch_tree;
} else {
struct object_entry *e = parse_treeish_dataref(&p);
@@ -3439,12 +3439,12 @@ static void parse_alias(void)
/* mark ... */
parse_mark();
if (!next_mark)
- die(_("Expected 'mark' command, got %s"), command_buf.buf);
+ die(_("expected 'mark' command, got %s"), command_buf.buf);
/* to ... */
memset(&b, 0, sizeof(b));
if (!parse_objectish_with_prefix(&b, "to "))
- die(_("Expected 'to' command, got %s"), command_buf.buf);
+ die(_("expected 'to' command, got %s"), command_buf.buf);
e = find_object(&b.oid);
assert(e);
insert_mark(&marks, next_mark, e);
@@ -3462,7 +3462,7 @@ static void option_import_marks(const char *marks,
{
if (import_marks_file) {
if (from_stream)
- die("Only one import-marks command allowed per stream");
+ die(_("only one import-marks command allowed per stream"));
/* read previous mark file */
if(!import_marks_file_from_stream)
@@ -3486,7 +3486,7 @@ static void option_date_format(const char *fmt)
else if (!strcmp(fmt, "now"))
whenspec = WHENSPEC_NOW;
else
- die("unknown --date-format argument %s", fmt);
+ die(_("unknown --date-format argument %s"), fmt);
}
static unsigned long ulong_arg(const char *option, const char *arg)
@@ -3494,7 +3494,7 @@ static unsigned long ulong_arg(const char *option, const char *arg)
char *endptr;
unsigned long rv = strtoul(arg, &endptr, 0);
if (strchr(arg, '-') || endptr == arg || *endptr)
- die("%s: argument must be a non-negative integer", option);
+ die(_("%s: argument must be a non-negative integer"), option);
return rv;
}
@@ -3502,7 +3502,7 @@ static void option_depth(const char *depth)
{
max_depth = ulong_arg("--depth", depth);
if (max_depth > MAX_DEPTH)
- die("--depth cannot exceed %u", MAX_DEPTH);
+ die(_("--depth cannot exceed %u"), MAX_DEPTH);
}
static void option_active_branches(const char *branches)
@@ -3520,7 +3520,7 @@ static void option_cat_blob_fd(const char *fd)
{
unsigned long n = ulong_arg("--cat-blob-fd", fd);
if (n > (unsigned long) INT_MAX)
- die("--cat-blob-fd cannot exceed %d", INT_MAX);
+ die(_("--cat-blob-fd cannot exceed %d"), INT_MAX);
cat_blob_fd = (int) n;
}
@@ -3540,7 +3540,7 @@ static void option_rewrite_submodules(const char *arg, struct string_list *list)
char *s = xstrdup(arg);
char *f = strchr(s, ':');
if (!f)
- die(_("Expected format name:filename for submodule rewrite option"));
+ die(_("expected format name:filename for submodule rewrite option"));
*f = '\0';
f++;
CALLOC_ARRAY(ms, 1);
@@ -3548,7 +3548,7 @@ static void option_rewrite_submodules(const char *arg, struct string_list *list)
f = prefix_filename(global_prefix, f);
fp = fopen(f, "r");
if (!fp)
- die_errno("cannot read '%s'", f);
+ die_errno(_("cannot read '%s'"), f);
read_mark_file(&ms, fp, insert_oid_entry);
fclose(fp);
free(f);
@@ -3565,10 +3565,10 @@ static int parse_one_option(const char *option)
if (!git_parse_ulong(option, &v))
return 0;
if (v < 8192) {
- warning("max-pack-size is now in bytes, assuming --max-pack-size=%lum", v);
+ warning(_("max-pack-size is now in bytes, assuming --max-pack-size=%lum"), v);
v *= 1024 * 1024;
} else if (v < 1024 * 1024) {
- warning("minimum max-pack-size is 1 MiB");
+ warning(_("minimum max-pack-size is 1 MiB"));
v = 1024 * 1024;
}
max_packsize = v;
@@ -3655,23 +3655,23 @@ static int parse_one_feature(const char *feature, int from_stream)
static void parse_feature(const char *feature)
{
if (seen_data_command)
- die("Got feature command '%s' after data command", feature);
+ die(_("got feature command '%s' after data command"), feature);
if (parse_one_feature(feature, 1))
return;
- die("This version of fast-import does not support feature %s.", feature);
+ die(_("this version of fast-import does not support feature %s."), feature);
}
static void parse_option(const char *option)
{
if (seen_data_command)
- die("Got option command '%s' after data command", option);
+ die(_("got option command '%s' after data command"), option);
if (parse_one_option(option))
return;
- die("This version of fast-import does not support option: %s", option);
+ die(_("this version of fast-import does not support option: %s"), option);
}
static void git_pack_config(void)
@@ -3715,7 +3715,7 @@ static void parse_argv(void)
break;
if (!skip_prefix(a, "--", &a))
- die("unknown option %s", a);
+ die(_("unknown option %s"), a);
if (parse_one_option(a))
continue;
@@ -3728,7 +3728,7 @@ static void parse_argv(void)
continue;
}
- die("unknown option --%s", a);
+ die(_("unknown option --%s"), a);
}
if (i != global_argc)
usage(fast_import_usage);
@@ -3817,7 +3817,7 @@ int cmd_fast_import(int argc,
else if (starts_with(command_buf.buf, "option "))
/* ignore non-git options*/;
else
- die("Unsupported command: %s", command_buf.buf);
+ die(_("unsupported command: %s"), command_buf.buf);
if (checkpoint_requested)
checkpoint();
@@ -3828,7 +3828,7 @@ int cmd_fast_import(int argc,
parse_argv();
if (require_explicit_termination && feof(stdin))
- die("stream ends early");
+ die(_("stream ends early"));
end_packfile();
diff --git a/builtin/fetch.c b/builtin/fetch.c
index c7ff3480fb..7052e6ff21 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -289,13 +289,11 @@ static struct refname_hash_entry *refname_hash_add(struct hashmap *map,
return ent;
}
-static int add_one_refname(const char *refname, const char *referent UNUSED,
- const struct object_id *oid,
- int flag UNUSED, void *cbdata)
+static int add_one_refname(const struct reference *ref, void *cbdata)
{
struct hashmap *refname_map = cbdata;
- (void) refname_hash_add(refname_map, refname, oid);
+ (void) refname_hash_add(refname_map, ref->name, ref->oid);
return 0;
}
@@ -1416,14 +1414,11 @@ static void set_option(struct transport *transport, const char *name, const char
}
-static int add_oid(const char *refname UNUSED,
- const char *referent UNUSED,
- const struct object_id *oid,
- int flags UNUSED, void *cb_data)
+static int add_oid(const struct reference *ref, void *cb_data)
{
struct oid_array *oids = cb_data;
- oid_array_append(oids, oid);
+ oid_array_append(oids, ref->oid);
return 0;
}
diff --git a/builtin/fsck.c b/builtin/fsck.c
index b1a650c673..c489582faa 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -530,14 +530,13 @@ static int fsck_handle_reflog(const char *logname, void *cb_data)
return 0;
}
-static int fsck_handle_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid,
- int flag UNUSED, void *cb_data UNUSED)
+static int fsck_handle_ref(const struct reference *ref, void *cb_data UNUSED)
{
struct object *obj;
- obj = parse_object(the_repository, oid);
+ obj = parse_object(the_repository, ref->oid);
if (!obj) {
- if (is_promisor_object(the_repository, oid)) {
+ if (is_promisor_object(the_repository, ref->oid)) {
/*
* Increment default_refs anyway, because this is a
* valid ref.
@@ -546,19 +545,19 @@ static int fsck_handle_ref(const char *refname, const char *referent UNUSED, con
return 0;
}
error(_("%s: invalid sha1 pointer %s"),
- refname, oid_to_hex(oid));
+ ref->name, oid_to_hex(ref->oid));
errors_found |= ERROR_REACHABLE;
/* We'll continue with the rest despite the error.. */
return 0;
}
- if (obj->type != OBJ_COMMIT && is_branch(refname)) {
- error(_("%s: not a commit"), refname);
+ if (obj->type != OBJ_COMMIT && is_branch(ref->name)) {
+ error(_("%s: not a commit"), ref->name);
errors_found |= ERROR_REFS;
}
default_refs++;
obj->flags |= USED;
fsck_put_object_name(&fsck_walk_options,
- oid, "%s", refname);
+ ref->oid, "%s", ref->name);
mark_object_reachable(obj);
return 0;
@@ -580,13 +579,19 @@ static void get_default_heads(void)
worktrees = get_worktrees();
for (p = worktrees; *p; p++) {
struct worktree *wt = *p;
- struct strbuf ref = STRBUF_INIT;
+ struct strbuf refname = STRBUF_INIT;
- strbuf_worktree_ref(wt, &ref, "HEAD");
- fsck_head_link(ref.buf, &head_points_at, &head_oid);
- if (head_points_at && !is_null_oid(&head_oid))
- fsck_handle_ref(ref.buf, NULL, &head_oid, 0, NULL);
- strbuf_release(&ref);
+ strbuf_worktree_ref(wt, &refname, "HEAD");
+ fsck_head_link(refname.buf, &head_points_at, &head_oid);
+ if (head_points_at && !is_null_oid(&head_oid)) {
+ struct reference ref = {
+ .name = refname.buf,
+ .oid = &head_oid,
+ };
+
+ fsck_handle_ref(&ref, NULL);
+ }
+ strbuf_release(&refname);
if (include_reflogs)
refs_for_each_reflog(get_worktree_ref_store(wt),
diff --git a/builtin/gc.c b/builtin/gc.c
index d212cbb9b8..aad1496f07 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -1103,24 +1103,21 @@ struct cg_auto_data {
int limit;
};
-static int dfs_on_ref(const char *refname UNUSED,
- const char *referent UNUSED,
- const struct object_id *oid,
- int flags UNUSED,
- void *cb_data)
+static int dfs_on_ref(const struct reference *ref, void *cb_data)
{
struct cg_auto_data *data = (struct cg_auto_data *)cb_data;
int result = 0;
+ const struct object_id *maybe_peeled = ref->oid;
struct object_id peeled;
struct commit_list *stack = NULL;
struct commit *commit;
- if (!peel_iterated_oid(the_repository, oid, &peeled))
- oid = &peeled;
- if (odb_read_object_info(the_repository->objects, oid, NULL) != OBJ_COMMIT)
+ if (!reference_get_peeled_oid(the_repository, ref, &peeled))
+ maybe_peeled = &peeled;
+ if (odb_read_object_info(the_repository->objects, maybe_peeled, NULL) != OBJ_COMMIT)
return 0;
- commit = lookup_commit(the_repository, oid);
+ commit = lookup_commit(the_repository, maybe_peeled);
if (!commit)
return 0;
if (repo_parse_commit(the_repository, commit) ||
diff --git a/builtin/last-modified.c b/builtin/last-modified.c
index ae8b36a2c3..b0ecbdc540 100644
--- a/builtin/last-modified.c
+++ b/builtin/last-modified.c
@@ -2,26 +2,32 @@
#include "bloom.h"
#include "builtin.h"
#include "commit-graph.h"
+#include "commit-slab.h"
#include "commit.h"
#include "config.h"
-#include "environment.h"
#include "diff.h"
#include "diffcore.h"
#include "environment.h"
+#include "ewah/ewok.h"
#include "hashmap.h"
#include "hex.h"
-#include "log-tree.h"
#include "object-name.h"
#include "object.h"
#include "parse-options.h"
+#include "prio-queue.h"
#include "quote.h"
#include "repository.h"
#include "revision.h"
+/* Remember to update object flag allocation in object.h */
+#define PARENT1 (1u<<16) /* used instead of SEEN */
+#define PARENT2 (1u<<17) /* used instead of BOTTOM, BOUNDARY */
+
struct last_modified_entry {
struct hashmap_entry hashent;
struct object_id oid;
struct bloom_key key;
+ size_t diff_idx;
const char path[FLEX_ARRAY];
};
@@ -37,13 +43,45 @@ static int last_modified_entry_hashcmp(const void *unused UNUSED,
return strcmp(ent1->path, path ? path : ent2->path);
}
+/*
+ * Hold a bitmap for each commit we're working with. In the bitmap, each bit
+ * represents a path in `lm->all_paths`. An active bit indicates the path still
+ * needs to be associated to a commit.
+ */
+define_commit_slab(active_paths_for_commit, struct bitmap *);
+
struct last_modified {
struct hashmap paths;
struct rev_info rev;
bool recursive;
bool show_trees;
+
+ const char **all_paths;
+ size_t all_paths_nr;
+ struct active_paths_for_commit active_paths;
+
+ /* 'scratch' to avoid allocating a bitmap every process_parent() */
+ struct bitmap *scratch;
};
+static struct bitmap *active_paths_for(struct last_modified *lm, struct commit *c)
+{
+ struct bitmap **bitmap = active_paths_for_commit_at(&lm->active_paths, c);
+ if (!*bitmap)
+ *bitmap = bitmap_word_alloc(lm->all_paths_nr / BITS_IN_EWORD + 1);
+
+ return *bitmap;
+}
+
+static void active_paths_free(struct last_modified *lm, struct commit *c)
+{
+ struct bitmap **bitmap = active_paths_for_commit_at(&lm->active_paths, c);
+ if (*bitmap) {
+ bitmap_free(*bitmap);
+ *bitmap = NULL;
+ }
+}
+
static void last_modified_release(struct last_modified *lm)
{
struct hashmap_iter iter;
@@ -54,6 +92,8 @@ static void last_modified_release(struct last_modified *lm)
hashmap_clear_and_free(&lm->paths, struct last_modified_entry, hashent);
release_revisions(&lm->rev);
+
+ free(lm->all_paths);
}
struct last_modified_callback_data {
@@ -146,7 +186,7 @@ static void mark_path(const char *path, const struct object_id *oid,
* Is it arriving at a version of interest, or is it from a side branch
* which did not contribute to the final state?
*/
- if (!oideq(oid, &ent->oid))
+ if (oid && !oideq(oid, &ent->oid))
return;
last_modified_emit(data->lm, path, data->commit);
@@ -196,7 +236,17 @@ static void last_modified_diff(struct diff_queue_struct *q,
}
}
-static bool maybe_changed_path(struct last_modified *lm, struct commit *origin)
+static void pass_to_parent(struct bitmap *c,
+ struct bitmap *p,
+ size_t pos)
+{
+ bitmap_unset(c, pos);
+ bitmap_set(p, pos);
+}
+
+static bool maybe_changed_path(struct last_modified *lm,
+ struct commit *origin,
+ struct bitmap *active)
{
struct bloom_filter *filter;
struct last_modified_entry *ent;
@@ -213,6 +263,9 @@ static bool maybe_changed_path(struct last_modified *lm, struct commit *origin)
return true;
hashmap_for_each_entry(&lm->paths, &iter, ent, hashent) {
+ if (active && !bitmap_get(active, ent->diff_idx))
+ continue;
+
if (bloom_filter_contains(filter, &ent->key,
lm->rev.bloom_filter_settings))
return true;
@@ -220,42 +273,202 @@ static bool maybe_changed_path(struct last_modified *lm, struct commit *origin)
return false;
}
+static void process_parent(struct last_modified *lm,
+ struct prio_queue *queue,
+ struct commit *c, struct bitmap *active_c,
+ struct commit *parent, int parent_i)
+{
+ struct bitmap *active_p;
+
+ repo_parse_commit(lm->rev.repo, parent);
+ active_p = active_paths_for(lm, parent);
+
+ /*
+ * The first time entering this function for this commit (i.e. first parent)
+ * see if Bloom filters will tell us it's worth to do the diff.
+ */
+ if (parent_i || maybe_changed_path(lm, c, active_c)) {
+ diff_tree_oid(&parent->object.oid,
+ &c->object.oid, "", &lm->rev.diffopt);
+ diffcore_std(&lm->rev.diffopt);
+ }
+
+ /*
+ * Test each path for TREESAME-ness against the parent. If a path is
+ * TREESAME, pass it on to this parent.
+ *
+ * First, collect all paths that are *not* TREESAME in 'scratch'.
+ * Then, pass paths that *are* TREESAME and active to the parent.
+ */
+ for (int i = 0; i < diff_queued_diff.nr; i++) {
+ struct diff_filepair *fp = diff_queued_diff.queue[i];
+ const char *path = fp->two->path;
+ struct last_modified_entry *ent =
+ hashmap_get_entry_from_hash(&lm->paths, strhash(path), path,
+ struct last_modified_entry, hashent);
+ if (ent) {
+ size_t k = ent->diff_idx;
+ if (bitmap_get(active_c, k))
+ bitmap_set(lm->scratch, k);
+ }
+ }
+ for (size_t i = 0; i < lm->all_paths_nr; i++) {
+ if (bitmap_get(active_c, i) && !bitmap_get(lm->scratch, i))
+ pass_to_parent(active_c, active_p, i);
+ }
+
+ /*
+ * If parent has any active paths, put it on the queue (if not already).
+ */
+ if (!bitmap_is_empty(active_p) && !(parent->object.flags & PARENT1)) {
+ parent->object.flags |= PARENT1;
+ prio_queue_put(queue, parent);
+ }
+ if (!(parent->object.flags & PARENT1))
+ active_paths_free(lm, parent);
+
+ memset(lm->scratch->words, 0x0, lm->scratch->word_alloc);
+ diff_queue_clear(&diff_queued_diff);
+}
+
static int last_modified_run(struct last_modified *lm)
{
+ int max_count, queue_popped = 0;
+ struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
+ struct prio_queue not_queue = { compare_commits_by_gen_then_commit_date };
+ struct commit_list *list;
struct last_modified_callback_data data = { .lm = lm };
lm->rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
lm->rev.diffopt.format_callback = last_modified_diff;
lm->rev.diffopt.format_callback_data = &data;
+ lm->rev.no_walk = 1;
prepare_revision_walk(&lm->rev);
- while (hashmap_get_size(&lm->paths)) {
- data.commit = get_revision(&lm->rev);
- if (!data.commit)
- BUG("paths remaining beyond boundary in last-modified");
+ max_count = lm->rev.max_count;
+
+ init_active_paths_for_commit(&lm->active_paths);
+ lm->scratch = bitmap_word_alloc(lm->all_paths_nr);
+
+ /*
+ * lm->rev.commits holds the set of boundary commits for our walk.
+ *
+ * Loop through each such commit, and place it in the appropriate queue.
+ */
+ for (list = lm->rev.commits; list; list = list->next) {
+ struct commit *c = list->item;
+
+ if (c->object.flags & BOTTOM) {
+ prio_queue_put(&not_queue, c);
+ c->object.flags |= PARENT2;
+ } else if (!(c->object.flags & PARENT1)) {
+ /*
+ * If the commit is a starting point (and hasn't been
+ * seen yet), then initialize the set of interesting
+ * paths, too.
+ */
+ struct bitmap *active;
+
+ prio_queue_put(&queue, c);
+ c->object.flags |= PARENT1;
+
+ active = active_paths_for(lm, c);
+ for (size_t i = 0; i < lm->all_paths_nr; i++)
+ bitmap_set(active, i);
+ }
+ }
- if (data.commit->object.flags & BOUNDARY) {
+ while (queue.nr) {
+ int parent_i;
+ struct commit_list *p;
+ struct commit *c = prio_queue_get(&queue);
+ struct bitmap *active_c = active_paths_for(lm, c);
+
+ if ((0 <= max_count && max_count < ++queue_popped) ||
+ (c->object.flags & PARENT2)) {
+ /*
+ * Either a boundary commit, or we have already seen too
+ * many others. Either way, stop here.
+ */
+ c->object.flags |= PARENT2 | BOUNDARY;
+ data.commit = c;
diff_tree_oid(lm->rev.repo->hash_algo->empty_tree,
- &data.commit->object.oid, "",
- &lm->rev.diffopt);
+ &c->object.oid,
+ "", &lm->rev.diffopt);
diff_flush(&lm->rev.diffopt);
+ goto cleanup;
+ }
- break;
+ /*
+ * Otherwise, make sure that 'c' isn't reachable from anything
+ * in the '--not' queue.
+ */
+ repo_parse_commit(lm->rev.repo, c);
+
+ while (not_queue.nr) {
+ struct commit_list *np;
+ struct commit *n = prio_queue_get(&not_queue);
+
+ repo_parse_commit(lm->rev.repo, n);
+
+ for (np = n->parents; np; np = np->next) {
+ if (!(np->item->object.flags & PARENT2)) {
+ prio_queue_put(&not_queue, np->item);
+ np->item->object.flags |= PARENT2;
+ }
+ }
+
+ if (commit_graph_generation(n) < commit_graph_generation(c))
+ break;
}
- if (!maybe_changed_path(lm, data.commit))
- continue;
+ /*
+ * Look at each parent and pass on each path that's TREESAME
+ * with that parent. Stop early when no active paths remain.
+ */
+ for (p = c->parents, parent_i = 0; p; p = p->next, parent_i++) {
+ process_parent(lm, &queue,
+ c, active_c,
+ p->item, parent_i);
+
+ if (bitmap_is_empty(active_c))
+ break;
+ }
+
+ /*
+ * Paths that remain active, or not TREESAME with any parent,
+ * were changed by 'c'.
+ */
+ if (!bitmap_is_empty(active_c)) {
+ data.commit = c;
+ for (size_t i = 0; i < lm->all_paths_nr; i++) {
+ if (bitmap_get(active_c, i))
+ mark_path(lm->all_paths[i], NULL, &data);
+ }
+ }
- log_tree_commit(&lm->rev, data.commit);
+cleanup:
+ active_paths_free(lm, c);
}
+ if (hashmap_get_size(&lm->paths))
+ BUG("paths remaining beyond boundary in last-modified");
+
+ clear_prio_queue(&not_queue);
+ clear_prio_queue(&queue);
+ clear_active_paths_for_commit(&lm->active_paths);
+ bitmap_free(lm->scratch);
+
return 0;
}
static int last_modified_init(struct last_modified *lm, struct repository *r,
const char *prefix, int argc, const char **argv)
{
+ struct hashmap_iter iter;
+ struct last_modified_entry *ent;
+
hashmap_init(&lm->paths, last_modified_entry_hashcmp, NULL, 0);
repo_init_revisions(r, &lm->rev, prefix);
@@ -280,6 +493,13 @@ static int last_modified_init(struct last_modified *lm, struct repository *r,
if (populate_paths_from_revs(lm) < 0)
return error(_("unable to setup last-modified"));
+ CALLOC_ARRAY(lm->all_paths, hashmap_get_size(&lm->paths));
+ lm->all_paths_nr = 0;
+ hashmap_for_each_entry(&lm->paths, &iter, ent, hashent) {
+ ent->diff_idx = lm->all_paths_nr++;
+ lm->all_paths[ent->diff_idx] = ent->path;
+ }
+
return 0;
}
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index df09000b30..fe77829557 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -156,7 +156,7 @@ int cmd_ls_remote(int argc,
continue;
if (!tail_match(&pattern, ref->name))
continue;
- item = ref_array_push(&ref_array, ref->name, &ref->old_oid);
+ item = ref_array_push(&ref_array, ref->name, &ref->old_oid, NULL);
item->symref = xstrdup_or_null(ref->symref);
}
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 74512e54a3..615f7d1aae 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -339,10 +339,9 @@ static int cmp_by_tag_and_age(const void *a_, const void *b_)
return a->taggerdate != b->taggerdate;
}
-static int name_ref(const char *path, const char *referent UNUSED, const struct object_id *oid,
- int flags UNUSED, void *cb_data)
+static int name_ref(const struct reference *ref, void *cb_data)
{
- struct object *o = parse_object(the_repository, oid);
+ struct object *o = parse_object(the_repository, ref->oid);
struct name_ref_data *data = cb_data;
int can_abbreviate_output = data->tags_only && data->name_only;
int deref = 0;
@@ -350,14 +349,14 @@ static int name_ref(const char *path, const char *referent UNUSED, const struct
struct commit *commit = NULL;
timestamp_t taggerdate = TIME_MAX;
- if (data->tags_only && !starts_with(path, "refs/tags/"))
+ if (data->tags_only && !starts_with(ref->name, "refs/tags/"))
return 0;
if (data->exclude_filters.nr) {
struct string_list_item *item;
for_each_string_list_item(item, &data->exclude_filters) {
- if (subpath_matches(path, item->string) >= 0)
+ if (subpath_matches(ref->name, item->string) >= 0)
return 0;
}
}
@@ -378,7 +377,7 @@ static int name_ref(const char *path, const char *referent UNUSED, const struct
* shouldn't stop when seeing 'refs/tags/v1.4' matches
* 'refs/tags/v*'. We should show it as 'v1.4'.
*/
- switch (subpath_matches(path, item->string)) {
+ switch (subpath_matches(ref->name, item->string)) {
case -1: /* did not match */
break;
case 0: /* matched fully */
@@ -406,13 +405,13 @@ static int name_ref(const char *path, const char *referent UNUSED, const struct
}
if (o && o->type == OBJ_COMMIT) {
commit = (struct commit *)o;
- from_tag = starts_with(path, "refs/tags/");
+ from_tag = starts_with(ref->name, "refs/tags/");
if (taggerdate == TIME_MAX)
taggerdate = commit->date;
}
- add_to_tip_table(oid, path, can_abbreviate_output, commit, taggerdate,
- from_tag, deref);
+ add_to_tip_table(ref->oid, ref->name, can_abbreviate_output,
+ commit, taggerdate, from_tag, deref);
return 0;
}
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index b5454e5df1..4486b55e6d 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -831,15 +831,14 @@ static enum write_one_status write_one(struct hashfile *f,
return WRITE_ONE_WRITTEN;
}
-static int mark_tagged(const char *path UNUSED, const char *referent UNUSED, const struct object_id *oid,
- int flag UNUSED, void *cb_data UNUSED)
+static int mark_tagged(const struct reference *ref, void *cb_data UNUSED)
{
struct object_id peeled;
- struct object_entry *entry = packlist_find(&to_pack, oid);
+ struct object_entry *entry = packlist_find(&to_pack, ref->oid);
if (entry)
entry->tagged = 1;
- if (!peel_iterated_oid(the_repository, oid, &peeled)) {
+ if (!reference_get_peeled_oid(the_repository, ref, &peeled)) {
entry = packlist_find(&to_pack, &peeled);
if (entry)
entry->tagged = 1;
@@ -1706,8 +1705,8 @@ static int want_object_in_pack_mtime(const struct object_id *oid,
uint32_t found_mtime)
{
int want;
+ struct packfile_list_entry *e;
struct odb_source *source;
- struct list_head *pos;
if (!exclude && local) {
/*
@@ -1748,12 +1747,11 @@ static int want_object_in_pack_mtime(const struct object_id *oid,
}
}
- list_for_each(pos, packfile_store_get_packs_mru(the_repository->objects->packfiles)) {
- struct packed_git *p = list_entry(pos, struct packed_git, mru);
+ for (e = the_repository->objects->packfiles->packs.head; e; e = e->next) {
+ struct packed_git *p = e->pack;
want = want_object_in_pack_one(p, oid, exclude, found_pack, found_offset, found_mtime);
if (!exclude && want > 0)
- list_move(&p->mru,
- packfile_store_get_packs_mru(the_repository->objects->packfiles));
+ packfile_list_prepend(&the_repository->objects->packfiles->packs, p);
if (want != -1)
return want;
}
@@ -3306,13 +3304,13 @@ static void add_tag_chain(const struct object_id *oid)
}
}
-static int add_ref_tag(const char *tag UNUSED, const char *referent UNUSED, const struct object_id *oid,
- int flag UNUSED, void *cb_data UNUSED)
+static int add_ref_tag(const struct reference *ref, void *cb_data UNUSED)
{
struct object_id peeled;
- if (!peel_iterated_oid(the_repository, oid, &peeled) && obj_is_packed(&peeled))
- add_tag_chain(oid);
+ if (!reference_get_peeled_oid(the_repository, ref, &peeled) &&
+ obj_is_packed(&peeled))
+ add_tag_chain(ref->oid);
return 0;
}
@@ -4389,27 +4387,27 @@ static void add_unreachable_loose_objects(struct rev_info *revs)
static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)
{
- struct packfile_store *packs = the_repository->objects->packfiles;
- static struct packed_git *last_found = (void *)1;
+ static struct packed_git *last_found = NULL;
struct packed_git *p;
- p = (last_found != (void *)1) ? last_found :
- packfile_store_get_packs(packs);
+ if (last_found && find_pack_entry_one(oid, last_found))
+ return 1;
- while (p) {
- if ((!p->pack_local || p->pack_keep ||
- p->pack_keep_in_core) &&
- find_pack_entry_one(oid, p)) {
+ repo_for_each_pack(the_repository, p) {
+ /*
+ * We have already checked `last_found`, so there is no need to
+ * re-check here.
+ */
+ if (p == last_found)
+ continue;
+
+ if ((!p->pack_local || p->pack_keep || p->pack_keep_in_core) &&
+ find_pack_entry_one(oid, p)) {
last_found = p;
return 1;
}
- if (p == last_found)
- p = packfile_store_get_packs(packs);
- else
- p = p->next;
- if (p == last_found)
- p = p->next;
}
+
return 0;
}
@@ -4528,19 +4526,16 @@ static void record_recent_commit(struct commit *commit, void *data UNUSED)
oid_array_append(&recent_objects, &commit->object.oid);
}
-static int mark_bitmap_preferred_tip(const char *refname,
- const char *referent UNUSED,
- const struct object_id *oid,
- int flags UNUSED,
- void *data UNUSED)
+static int mark_bitmap_preferred_tip(const struct reference *ref, void *data UNUSED)
{
+ const struct object_id *maybe_peeled = ref->oid;
struct object_id peeled;
struct object *object;
- if (!peel_iterated_oid(the_repository, oid, &peeled))
- oid = &peeled;
+ if (!reference_get_peeled_oid(the_repository, ref, &peeled))
+ maybe_peeled = &peeled;
- object = parse_object_or_die(the_repository, oid, refname);
+ object = parse_object_or_die(the_repository, maybe_peeled, ref->name);
if (object->type == OBJ_COMMIT)
object->flags |= NEEDS_BITMAP;
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index c9288a9c7e..e8ee0e7321 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -305,13 +305,12 @@ static void show_ref(const char *path, const struct object_id *oid)
}
}
-static int show_ref_cb(const char *path_full, const char *referent UNUSED, const struct object_id *oid,
- int flag UNUSED, void *data)
+static int show_ref_cb(const struct reference *ref, void *data)
{
struct oidset *seen = data;
- const char *path = strip_namespace(path_full);
+ const char *path = strip_namespace(ref->name);
- if (ref_is_hidden(path, path_full, &hidden_refs))
+ if (ref_is_hidden(path, ref->name, &hidden_refs))
return 0;
/*
@@ -320,13 +319,13 @@ static int show_ref_cb(const char *path_full, const char *referent UNUSED, const
* transfer but will otherwise ignore them.
*/
if (!path) {
- if (oidset_insert(seen, oid))
+ if (oidset_insert(seen, ref->oid))
return 0;
path = ".have";
} else {
- oidset_insert(seen, oid);
+ oidset_insert(seen, ref->oid);
}
- show_ref(path, oid);
+ show_ref(path, ref->oid);
return 0;
}
diff --git a/builtin/remote.c b/builtin/remote.c
index 8a7ed4299a..7ffc14ba15 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -570,17 +570,14 @@ struct branches_for_remote {
struct known_remotes *keep;
};
-static int add_branch_for_removal(const char *refname,
- const char *referent UNUSED,
- const struct object_id *oid UNUSED,
- int flags UNUSED, void *cb_data)
+static int add_branch_for_removal(const struct reference *ref, void *cb_data)
{
struct branches_for_remote *branches = cb_data;
struct refspec_item refspec;
struct known_remote *kr;
memset(&refspec, 0, sizeof(refspec));
- refspec.dst = (char *)refname;
+ refspec.dst = (char *)ref->name;
if (remote_find_tracking(branches->remote, &refspec))
return 0;
free(refspec.src);
@@ -588,7 +585,7 @@ static int add_branch_for_removal(const char *refname,
/* don't delete a branch if another remote also uses it */
for (kr = branches->keep->list; kr; kr = kr->next) {
memset(&refspec, 0, sizeof(refspec));
- refspec.dst = (char *)refname;
+ refspec.dst = (char *)ref->name;
if (!remote_find_tracking(kr->remote, &refspec)) {
free(refspec.src);
return 0;
@@ -596,16 +593,16 @@ static int add_branch_for_removal(const char *refname,
}
/* don't delete non-remote-tracking refs */
- if (!starts_with(refname, "refs/remotes/")) {
+ if (!starts_with(ref->name, "refs/remotes/")) {
/* advise user how to delete local branches */
- if (starts_with(refname, "refs/heads/"))
+ if (starts_with(ref->name, "refs/heads/"))
string_list_append(branches->skipped,
- abbrev_branch(refname));
+ abbrev_branch(ref->name));
/* silently skip over other non-remote refs */
return 0;
}
- string_list_append(branches->branches, refname);
+ string_list_append(branches->branches, ref->name);
return 0;
}
@@ -713,18 +710,18 @@ out:
return error;
}
-static int rename_one_ref(const char *old_refname, const char *referent,
- const struct object_id *oid,
- int flags, void *cb_data)
+static int rename_one_ref(const struct reference *ref, void *cb_data)
{
struct strbuf new_referent = STRBUF_INIT;
struct strbuf new_refname = STRBUF_INIT;
struct rename_info *rename = cb_data;
+ const struct object_id *oid = ref->oid;
+ const char *referent = ref->target;
int error;
- compute_renamed_ref(rename, old_refname, &new_refname);
+ compute_renamed_ref(rename, ref->name, &new_refname);
- if (flags & REF_ISSYMREF) {
+ if (ref->flags & REF_ISSYMREF) {
/*
* Stupidly enough `referent` is not pointing to the immediate
* target of a symref, but it's the recursively resolved value.
@@ -732,25 +729,25 @@ static int rename_one_ref(const char *old_refname, const char *referent,
* unborn symrefs don't have any value for the `referent` at all.
*/
referent = refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
- old_refname, RESOLVE_REF_NO_RECURSE,
+ ref->name, RESOLVE_REF_NO_RECURSE,
NULL, NULL);
compute_renamed_ref(rename, referent, &new_referent);
oid = NULL;
}
- error = ref_transaction_delete(rename->transaction, old_refname,
+ error = ref_transaction_delete(rename->transaction, ref->name,
oid, referent, REF_NO_DEREF, NULL, rename->err);
if (error < 0)
goto out;
error = ref_transaction_update(rename->transaction, new_refname.buf, oid, null_oid(the_hash_algo),
- (flags & REF_ISSYMREF) ? new_referent.buf : NULL, NULL,
+ (ref->flags & REF_ISSYMREF) ? new_referent.buf : NULL, NULL,
REF_SKIP_CREATE_REFLOG | REF_NO_DEREF | REF_SKIP_OID_VERIFICATION,
NULL, rename->err);
if (error < 0)
goto out;
- error = rename_one_reflog(old_refname, oid, rename);
+ error = rename_one_reflog(ref->name, oid, rename);
if (error < 0)
goto out;
@@ -1125,19 +1122,16 @@ static void free_remote_ref_states(struct ref_states *states)
string_list_clear_func(&states->push, clear_push_info);
}
-static int append_ref_to_tracked_list(const char *refname,
- const char *referent UNUSED,
- const struct object_id *oid UNUSED,
- int flags, void *cb_data)
+static int append_ref_to_tracked_list(const struct reference *ref, void *cb_data)
{
struct ref_states *states = cb_data;
struct refspec_item refspec;
- if (flags & REF_ISSYMREF)
+ if (ref->flags & REF_ISSYMREF)
return 0;
memset(&refspec, 0, sizeof(refspec));
- refspec.dst = (char *)refname;
+ refspec.dst = (char *)ref->name;
if (!remote_find_tracking(states->remote, &refspec)) {
string_list_append(&states->tracked, abbrev_branch(refspec.src));
free(refspec.src);
diff --git a/builtin/replace.c b/builtin/replace.c
index 900b560a77..4c62c5ab58 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -47,30 +47,27 @@ struct show_data {
enum replace_format format;
};
-static int show_reference(const char *refname,
- const char *referent UNUSED,
- const struct object_id *oid,
- int flag UNUSED, void *cb_data)
+static int show_reference(const struct reference *ref, void *cb_data)
{
struct show_data *data = cb_data;
- if (!wildmatch(data->pattern, refname, 0)) {
+ if (!wildmatch(data->pattern, ref->name, 0)) {
if (data->format == REPLACE_FORMAT_SHORT)
- printf("%s\n", refname);
+ printf("%s\n", ref->name);
else if (data->format == REPLACE_FORMAT_MEDIUM)
- printf("%s -> %s\n", refname, oid_to_hex(oid));
+ printf("%s -> %s\n", ref->name, oid_to_hex(ref->oid));
else { /* data->format == REPLACE_FORMAT_LONG */
struct object_id object;
enum object_type obj_type, repl_type;
- if (repo_get_oid(data->repo, refname, &object))
- return error(_("failed to resolve '%s' as a valid ref"), refname);
+ if (repo_get_oid(data->repo, ref->name, &object))
+ return error(_("failed to resolve '%s' as a valid ref"), ref->name);
obj_type = odb_read_object_info(data->repo->objects, &object, NULL);
- repl_type = odb_read_object_info(data->repo->objects, oid, NULL);
+ repl_type = odb_read_object_info(data->repo->objects, ref->oid, NULL);
- printf("%s (%s) -> %s (%s)\n", refname, type_name(obj_type),
- oid_to_hex(oid), type_name(repl_type));
+ printf("%s (%s) -> %s (%s)\n", ref->name, type_name(obj_type),
+ oid_to_hex(ref->oid), type_name(repl_type));
}
}
diff --git a/builtin/repo.c b/builtin/repo.c
index bbb0966f2d..f26640bd6e 100644
--- a/builtin/repo.c
+++ b/builtin/repo.c
@@ -3,19 +3,27 @@
#include "builtin.h"
#include "environment.h"
#include "parse-options.h"
+#include "path-walk.h"
+#include "progress.h"
#include "quote.h"
+#include "ref-filter.h"
#include "refs.h"
+#include "revision.h"
#include "strbuf.h"
+#include "string-list.h"
#include "shallow.h"
+#include "utf8.h"
static const char *const repo_usage[] = {
"git repo info [--format=(keyvalue|nul)] [-z] [<key>...]",
+ "git repo structure [--format=(table|keyvalue|nul)]",
NULL
};
typedef int get_value_fn(struct repository *repo, struct strbuf *buf);
enum output_format {
+ FORMAT_TABLE,
FORMAT_KEYVALUE,
FORMAT_NUL_TERMINATED,
};
@@ -130,14 +138,16 @@ static int parse_format_cb(const struct option *opt,
*format = FORMAT_NUL_TERMINATED;
else if (!strcmp(arg, "keyvalue"))
*format = FORMAT_KEYVALUE;
+ else if (!strcmp(arg, "table"))
+ *format = FORMAT_TABLE;
else
die(_("invalid format '%s'"), arg);
return 0;
}
-static int repo_info(int argc, const char **argv, const char *prefix,
- struct repository *repo)
+static int cmd_repo_info(int argc, const char **argv, const char *prefix,
+ struct repository *repo)
{
enum output_format format = FORMAT_KEYVALUE;
struct option options[] = {
@@ -152,16 +162,377 @@ static int repo_info(int argc, const char **argv, const char *prefix,
};
argc = parse_options(argc, argv, prefix, options, repo_usage, 0);
+ if (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED)
+ die(_("unsupported output format"));
return print_fields(argc, argv, repo, format);
}
+struct ref_stats {
+ size_t branches;
+ size_t remotes;
+ size_t tags;
+ size_t others;
+};
+
+struct object_stats {
+ size_t tags;
+ size_t commits;
+ size_t trees;
+ size_t blobs;
+};
+
+struct repo_structure {
+ struct ref_stats refs;
+ struct object_stats objects;
+};
+
+struct stats_table {
+ struct string_list rows;
+
+ int name_col_width;
+ int value_col_width;
+};
+
+/*
+ * Holds column data that gets stored for each row.
+ */
+struct stats_table_entry {
+ char *value;
+};
+
+static void stats_table_vaddf(struct stats_table *table,
+ struct stats_table_entry *entry,
+ const char *format, va_list ap)
+{
+ struct strbuf buf = STRBUF_INIT;
+ struct string_list_item *item;
+ char *formatted_name;
+ int name_width;
+
+ strbuf_vaddf(&buf, format, ap);
+ formatted_name = strbuf_detach(&buf, NULL);
+ name_width = utf8_strwidth(formatted_name);
+
+ item = string_list_append_nodup(&table->rows, formatted_name);
+ item->util = entry;
+
+ if (name_width > table->name_col_width)
+ table->name_col_width = name_width;
+ if (entry) {
+ int value_width = utf8_strwidth(entry->value);
+ if (value_width > table->value_col_width)
+ table->value_col_width = value_width;
+ }
+}
+
+static void stats_table_addf(struct stats_table *table, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ stats_table_vaddf(table, NULL, format, ap);
+ va_end(ap);
+}
+
+static void stats_table_count_addf(struct stats_table *table, size_t value,
+ const char *format, ...)
+{
+ struct stats_table_entry *entry;
+ va_list ap;
+
+ CALLOC_ARRAY(entry, 1);
+ entry->value = xstrfmt("%" PRIuMAX, (uintmax_t)value);
+
+ va_start(ap, format);
+ stats_table_vaddf(table, entry, format, ap);
+ va_end(ap);
+}
+
+static inline size_t get_total_reference_count(struct ref_stats *stats)
+{
+ return stats->branches + stats->remotes + stats->tags + stats->others;
+}
+
+static inline size_t get_total_object_count(struct object_stats *stats)
+{
+ return stats->tags + stats->commits + stats->trees + stats->blobs;
+}
+
+static void stats_table_setup_structure(struct stats_table *table,
+ struct repo_structure *stats)
+{
+ struct object_stats *objects = &stats->objects;
+ struct ref_stats *refs = &stats->refs;
+ size_t object_total;
+ size_t ref_total;
+
+ ref_total = get_total_reference_count(refs);
+ stats_table_addf(table, "* %s", _("References"));
+ stats_table_count_addf(table, ref_total, " * %s", _("Count"));
+ stats_table_count_addf(table, refs->branches, " * %s", _("Branches"));
+ stats_table_count_addf(table, refs->tags, " * %s", _("Tags"));
+ stats_table_count_addf(table, refs->remotes, " * %s", _("Remotes"));
+ stats_table_count_addf(table, refs->others, " * %s", _("Others"));
+
+ object_total = get_total_object_count(objects);
+ stats_table_addf(table, "");
+ stats_table_addf(table, "* %s", _("Reachable objects"));
+ stats_table_count_addf(table, object_total, " * %s", _("Count"));
+ stats_table_count_addf(table, objects->commits, " * %s", _("Commits"));
+ stats_table_count_addf(table, objects->trees, " * %s", _("Trees"));
+ stats_table_count_addf(table, objects->blobs, " * %s", _("Blobs"));
+ stats_table_count_addf(table, objects->tags, " * %s", _("Tags"));
+}
+
+static void stats_table_print_structure(const struct stats_table *table)
+{
+ const char *name_col_title = _("Repository structure");
+ const char *value_col_title = _("Value");
+ int name_col_width = utf8_strwidth(name_col_title);
+ int value_col_width = utf8_strwidth(value_col_title);
+ struct string_list_item *item;
+
+ if (table->name_col_width > name_col_width)
+ name_col_width = table->name_col_width;
+ if (table->value_col_width > value_col_width)
+ value_col_width = table->value_col_width;
+
+ printf("| %-*s | %-*s |\n", name_col_width, name_col_title,
+ value_col_width, value_col_title);
+ printf("| ");
+ for (int i = 0; i < name_col_width; i++)
+ putchar('-');
+ printf(" | ");
+ for (int i = 0; i < value_col_width; i++)
+ putchar('-');
+ printf(" |\n");
+
+ for_each_string_list_item(item, &table->rows) {
+ struct stats_table_entry *entry = item->util;
+ const char *value = "";
+
+ if (entry) {
+ struct stats_table_entry *entry = item->util;
+ value = entry->value;
+ }
+
+ printf("| %-*s | %*s |\n", name_col_width, item->string,
+ value_col_width, value);
+ }
+}
+
+static void stats_table_clear(struct stats_table *table)
+{
+ struct stats_table_entry *entry;
+ struct string_list_item *item;
+
+ for_each_string_list_item(item, &table->rows) {
+ entry = item->util;
+ if (entry)
+ free(entry->value);
+ }
+
+ string_list_clear(&table->rows, 1);
+}
+
+static void structure_keyvalue_print(struct repo_structure *stats,
+ char key_delim, char value_delim)
+{
+ printf("references.branches.count%c%" PRIuMAX "%c", key_delim,
+ (uintmax_t)stats->refs.branches, value_delim);
+ printf("references.tags.count%c%" PRIuMAX "%c", key_delim,
+ (uintmax_t)stats->refs.tags, value_delim);
+ printf("references.remotes.count%c%" PRIuMAX "%c", key_delim,
+ (uintmax_t)stats->refs.remotes, value_delim);
+ printf("references.others.count%c%" PRIuMAX "%c", key_delim,
+ (uintmax_t)stats->refs.others, value_delim);
+
+ printf("objects.commits.count%c%" PRIuMAX "%c", key_delim,
+ (uintmax_t)stats->objects.commits, value_delim);
+ printf("objects.trees.count%c%" PRIuMAX "%c", key_delim,
+ (uintmax_t)stats->objects.trees, value_delim);
+ printf("objects.blobs.count%c%" PRIuMAX "%c", key_delim,
+ (uintmax_t)stats->objects.blobs, value_delim);
+ printf("objects.tags.count%c%" PRIuMAX "%c", key_delim,
+ (uintmax_t)stats->objects.tags, value_delim);
+
+ fflush(stdout);
+}
+
+struct count_references_data {
+ struct ref_stats *stats;
+ struct rev_info *revs;
+ struct progress *progress;
+};
+
+static int count_references(const struct reference *ref, void *cb_data)
+{
+ struct count_references_data *data = cb_data;
+ struct ref_stats *stats = data->stats;
+ size_t ref_count;
+
+ switch (ref_kind_from_refname(ref->name)) {
+ case FILTER_REFS_BRANCHES:
+ stats->branches++;
+ break;
+ case FILTER_REFS_REMOTES:
+ stats->remotes++;
+ break;
+ case FILTER_REFS_TAGS:
+ stats->tags++;
+ break;
+ case FILTER_REFS_OTHERS:
+ stats->others++;
+ break;
+ default:
+ BUG("unexpected reference type");
+ }
+
+ /*
+ * While iterating through references for counting, also add OIDs in
+ * preparation for the path walk.
+ */
+ add_pending_oid(data->revs, NULL, ref->oid, 0);
+
+ ref_count = get_total_reference_count(stats);
+ display_progress(data->progress, ref_count);
+
+ return 0;
+}
+
+static void structure_count_references(struct ref_stats *stats,
+ struct rev_info *revs,
+ struct repository *repo,
+ int show_progress)
+{
+ struct count_references_data data = {
+ .stats = stats,
+ .revs = revs,
+ };
+
+ if (show_progress)
+ data.progress = start_delayed_progress(repo,
+ _("Counting references"), 0);
+
+ refs_for_each_ref(get_main_ref_store(repo), count_references, &data);
+ stop_progress(&data.progress);
+}
+
+struct count_objects_data {
+ struct object_stats *stats;
+ struct progress *progress;
+};
+
+static int count_objects(const char *path UNUSED, struct oid_array *oids,
+ enum object_type type, void *cb_data)
+{
+ struct count_objects_data *data = cb_data;
+ struct object_stats *stats = data->stats;
+ size_t object_count;
+
+ switch (type) {
+ case OBJ_TAG:
+ stats->tags += oids->nr;
+ break;
+ case OBJ_COMMIT:
+ stats->commits += oids->nr;
+ break;
+ case OBJ_TREE:
+ stats->trees += oids->nr;
+ break;
+ case OBJ_BLOB:
+ stats->blobs += oids->nr;
+ break;
+ default:
+ BUG("invalid object type");
+ }
+
+ object_count = get_total_object_count(stats);
+ display_progress(data->progress, object_count);
+
+ return 0;
+}
+
+static void structure_count_objects(struct object_stats *stats,
+ struct rev_info *revs,
+ struct repository *repo, int show_progress)
+{
+ struct path_walk_info info = PATH_WALK_INFO_INIT;
+ struct count_objects_data data = {
+ .stats = stats,
+ };
+
+ info.revs = revs;
+ info.path_fn = count_objects;
+ info.path_fn_data = &data;
+
+ if (show_progress)
+ data.progress = start_delayed_progress(repo, _("Counting objects"), 0);
+
+ walk_objects_by_path(&info);
+ path_walk_info_clear(&info);
+ stop_progress(&data.progress);
+}
+
+static int cmd_repo_structure(int argc, const char **argv, const char *prefix,
+ struct repository *repo)
+{
+ struct stats_table table = {
+ .rows = STRING_LIST_INIT_DUP,
+ };
+ enum output_format format = FORMAT_TABLE;
+ struct repo_structure stats = { 0 };
+ struct rev_info revs;
+ int show_progress = -1;
+ struct option options[] = {
+ OPT_CALLBACK_F(0, "format", &format, N_("format"),
+ N_("output format"),
+ PARSE_OPT_NONEG, parse_format_cb),
+ OPT_BOOL(0, "progress", &show_progress, N_("show progress")),
+ OPT_END()
+ };
+
+ argc = parse_options(argc, argv, prefix, options, repo_usage, 0);
+ if (argc)
+ usage(_("too many arguments"));
+
+ repo_init_revisions(repo, &revs, prefix);
+
+ if (show_progress < 0)
+ show_progress = isatty(2);
+
+ structure_count_references(&stats.refs, &revs, repo, show_progress);
+ structure_count_objects(&stats.objects, &revs, repo, show_progress);
+
+ switch (format) {
+ case FORMAT_TABLE:
+ stats_table_setup_structure(&table, &stats);
+ stats_table_print_structure(&table);
+ break;
+ case FORMAT_KEYVALUE:
+ structure_keyvalue_print(&stats, '=', '\n');
+ break;
+ case FORMAT_NUL_TERMINATED:
+ structure_keyvalue_print(&stats, '\n', '\0');
+ break;
+ default:
+ BUG("invalid output format");
+ }
+
+ stats_table_clear(&table);
+ release_revisions(&revs);
+
+ return 0;
+}
+
int cmd_repo(int argc, const char **argv, const char *prefix,
struct repository *repo)
{
parse_opt_subcommand_fn *fn = NULL;
struct option options[] = {
- OPT_SUBCOMMAND("info", &fn, repo_info),
+ OPT_SUBCOMMAND("info", &fn, cmd_repo_info),
+ OPT_SUBCOMMAND("structure", &fn, cmd_repo_structure),
OPT_END()
};
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 7b3711cf34..9032cc6327 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -217,19 +217,17 @@ static int show_default(void)
return 0;
}
-static int show_reference(const char *refname, const char *referent UNUSED, const struct object_id *oid,
- int flag UNUSED, void *cb_data UNUSED)
+static int show_reference(const struct reference *ref, void *cb_data UNUSED)
{
- if (ref_excluded(&ref_excludes, refname))
+ if (ref_excluded(&ref_excludes, ref->name))
return 0;
- show_rev(NORMAL, oid, refname);
+ show_rev(NORMAL, ref->oid, ref->name);
return 0;
}
-static int anti_reference(const char *refname, const char *referent UNUSED, const struct object_id *oid,
- int flag UNUSED, void *cb_data UNUSED)
+static int anti_reference(const struct reference *ref, void *cb_data UNUSED)
{
- show_rev(REVERSED, oid, refname);
+ show_rev(REVERSED, ref->oid, ref->name);
return 0;
}
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index 441babf2e3..10475a6b5e 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -413,34 +413,32 @@ static int append_ref(const char *refname, const struct object_id *oid,
return 0;
}
-static int append_head_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid,
- int flag UNUSED, void *cb_data UNUSED)
+static int append_head_ref(const struct reference *ref, void *cb_data UNUSED)
{
struct object_id tmp;
int ofs = 11;
- if (!starts_with(refname, "refs/heads/"))
+ if (!starts_with(ref->name, "refs/heads/"))
return 0;
/* If both heads/foo and tags/foo exists, get_sha1 would
* get confused.
*/
- if (repo_get_oid(the_repository, refname + ofs, &tmp) || !oideq(&tmp, oid))
+ if (repo_get_oid(the_repository, ref->name + ofs, &tmp) || !oideq(&tmp, ref->oid))
ofs = 5;
- return append_ref(refname + ofs, oid, 0);
+ return append_ref(ref->name + ofs, ref->oid, 0);
}
-static int append_remote_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid,
- int flag UNUSED, void *cb_data UNUSED)
+static int append_remote_ref(const struct reference *ref, void *cb_data UNUSED)
{
struct object_id tmp;
int ofs = 13;
- if (!starts_with(refname, "refs/remotes/"))
+ if (!starts_with(ref->name, "refs/remotes/"))
return 0;
/* If both heads/foo and tags/foo exists, get_sha1 would
* get confused.
*/
- if (repo_get_oid(the_repository, refname + ofs, &tmp) || !oideq(&tmp, oid))
+ if (repo_get_oid(the_repository, ref->name + ofs, &tmp) || !oideq(&tmp, ref->oid))
ofs = 5;
- return append_ref(refname + ofs, oid, 0);
+ return append_ref(ref->name + ofs, ref->oid, 0);
}
static int append_tag_ref(const char *refname, const struct object_id *oid,
@@ -454,27 +452,26 @@ static int append_tag_ref(const char *refname, const struct object_id *oid,
static const char *match_ref_pattern = NULL;
static int match_ref_slash = 0;
-static int append_matching_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid,
- int flag, void *cb_data)
+static int append_matching_ref(const struct reference *ref, void *cb_data)
{
/* we want to allow pattern hold/<asterisk> to show all
* branches under refs/heads/hold/, and v0.99.9? to show
* refs/tags/v0.99.9a and friends.
*/
const char *tail;
- int slash = count_slashes(refname);
- for (tail = refname; *tail && match_ref_slash < slash; )
+ int slash = count_slashes(ref->name);
+ for (tail = ref->name; *tail && match_ref_slash < slash; )
if (*tail++ == '/')
slash--;
if (!*tail)
return 0;
if (wildmatch(match_ref_pattern, tail, 0))
return 0;
- if (starts_with(refname, "refs/heads/"))
- return append_head_ref(refname, NULL, oid, flag, cb_data);
- if (starts_with(refname, "refs/tags/"))
- return append_tag_ref(refname, oid, flag, cb_data);
- return append_ref(refname, oid, 0);
+ if (starts_with(ref->name, "refs/heads/"))
+ return append_head_ref(ref, cb_data);
+ if (starts_with(ref->name, "refs/tags/"))
+ return append_tag_ref(ref->name, ref->oid, ref->flags, cb_data);
+ return append_ref(ref->name, ref->oid, 0);
}
static void snarf_refs(int head, int remotes)
diff --git a/builtin/show-ref.c b/builtin/show-ref.c
index 0b6f9edf86..4d4984e4e0 100644
--- a/builtin/show-ref.c
+++ b/builtin/show-ref.c
@@ -31,31 +31,31 @@ struct show_one_options {
};
static void show_one(const struct show_one_options *opts,
- const char *refname, const struct object_id *oid)
+ const struct reference *ref)
{
const char *hex;
struct object_id peeled;
- if (!odb_has_object(the_repository->objects, oid,
+ if (!odb_has_object(the_repository->objects, ref->oid,
HAS_OBJECT_RECHECK_PACKED | HAS_OBJECT_FETCH_PROMISOR))
- die("git show-ref: bad ref %s (%s)", refname,
- oid_to_hex(oid));
+ die("git show-ref: bad ref %s (%s)", ref->name,
+ oid_to_hex(ref->oid));
if (opts->quiet)
return;
- hex = repo_find_unique_abbrev(the_repository, oid, opts->abbrev);
+ hex = repo_find_unique_abbrev(the_repository, ref->oid, opts->abbrev);
if (opts->hash_only)
printf("%s\n", hex);
else
- printf("%s %s\n", hex, refname);
+ printf("%s %s\n", hex, ref->name);
if (!opts->deref_tags)
return;
- if (!peel_iterated_oid(the_repository, oid, &peeled)) {
+ if (!reference_get_peeled_oid(the_repository, ref, &peeled)) {
hex = repo_find_unique_abbrev(the_repository, &peeled, opts->abbrev);
- printf("%s %s^{}\n", hex, refname);
+ printf("%s %s^{}\n", hex, ref->name);
}
}
@@ -66,26 +66,25 @@ struct show_ref_data {
int show_head;
};
-static int show_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid,
- int flag UNUSED, void *cbdata)
+static int show_ref(const struct reference *ref, void *cbdata)
{
struct show_ref_data *data = cbdata;
- if (data->show_head && !strcmp(refname, "HEAD"))
+ if (data->show_head && !strcmp(ref->name, "HEAD"))
goto match;
if (data->patterns) {
- int reflen = strlen(refname);
+ int reflen = strlen(ref->name);
const char **p = data->patterns, *m;
while ((m = *p++) != NULL) {
int len = strlen(m);
if (len > reflen)
continue;
- if (memcmp(m, refname + reflen - len, len))
+ if (memcmp(m, ref->name + reflen - len, len))
continue;
if (len == reflen)
goto match;
- if (refname[reflen - len - 1] == '/')
+ if (ref->name[reflen - len - 1] == '/')
goto match;
}
return 0;
@@ -94,18 +93,15 @@ static int show_ref(const char *refname, const char *referent UNUSED, const stru
match:
data->found_match++;
- show_one(data->show_one_opts, refname, oid);
+ show_one(data->show_one_opts, ref);
return 0;
}
-static int add_existing(const char *refname,
- const char *referent UNUSED,
- const struct object_id *oid UNUSED,
- int flag UNUSED, void *cbdata)
+static int add_existing(const struct reference *ref, void *cbdata)
{
struct string_list *list = (struct string_list *)cbdata;
- string_list_insert(list, refname);
+ string_list_insert(list, ref->name);
return 0;
}
@@ -179,12 +175,18 @@ static int cmd_show_ref__verify(const struct show_one_options *show_one_opts,
if ((starts_with(*refs, "refs/") || refname_is_safe(*refs)) &&
!refs_read_ref(get_main_ref_store(the_repository), *refs, &oid)) {
- show_one(show_one_opts, *refs, &oid);
- }
- else if (!show_one_opts->quiet)
+ struct reference ref = {
+ .name = *refs,
+ .oid = &oid,
+ };
+
+ show_one(show_one_opts, &ref);
+ } else if (!show_one_opts->quiet) {
die("'%s' - not a valid ref", *refs);
- else
+ } else {
return 1;
+ }
+
refs++;
}
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index fcd73abe53..35f6cf735e 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -593,16 +593,12 @@ static void print_status(unsigned int flags, char state, const char *path,
printf("\n");
}
-static int handle_submodule_head_ref(const char *refname UNUSED,
- const char *referent UNUSED,
- const struct object_id *oid,
- int flags UNUSED,
- void *cb_data)
+static int handle_submodule_head_ref(const struct reference *ref, void *cb_data)
{
struct object_id *output = cb_data;
- if (oid)
- oidcpy(output, oid);
+ if (ref->oid)
+ oidcpy(output, ref->oid);
return 0;
}
diff --git a/builtin/tag.c b/builtin/tag.c
index f0665af3ac..01eba90c5c 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -153,7 +153,7 @@ static int verify_tag(const char *name, const char *ref UNUSED,
return -1;
if (format->format)
- pretty_print_ref(name, oid, format);
+ pretty_print_ref(name, oid, NULL, format);
return 0;
}
diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c
index cd6bc11095..558121eaa1 100644
--- a/builtin/verify-tag.c
+++ b/builtin/verify-tag.c
@@ -67,7 +67,7 @@ int cmd_verify_tag(int argc,
}
if (format.format)
- pretty_print_ref(name, &oid, &format);
+ pretty_print_ref(name, &oid, NULL, &format);
}
return had_error;
}
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 812774a5ca..b7f323b5e4 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -635,11 +635,7 @@ static void print_preparing_worktree_line(int detach,
*
* Returns 0 on failure and non-zero on success.
*/
-static int first_valid_ref(const char *refname UNUSED,
- const char *referent UNUSED,
- const struct object_id *oid UNUSED,
- int flags UNUSED,
- void *cb_data UNUSED)
+static int first_valid_ref(const struct reference *ref UNUSED, void *cb_data UNUSED)
{
return 1;
}