path: root/transport.c
diff options
authorShawn O. Pearce <>2007-09-14 07:31:23 (GMT)
committerJunio C Hamano <>2007-09-19 10:22:30 (GMT)
commit1788c39cd0742439b9bedc28bc10bc4d105b6c0f (patch)
tree7cb5e53238b90e0c9bdcc1812c9ca266af1a12b9 /transport.c
parent106764e6515dd0fb9fda8bb8cab523932ae903b3 (diff)
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 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 was converted to pure C and fetch--tool was no longer being invoked. Signed-off-by: Shawn O. Pearce <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'transport.c')
1 files changed, 14 insertions, 4 deletions
diff --git a/transport.c b/transport.c
index d2cbf3a..0882edd 100644
--- a/transport.c
+++ b/transport.c
@@ -9,7 +9,7 @@
/* Generic functions for using commit walkers */
-static int fetch_objs_via_walker(const struct transport *transport,
+static int fetch_objs_via_walker(struct transport *transport,
int nr_objs, struct ref **to_fetch)
char *dest = xstrdup(transport->url);
@@ -219,7 +219,7 @@ static struct ref *get_refs_from_bundle(const struct transport *transport)
return result;
-static int fetch_refs_from_bundle(const struct transport *transport,
+static int fetch_refs_from_bundle(struct transport *transport,
int nr_heads, struct ref **to_fetch)
struct bundle_transport_data *data = transport->data;
@@ -306,7 +306,7 @@ static struct ref *get_refs_via_connect(const struct transport *transport)
return refs;
-static int fetch_refs_via_pack(const struct transport *transport,
+static int fetch_refs_via_pack(struct transport *transport,
int nr_heads, struct ref **to_fetch)
struct git_transport_data *data = transport->data;
@@ -330,7 +330,7 @@ static int fetch_refs_via_pack(const struct transport *transport,
for (i = 0; i < nr_heads; i++)
heads[i] = xstrdup(to_fetch[i]->name);
- refs = fetch_pack(dest, nr_heads, heads);
+ refs = fetch_pack(dest, nr_heads, heads, &transport->pack_lockfile);
for (i = 0; i < nr_heads; i++)
@@ -445,6 +445,7 @@ struct transport *transport_get(struct remote *remote, const char *url,
ret->url = url;
ret->remote_refs = NULL;
ret->fetch = !!fetch;
+ ret->pack_lockfile = NULL;
return ret;
@@ -500,6 +501,15 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs)
return rc;
+void transport_unlock_pack(struct transport *transport)
+ if (transport->pack_lockfile) {
+ unlink(transport->pack_lockfile);
+ free(transport->pack_lockfile);
+ transport->pack_lockfile = NULL;
+ }
int transport_disconnect(struct transport *transport)
int ret = 0;