diff options
author | Shawn O. Pearce <spearce@spearce.org> | 2007-09-14 03:31:23 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2007-09-19 03:22:30 -0700 |
commit | 1788c39cd0742439b9bedc28bc10bc4d105b6c0f (patch) | |
tree | 7cb5e53238b90e0c9bdcc1812c9ca266af1a12b9 /builtin-fetch-pack.c | |
parent | 106764e6515dd0fb9fda8bb8cab523932ae903b3 (diff) | |
download | git-1788c39cd0742439b9bedc28bc10bc4d105b6c0f.tar.gz |
Remove pack.keep after ref updates in git-fetch
If we are using a native packfile to perform a git-fetch invocation
and the received packfile contained more than the configured limits
of fetch.unpackLimit/transfer.unpackLimit then index-pack will output
a single line saying "keep\t$sha1\n" to stdout. This line needs to
be captured and retained so we can delete the corresponding .keep
file ("$GIT_DIR/objects/pack/pack-$sha1.keep") once all refs have
been safely updated.
This trick has long been in use with git-fetch.sh and its lower level
helper git-fetch--tool as a way to allow index-pack to save the new
packfile before the refs have been updated and yet avoid a race with
any concurrently running git-repack process. It was unfortunately
lost when git-fetch.sh was converted to pure C and fetch--tool was
no longer being invoked.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-fetch-pack.c')
-rw-r--r-- | builtin-fetch-pack.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c index e77cd26719..b0936ccf0c 100644 --- a/builtin-fetch-pack.c +++ b/builtin-fetch-pack.c @@ -493,7 +493,7 @@ static pid_t setup_sideband(int fd[2], int xd[2]) return side_pid; } -static int get_pack(int xd[2]) +static int get_pack(int xd[2], char **pack_lockfile) { int status; pid_t pid, side_pid; @@ -503,6 +503,7 @@ static int get_pack(int xd[2]) char hdr_arg[256]; const char **av; int do_keep = keep_pack; + int keep_pipe[2]; side_pid = setup_sideband(fd, xd); @@ -522,6 +523,8 @@ static int get_pack(int xd[2]) } if (do_keep) { + if (pack_lockfile && pipe(keep_pipe)) + die("fetch-pack: pipe setup failure: %s", strerror(errno)); *av++ = "index-pack"; *av++ = "--stdin"; if (!quiet && !no_progress) @@ -550,6 +553,11 @@ static int get_pack(int xd[2]) die("fetch-pack: unable to fork off %s", argv[0]); if (!pid) { dup2(fd[0], 0); + if (do_keep && pack_lockfile) { + dup2(keep_pipe[1], 1); + close(keep_pipe[0]); + close(keep_pipe[1]); + } close(fd[0]); close(fd[1]); execv_git_cmd(argv); @@ -557,6 +565,11 @@ static int get_pack(int xd[2]) } close(fd[0]); close(fd[1]); + if (do_keep && pack_lockfile) { + close(keep_pipe[1]); + *pack_lockfile = index_pack_lockfile(keep_pipe[0]); + close(keep_pipe[0]); + } while (waitpid(pid, &status, 0) < 0) { if (errno != EINTR) die("waiting for %s: %s", argv[0], strerror(errno)); @@ -574,7 +587,10 @@ static int get_pack(int xd[2]) die("%s died of unnatural causes %d", argv[0], status); } -static struct ref *do_fetch_pack(int fd[2], int nr_match, char **match) +static struct ref *do_fetch_pack(int fd[2], + int nr_match, + char **match, + char **pack_lockfile) { struct ref *ref; unsigned char sha1[20]; @@ -612,7 +628,7 @@ static struct ref *do_fetch_pack(int fd[2], int nr_match, char **match) */ fprintf(stderr, "warning: no common commits\n"); - if (get_pack(fd)) + if (get_pack(fd, pack_lockfile)) die("git-fetch-pack: fetch failed."); all_done: @@ -741,7 +757,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) if (!dest) usage(fetch_pack_usage); - ref = fetch_pack(dest, nr_heads, heads); + ref = fetch_pack(dest, nr_heads, heads, NULL); ret = !ref; @@ -754,7 +770,10 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) return ret; } -struct ref *fetch_pack(const char *dest, int nr_heads, char **heads) +struct ref *fetch_pack(const char *dest, + int nr_heads, + char **heads, + char **pack_lockfile) { int i, ret; int fd[2]; @@ -773,7 +792,7 @@ struct ref *fetch_pack(const char *dest, int nr_heads, char **heads) return NULL; if (heads && nr_heads) nr_heads = remove_duplicates(nr_heads, heads); - ref = do_fetch_pack(fd, nr_heads, heads); + ref = do_fetch_pack(fd, nr_heads, heads, pack_lockfile); close(fd[0]); close(fd[1]); ret = finish_connect(pid); |