Skip to content
Snippets Groups Projects
Commit 9e3dc6bf authored by Junio C Hamano's avatar Junio C Hamano
Browse files

Merge branch 'jk/close-duped-fd-before-unlock-for-bundle'

When "git bundle" aborts due to an empty commit ranges
(i.e. resulting in an empty pack), it left a file descriptor to an
lockfile open, which resulted in leftover lockfile on Windows where
you cannot remove a file with an open file descriptor.  This has
been corrected.

* jk/close-duped-fd-before-unlock-for-bundle:
  bundle: dup() output descriptor closer to point-of-use
parents 4520c233 2c8ee1f5
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -243,7 +243,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;
Loading
Loading
@@ -256,6 +256,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"));
 
Loading
Loading
@@ -421,21 +435,10 @@ 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));
 
Loading
Loading
@@ -463,10 +466,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))
Loading
Loading
@@ -474,11 +475,7 @@ 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;
}
 
Loading
Loading
Loading
Loading
@@ -71,4 +71,10 @@ test_expect_success 'prerequisites with an empty commit message' '
git bundle verify bundle
'
 
test_expect_success 'failed bundle creation does not leave cruft' '
# This fails because the bundle would be empty.
test_must_fail git bundle create fail.bundle master..master &&
test_path_is_missing fail.bundle.lock
'
test_done
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment