aboutsummaryrefslogtreecommitdiff
path: root/builtin-receive-pack.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin-receive-pack.c')
-rw-r--r--builtin-receive-pack.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/builtin-receive-pack.c b/builtin-receive-pack.c
index 6d6027ead..45e3cd90f 100644
--- a/builtin-receive-pack.c
+++ b/builtin-receive-pack.c
@@ -6,6 +6,8 @@
#include "exec_cmd.h"
#include "commit.h"
#include "object.h"
+#include "remote.h"
+#include "transport.h"
static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
@@ -462,6 +464,40 @@ static int delete_only(struct command *cmd)
return 1;
}
+static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
+{
+ char *other = xstrdup(make_absolute_path(e->base));
+ size_t len = strlen(other);
+ struct remote *remote;
+ struct transport *transport;
+ const struct ref *extra;
+
+ while (other[len-1] == '/')
+ other[--len] = '\0';
+ if (len < 8 || memcmp(other + len - 8, "/objects", 8))
+ return 0;
+ /* Is this a git repository with refs? */
+ memcpy(other + len - 8, "/refs", 6);
+ if (!is_directory(other))
+ return 0;
+ other[len - 8] = '\0';
+ remote = remote_get(other);
+ transport = transport_get(remote, other);
+ for (extra = transport_get_remote_refs(transport);
+ extra;
+ extra = extra->next) {
+ add_extra_ref(".have", extra->old_sha1, 0);
+ }
+ transport_disconnect(transport);
+ free(other);
+ return 0;
+}
+
+static void add_alternate_refs(void)
+{
+ foreach_alt_odb(add_refs_from_alternate, NULL);
+}
+
int cmd_receive_pack(int argc, const char **argv, const char *prefix)
{
int i;
@@ -497,7 +533,9 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
else if (0 <= receive_unpack_limit)
unpack_limit = receive_unpack_limit;
+ add_alternate_refs();
write_head_info();
+ clear_extra_refs();
/* EOF */
packet_flush(1);