summaryrefslogtreecommitdiff
path: root/bundle.c
diff options
context:
space:
mode:
Diffstat (limited to 'bundle.c')
-rw-r--r--bundle.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/bundle.c b/bundle.c
index 2e2dbd50ef..b9dacc0241 100644
--- a/bundle.c
+++ b/bundle.c
@@ -235,7 +235,9 @@ out:
return result;
}
-static int write_pack_data(int bundle_fd, struct lock_file *lock, struct rev_info *revs)
+
+/* Write the pack data to bundle_fd, then close it if it is > 1. */
+static int write_pack_data(int bundle_fd, struct rev_info *revs)
{
struct child_process pack_objects = CHILD_PROCESS_INIT;
int i;
@@ -250,13 +252,6 @@ static int write_pack_data(int bundle_fd, struct lock_file *lock, struct rev_inf
if (start_command(&pack_objects))
return error(_("Could not spawn pack-objects"));
- /*
- * start_command closed bundle_fd if it was > 1
- * so set the lock fd to -1 so commit_lock_file()
- * won't fail trying to close it.
- */
- lock->fd = -1;
-
for (i = 0; i < revs->pending.nr; i++) {
struct object *object = revs->pending.objects[i].item;
if (object->flags & UNINTERESTING)
@@ -334,7 +329,7 @@ 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), sha1, &ref) != 1)
- continue;
+ goto skip_write_ref;
if (read_ref_full(e->name, RESOLVE_REF_READING, sha1, &flag))
flag = 0;
display_ref = (flag & REF_ISSYMREF) ? e->name : ref;
@@ -342,7 +337,7 @@ static int write_bundle_refs(int bundle_fd, struct rev_info *revs)
if (e->item->type == OBJ_TAG &&
!is_tag_in_date_range(e->item, revs)) {
e->item->flags |= UNINTERESTING;
- continue;
+ goto skip_write_ref;
}
/*
@@ -357,8 +352,7 @@ static int write_bundle_refs(int bundle_fd, struct rev_info *revs)
if (!(e->item->flags & SHOWN) && e->item->type == OBJ_COMMIT) {
warning(_("ref '%s' is excluded by the rev-list options"),
e->name);
- free(ref);
- continue;
+ goto skip_write_ref;
}
/*
* If you run "git bundle create bndl v1.0..v2.0", the
@@ -388,8 +382,7 @@ static int write_bundle_refs(int bundle_fd, struct rev_info *revs)
obj->flags |= SHOWN;
add_pending_object(revs, obj, e->name);
}
- free(ref);
- continue;
+ goto skip_write_ref;
}
ref_count++;
@@ -397,6 +390,7 @@ static int write_bundle_refs(int bundle_fd, struct rev_info *revs)
write_or_die(bundle_fd, " ", 1);
write_or_die(bundle_fd, display_ref, strlen(display_ref));
write_or_die(bundle_fd, "\n", 1);
+ skip_write_ref:
free(ref);
}
@@ -417,10 +411,21 @@ 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));
@@ -446,7 +451,7 @@ int create_bundle(struct bundle_header *header, const char *path,
return -1;
/* write pack */
- if (write_pack_data(bundle_fd, &lock, &revs))
+ if (write_pack_data(bundle_fd, &revs))
return -1;
if (!bundle_to_stdout) {