upload-pack: teach deepen-relative in protocol v2
[gitweb.git] / bundle.c
index 24cbe409863a83e8bda453af637c2237504a531d..37b1daa6918bafb6b21faba47d25fcc6433698ba 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -127,7 +127,9 @@ static int list_refs(struct ref_list *r, int argc, const char **argv)
 /* Remember to update object flag allocation in object.h */
 #define PREREQ_MARK (1u<<16)
 
-int verify_bundle(struct bundle_header *header, int verbose)
+int verify_bundle(struct repository *r,
+                 struct bundle_header *header,
+                 int verbose)
 {
        /*
         * Do fast check, then if any prereqs are missing then go line by line
@@ -140,10 +142,10 @@ int verify_bundle(struct bundle_header *header, int verbose)
        int i, ret = 0, req_nr;
        const char *message = _("Repository lacks these prerequisite commits:");
 
-       init_revisions(&revs, NULL);
+       repo_init_revisions(r, &revs, NULL);
        for (i = 0; i < p->nr; i++) {
                struct ref_list_entry *e = p->list + i;
-               struct object *o = parse_object(the_repository, &e->oid);
+               struct object *o = parse_object(r, &e->oid);
                if (o) {
                        o->flags |= PREREQ_MARK;
                        add_pending_object(&revs, o, e->name);
@@ -168,7 +170,7 @@ int verify_bundle(struct bundle_header *header, int verbose)
 
        for (i = 0; i < p->nr; i++) {
                struct ref_list_entry *e = p->list + i;
-               struct object *o = parse_object(the_repository, &e->oid);
+               struct object *o = parse_object(r, &e->oid);
                assert(o); /* otherwise we'd have returned early */
                if (o->flags & SHOWN)
                        continue;
@@ -180,7 +182,7 @@ int verify_bundle(struct bundle_header *header, int verbose)
        /* Clean up objects used, as they will be reused. */
        for (i = 0; i < p->nr; i++) {
                struct ref_list_entry *e = p->list + i;
-               commit = lookup_commit_reference_gently(the_repository, &e->oid, 1);
+               commit = lookup_commit_reference_gently(r, &e->oid, 1);
                if (commit)
                        clear_commit_marks(commit, ALL_REV_FLAGS);
        }
@@ -243,7 +245,7 @@ static int is_tag_in_date_range(struct object *tag, struct rev_info *revs)
 }
 
 
-/* Write the pack data to bundle_fd, then close it if it is > 1. */
+/* Write the pack data to bundle_fd */
 static int write_pack_data(int bundle_fd, struct rev_info *revs)
 {
        struct child_process pack_objects = CHILD_PROCESS_INIT;
@@ -256,6 +258,20 @@ static int write_pack_data(int bundle_fd, struct rev_info *revs)
        pack_objects.in = -1;
        pack_objects.out = bundle_fd;
        pack_objects.git_cmd = 1;
+
+       /*
+        * start_command() will close our descriptor if it's >1. Duplicate it
+        * to avoid surprising the caller.
+        */
+       if (pack_objects.out > 1) {
+               pack_objects.out = dup(pack_objects.out);
+               if (pack_objects.out < 0) {
+                       error_errno(_("unable to dup bundle descriptor"));
+                       child_process_clear(&pack_objects);
+                       return -1;
+               }
+       }
+
        if (start_command(&pack_objects))
                return error(_("Could not spawn pack-objects"));
 
@@ -369,14 +385,13 @@ static int write_bundle_refs(int bundle_fd, struct rev_info *revs)
                 * commit that is referenced by the tag, and not the tag
                 * itself.
                 */
-               if (oidcmp(&oid, &e->item->oid)) {
+               if (!oideq(&oid, &e->item->oid)) {
                        /*
                         * Is this the positive end of a range expressed
                         * in terms of a tag (e.g. v2.0 from the range
                         * "v1.0..v2.0")?
                         */
-                       struct commit *one = lookup_commit_reference(the_repository,
-                                                                    &oid);
+                       struct commit *one = lookup_commit_reference(revs->repo, &oid);
                        struct object *obj;
 
                        if (e->item == &(one->object)) {
@@ -409,8 +424,8 @@ static int write_bundle_refs(int bundle_fd, struct rev_info *revs)
        return ref_count;
 }
 
-int create_bundle(struct bundle_header *header, const char *path,
-                 int argc, const char **argv)
+int create_bundle(struct repository *r, struct bundle_header *header,
+                 const char *path, int argc, const char **argv)
 {
        struct lock_file lock = LOCK_INIT;
        int bundle_fd = -1;
@@ -421,27 +436,16 @@ int create_bundle(struct bundle_header *header, const char *path,
        bundle_to_stdout = !strcmp(path, "-");
        if (bundle_to_stdout)
                bundle_fd = 1;
-       else {
+       else
                bundle_fd = hold_lock_file_for_update(&lock, path,
                                                      LOCK_DIE_ON_ERROR);
 
-               /*
-                * write_pack_data() will close the fd passed to it,
-                * but commit_lock_file() will also try to close the
-                * lockfile's fd. So make a copy of the file
-                * descriptor to avoid trying to close it twice.
-                */
-               bundle_fd = dup(bundle_fd);
-               if (bundle_fd < 0)
-                       die_errno("unable to dup file descriptor");
-       }
-
        /* write signature */
        write_or_die(bundle_fd, bundle_signature, strlen(bundle_signature));
 
        /* init revs to list objects for pack-objects later */
        save_commit_buffer = 0;
-       init_revisions(&revs, NULL);
+       repo_init_revisions(r, &revs, NULL);
 
        /* write prerequisites */
        if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv))
@@ -463,10 +467,8 @@ int create_bundle(struct bundle_header *header, const char *path,
                goto err;
 
        /* write pack */
-       if (write_pack_data(bundle_fd, &revs)) {
-               bundle_fd = -1; /* already closed by the above call */
+       if (write_pack_data(bundle_fd, &revs))
                goto err;
-       }
 
        if (!bundle_to_stdout) {
                if (commit_lock_file(&lock))
@@ -474,15 +476,12 @@ int create_bundle(struct bundle_header *header, const char *path,
        }
        return 0;
 err:
-       if (!bundle_to_stdout) {
-               if (0 <= bundle_fd)
-                       close(bundle_fd);
-               rollback_lock_file(&lock);
-       }
+       rollback_lock_file(&lock);
        return -1;
 }
 
-int unbundle(struct bundle_header *header, int bundle_fd, int flags)
+int unbundle(struct repository *r, struct bundle_header *header,
+            int bundle_fd, int flags)
 {
        const char *argv_index_pack[] = {"index-pack",
                                         "--fix-thin", "--stdin", NULL, NULL};
@@ -491,7 +490,7 @@ int unbundle(struct bundle_header *header, int bundle_fd, int flags)
        if (flags & BUNDLE_VERBOSE)
                argv_index_pack[3] = "-v";
 
-       if (verify_bundle(header, 0))
+       if (verify_bundle(r, header, 0))
                return -1;
        ip.argv = argv_index_pack;
        ip.in = bundle_fd;