diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 261b610d24017557c137d83a9c005b662e795b6a..8c9e91e78c95a4a3d581aae59d0f00bc95b2c942 100644 (file)
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
static int auto_update_server_info;
static int auto_gc = 1;
static const char *head_name;
+static void *head_name_to_free;
static int sent_capabilities;
static enum deny_action parse_deny_action(const char *var, const char *value)
return git_default_config(var, value, cb);
}
-static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+static void show_ref(const char *path, const unsigned char *sha1)
{
if (sent_capabilities)
packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
@@ -124,10 +125,9 @@ static int show_ref(const char *path, const unsigned char *sha1, int flag, void
" report-status delete-refs side-band-64k",
prefer_ofs_delta ? " ofs-delta" : "");
sent_capabilities = 1;
- return 0;
}
-static int show_ref_cb(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+static int show_ref_cb(const char *path, const unsigned char *sha1, int flag, void *unused)
{
path = strip_namespace(path);
/*
@@ -140,15 +140,33 @@ static int show_ref_cb(const char *path, const unsigned char *sha1, int flag, vo
*/
if (!path)
path = ".have";
- return show_ref(path, sha1, flag, cb_data);
+ show_ref(path, sha1);
+ return 0;
+}
+
+static void show_one_alternate_sha1(const unsigned char sha1[20], void *unused)
+{
+ show_ref(".have", sha1);
+}
+
+static void collect_one_alternate_ref(const struct ref *ref, void *data)
+{
+ struct sha1_array *sa = data;
+ sha1_array_append(sa, ref->old_sha1);
}
static void write_head_info(void)
{
+ struct sha1_array sa = SHA1_ARRAY_INIT;
+ for_each_alternate_ref(collect_one_alternate_ref, &sa);
+ sha1_array_for_each_unique(&sa, show_one_alternate_sha1, NULL);
+ sha1_array_clear(&sa);
for_each_ref(show_ref_cb, NULL);
if (!sent_capabilities)
- show_ref("capabilities^{}", null_sha1, 0, NULL);
+ show_ref("capabilities^{}", null_sha1);
+ /* EOF */
+ packet_flush(1);
}
struct command {
int flag;
strbuf_addf(&buf, "%s%s", get_git_namespace(), cmd->ref_name);
- dst_name = resolve_ref(buf.buf, sha1, 0, &flag);
+ dst_name = resolve_ref_unsafe(buf.buf, sha1, 0, &flag);
strbuf_release(&buf);
if (!(flag & REF_ISSYMREF))
struct command **cmd_list = cb_data;
struct command *cmd = *cmd_list;
- if (!cmd)
+ if (!cmd || is_null_sha1(cmd->new_sha1))
return -1; /* end of list */
*cmd_list = NULL; /* this returns only one */
hashcpy(sha1, cmd->new_sha1);
@@ -659,11 +677,16 @@ static int iterate_receive_command_list(void *cb_data, unsigned char sha1[20])
struct command **cmd_list = cb_data;
struct command *cmd = *cmd_list;
- if (!cmd)
- return -1; /* end of list */
- *cmd_list = cmd->next;
- hashcpy(sha1, cmd->new_sha1);
- return 0;
+ while (cmd) {
+ if (!is_null_sha1(cmd->new_sha1)) {
+ hashcpy(sha1, cmd->new_sha1);
+ *cmd_list = cmd->next;
+ return 0;
+ }
+ cmd = cmd->next;
+ }
+ *cmd_list = NULL;
+ return -1; /* end of list */
}
static void execute_commands(struct command *commands, const char *unpacker_error)
@@ -690,7 +713,8 @@ static void execute_commands(struct command *commands, const char *unpacker_erro
check_aliased_updates(commands);
- head_name = resolve_ref("HEAD", sha1, 0, NULL);
+ free(head_name_to_free);
+ head_name = head_name_to_free = resolve_refdup("HEAD", sha1, 0, NULL);
for (cmd = commands; cmd; cmd = cmd->next)
if (!cmd->skip_update)
return 1;
}
-static void add_one_alternate_sha1(const unsigned char sha1[20], void *unused)
-{
- add_extra_ref(".have", sha1, 0);
-}
-
-static void collect_one_alternate_ref(const struct ref *ref, void *data)
-{
- struct sha1_array *sa = data;
- sha1_array_append(sa, ref->old_sha1);
-}
-
-static void add_alternate_refs(void)
-{
- struct sha1_array sa = SHA1_ARRAY_INIT;
- for_each_alternate_ref(collect_one_alternate_ref, &sa);
- sha1_array_for_each_unique(&sa, add_one_alternate_sha1, NULL);
- sha1_array_clear(&sa);
-}
-
int cmd_receive_pack(int argc, const char **argv, const char *prefix)
{
int advertise_refs = 0;
unpack_limit = receive_unpack_limit;
if (advertise_refs || !stateless_rpc) {
- add_alternate_refs();
write_head_info();
- clear_extra_refs();
-
- /* EOF */
- packet_flush(1);
}
if (advertise_refs)
return 0;