Git 2.17.1
[gitweb.git] / builtin / receive-pack.c
index cc4876740569c6e495b7cb32161d019619171d79..75e7f18aceffc42b5fdc58296559c67d47203098 100644 (file)
@@ -24,6 +24,7 @@
 #include "tmp-objdir.h"
 #include "oidset.h"
 #include "packfile.h"
+#include "protocol.h"
 
 static const char * const receive_pack_usage[] = {
        N_("git receive-pack <git-dir>"),
@@ -68,7 +69,7 @@ static int sent_capabilities;
 static int shallow_update;
 static const char *alt_shallow_file;
 static struct strbuf push_cert = STRBUF_INIT;
-static unsigned char push_cert_sha1[20];
+static struct object_id push_cert_oid;
 static struct signature_check sigcheck;
 static const char *push_cert_nonce;
 static const char *cert_nonce_seed;
@@ -632,8 +633,9 @@ static void prepare_push_cert_sha1(struct child_process *proc)
                int bogs /* beginning_of_gpg_sig */;
 
                already_done = 1;
-               if (write_sha1_file(push_cert.buf, push_cert.len, "blob", push_cert_sha1))
-                       hashclr(push_cert_sha1);
+               if (write_object_file(push_cert.buf, push_cert.len, "blob",
+                                     &push_cert_oid))
+                       oidclr(&push_cert_oid);
 
                memset(&sigcheck, '\0', sizeof(sigcheck));
                sigcheck.result = 'N';
@@ -654,9 +656,9 @@ static void prepare_push_cert_sha1(struct child_process *proc)
                strbuf_release(&gpg_status);
                nonce_status = check_nonce(push_cert.buf, bogs);
        }
-       if (!is_null_sha1(push_cert_sha1)) {
+       if (!is_null_oid(&push_cert_oid)) {
                argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT=%s",
-                                sha1_to_hex(push_cert_sha1));
+                                oid_to_hex(&push_cert_oid));
                argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_SIGNER=%s",
                                 sigcheck.signer ? sigcheck.signer : "");
                argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_KEY=%s",
@@ -870,7 +872,7 @@ static void refuse_unconfigured_deny_delete_current(void)
        rp_error("%s", _(refuse_unconfigured_deny_delete_current_msg));
 }
 
-static int command_singleton_iterator(void *cb_data, unsigned char sha1[20]);
+static int command_singleton_iterator(void *cb_data, struct object_id *oid);
 static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
 {
        static struct lock_file shallow_lock;
@@ -1139,7 +1141,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
                }
                if (ref_transaction_delete(transaction,
                                           namespaced_name,
-                                          old_oid ? old_oid->hash : NULL,
+                                          old_oid,
                                           0, "push", &err)) {
                        rp_error("%s", err.buf);
                        strbuf_release(&err);
@@ -1156,7 +1158,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
 
                if (ref_transaction_update(transaction,
                                           namespaced_name,
-                                          new_oid->hash, old_oid->hash,
+                                          new_oid, old_oid,
                                           0, "push",
                                           &err)) {
                        rp_error("%s", err.buf);
@@ -1270,7 +1272,7 @@ static void check_aliased_updates(struct command *commands)
        string_list_clear(&ref_list, 0);
 }
 
-static int command_singleton_iterator(void *cb_data, unsigned char sha1[20])
+static int command_singleton_iterator(void *cb_data, struct object_id *oid)
 {
        struct command **cmd_list = cb_data;
        struct command *cmd = *cmd_list;
@@ -1278,7 +1280,7 @@ static int command_singleton_iterator(void *cb_data, unsigned char sha1[20])
        if (!cmd || is_null_oid(&cmd->new_oid))
                return -1; /* end of list */
        *cmd_list = NULL; /* this returns only one */
-       hashcpy(sha1, cmd->new_oid.hash);
+       oidcpy(oid, &cmd->new_oid);
        return 0;
 }
 
@@ -1309,7 +1311,7 @@ struct iterate_data {
        struct shallow_info *si;
 };
 
-static int iterate_receive_command_list(void *cb_data, unsigned char sha1[20])
+static int iterate_receive_command_list(void *cb_data, struct object_id *oid)
 {
        struct iterate_data *data = cb_data;
        struct command **cmd_list = &data->cmds;
@@ -1320,7 +1322,7 @@ static int iterate_receive_command_list(void *cb_data, unsigned char sha1[20])
                        /* to be checked in update_shallow_ref() */
                        continue;
                if (!is_null_oid(&cmd->new_oid) && !cmd->skip_update) {
-                       hashcpy(sha1, cmd->new_oid.hash);
+                       oidcpy(oid, &cmd->new_oid);
                        *cmd_list = cmd->next;
                        return 0;
                }
@@ -1961,6 +1963,22 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
        else if (0 <= receive_unpack_limit)
                unpack_limit = receive_unpack_limit;
 
+       switch (determine_protocol_version_server()) {
+       case protocol_v1:
+               /*
+                * v1 is just the original protocol with a version string,
+                * so just fall through after writing the version string.
+                */
+               if (advertise_refs || !stateless_rpc)
+                       packet_write_fmt(1, "version 1\n");
+
+               /* fallthrough */
+       case protocol_v0:
+               break;
+       case protocol_unknown_version:
+               BUG("unknown protocol version");
+       }
+
        if (advertise_refs || !stateless_rpc) {
                write_head_info();
        }