Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'bundle.c')
-rw-r--r--bundle.c112
1 files changed, 55 insertions, 57 deletions
diff --git a/bundle.c b/bundle.c
index be7c0dd77b..a9744da255 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";
@@ -66,8 +71,8 @@ static int parse_bundle_signature(struct bundle_header *header, const char *line
return -1;
}
-static int parse_bundle_header(int fd, struct bundle_header *header,
- const char *report_path)
+int read_bundle_header_fd(int fd, struct bundle_header *header,
+ const char *report_path)
{
struct strbuf buf = STRBUF_INIT;
int status = 0;
@@ -143,7 +148,7 @@ int read_bundle_header(const char *path, struct bundle_header *header)
if (fd < 0)
return error(_("could not open '%s'"), path);
- return parse_bundle_header(fd, header, path);
+ return read_bundle_header_fd(fd, header, path);
}
int is_bundle(const char *path, int quiet)
@@ -153,7 +158,7 @@ int is_bundle(const char *path, int quiet)
if (fd < 0)
return 0;
- fd = parse_bundle_header(fd, &header, quiet ? NULL : path);
+ fd = read_bundle_header_fd(fd, &header, quiet ? NULL : path);
if (fd >= 0)
close(fd);
bundle_header_release(&header);
@@ -187,77 +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;
- 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)
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)
- return ret;
- 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;
@@ -284,6 +277,7 @@ int verify_bundle(struct repository *r,
printf_ln(_("The bundle uses this filter: %s"),
list_objects_filter_spec(&header->filter));
}
+cleanup:
return ret;
}
@@ -303,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);
@@ -392,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;
@@ -616,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. */
@@ -630,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;