summaryrefslogtreecommitdiff
path: root/bundle.c
diff options
context:
space:
mode:
Diffstat (limited to 'bundle.c')
-rw-r--r--bundle.c114
1 files changed, 54 insertions, 60 deletions
diff --git a/bundle.c b/bundle.c
index 0208e6d..a9744da 100644
--- a/bundle.c
+++ b/bundle.c
@@ -1,7 +1,10 @@
-#include "cache.h"
+#include "git-compat-util.h"
#include "lockfile.h"
#include "bundle.h"
-#include "object-store.h"
+#include "environment.h"
+#include "gettext.h"
+#include "hex.h"
+#include "object-store-ll.h"
#include "repository.h"
#include "object.h"
#include "commit.h"
@@ -12,6 +15,8 @@
#include "refs.h"
#include "strvec.h"
#include "list-objects-filter-options.h"
+#include "connected.h"
+#include "write-or-die.h"
static const char v2_bundle_signature[] = "# v2 git bundle\n";
static const char v3_bundle_signature[] = "# v3 git bundle\n";
@@ -187,79 +192,65 @@ static int list_refs(struct string_list *r, int argc, const char **argv)
/* Remember to update object flag allocation in object.h */
#define PREREQ_MARK (1u<<16)
+struct string_list_iterator {
+ struct string_list *list;
+ size_t cur;
+};
+
+static const struct object_id *iterate_ref_map(void *cb_data)
+{
+ struct string_list_iterator *iter = cb_data;
+
+ if (iter->cur >= iter->list->nr)
+ return NULL;
+
+ return iter->list->items[iter->cur++].util;
+}
+
int verify_bundle(struct repository *r,
struct bundle_header *header,
- int verbose)
+ enum verify_bundle_flags flags)
{
/*
* Do fast check, then if any prereqs are missing then go line by line
* to be verbose about the errors
*/
struct string_list *p = &header->prerequisites;
- struct rev_info revs = REV_INFO_INIT;
- const char *argv[] = {NULL, "--all", NULL};
- struct commit *commit;
- int i, ret = 0, req_nr;
+ int i, ret = 0;
const char *message = _("Repository lacks these prerequisite commits:");
+ struct string_list_iterator iter = {
+ .list = p,
+ };
+ struct check_connected_options opts = {
+ .quiet = 1,
+ };
- if (!r || !r->objects || !r->objects->odb) {
- ret = error(_("need a repository to verify a bundle"));
- goto cleanup;
- }
+ if (!r || !r->objects || !r->objects->odb)
+ return error(_("need a repository to verify a bundle"));
- repo_init_revisions(r, &revs, NULL);
for (i = 0; i < p->nr; i++) {
struct string_list_item *e = p->items + i;
const char *name = e->string;
struct object_id *oid = e->util;
struct object *o = parse_object(r, oid);
- if (o) {
- o->flags |= PREREQ_MARK;
- add_pending_object(&revs, o, name);
+ if (o)
continue;
- }
- if (++ret == 1)
- error("%s", message);
- error("%s %s", oid_to_hex(oid), name);
- }
- if (revs.pending.nr != p->nr)
- goto cleanup;
- req_nr = revs.pending.nr;
- setup_revisions(2, argv, &revs, NULL);
-
- list_objects_filter_copy(&revs.filter, &header->filter);
-
- if (prepare_revision_walk(&revs))
- die(_("revision walk setup failed"));
-
- i = req_nr;
- while (i && (commit = get_revision(&revs)))
- if (commit->object.flags & PREREQ_MARK)
- i--;
-
- for (i = 0; i < p->nr; i++) {
- struct string_list_item *e = p->items + i;
- const char *name = e->string;
- const struct object_id *oid = e->util;
- struct object *o = parse_object(r, oid);
- assert(o); /* otherwise we'd have returned early */
- if (o->flags & SHOWN)
+ ret++;
+ if (flags & VERIFY_BUNDLE_QUIET)
continue;
- if (++ret == 1)
+ if (ret == 1)
error("%s", message);
error("%s %s", oid_to_hex(oid), name);
}
+ if (ret)
+ goto cleanup;
- /* Clean up objects used, as they will be reused. */
- for (i = 0; i < p->nr; i++) {
- struct string_list_item *e = p->items + i;
- struct object_id *oid = e->util;
- commit = lookup_commit_reference_gently(r, oid, 1);
- if (commit)
- clear_commit_marks(commit, ALL_REV_FLAGS);
- }
+ if ((ret = check_connected(iterate_ref_map, &iter, &opts)))
+ error(_("some prerequisite commits exist in the object store, "
+ "but are not connected to the repository's history"));
- if (verbose) {
+ /* TODO: preserve this verbose language. */
+ if (flags & VERIFY_BUNDLE_VERBOSE) {
struct string_list *r;
r = &header->references;
@@ -280,14 +271,13 @@ int verify_bundle(struct repository *r,
list_refs(r, 0, NULL);
}
- printf_ln("The bundle uses this hash algorithm: %s",
+ printf_ln(_("The bundle uses this hash algorithm: %s"),
header->hash_algo->name);
if (header->filter.choice)
- printf_ln("The bundle uses this filter: %s",
+ printf_ln(_("The bundle uses this filter: %s"),
list_objects_filter_spec(&header->filter));
}
cleanup:
- release_revisions(&revs);
return ret;
}
@@ -307,7 +297,7 @@ static int is_tag_in_date_range(struct object *tag, struct rev_info *revs)
if (revs->max_age == -1 && revs->min_age == -1)
goto out;
- buf = read_object_file(&tag->oid, &type, &size);
+ buf = repo_read_object_file(the_repository, &tag->oid, &type, &size);
if (!buf)
goto out;
line = memmem(buf, size, "\ntagger ", 8);
@@ -396,7 +386,8 @@ static int write_bundle_refs(int bundle_fd, struct rev_info *revs)
if (e->item->flags & UNINTERESTING)
continue;
- if (dwim_ref(e->name, strlen(e->name), &oid, &ref, 0) != 1)
+ if (repo_dwim_ref(the_repository, e->name, strlen(e->name),
+ &oid, &ref, 0) != 1)
goto skip_write_ref;
if (read_ref_full(e->name, RESOLVE_REF_READING, &oid, &flag))
flag = 0;
@@ -620,9 +611,14 @@ err:
}
int unbundle(struct repository *r, struct bundle_header *header,
- int bundle_fd, struct strvec *extra_index_pack_args)
+ int bundle_fd, struct strvec *extra_index_pack_args,
+ enum verify_bundle_flags flags)
{
struct child_process ip = CHILD_PROCESS_INIT;
+
+ if (verify_bundle(r, header, flags))
+ return -1;
+
strvec_pushl(&ip.args, "index-pack", "--fix-thin", "--stdin", NULL);
/* If there is a filter, then we need to create the promisor pack. */
@@ -634,8 +630,6 @@ int unbundle(struct repository *r, struct bundle_header *header,
strvec_clear(extra_index_pack_args);
}
- if (verify_bundle(r, header, 0))
- return -1;
ip.in = bundle_fd;
ip.no_stdout = 1;
ip.git_cmd = 1;