checkout-index: handle "--no-prefix" option
[gitweb.git] / builtin / receive-pack.c
index e6b93d026478dce208ab4c267d9b6e67fa856c8d..ca38131873aad1c5dd5b8001aceb39ed906b3c2d 100644 (file)
@@ -195,9 +195,6 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
 
 static void show_ref(const char *path, const unsigned char *sha1)
 {
-       if (ref_is_hidden(path))
-               return;
-
        if (sent_capabilities) {
                packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
        } else {
@@ -219,9 +216,14 @@ static void show_ref(const char *path, const unsigned char *sha1)
        }
 }
 
-static int show_ref_cb(const char *path, const struct object_id *oid, int flag, void *unused)
+static int show_ref_cb(const char *path_full, const struct object_id *oid,
+                      int flag, void *unused)
 {
-       path = strip_namespace(path);
+       const char *path = strip_namespace(path_full);
+
+       if (ref_is_hidden(path, path_full))
+               return 0;
+
        /*
         * Advertise refs outside our current namespace as ".have"
         * refs, so that the client can use them to minimize data
@@ -244,7 +246,7 @@ static void show_one_alternate_sha1(const unsigned char sha1[20], void *unused)
 static void collect_one_alternate_ref(const struct ref *ref, void *data)
 {
        struct sha1_array *sa = data;
-       sha1_array_append(sa, ref->old_sha1);
+       sha1_array_append(sa, ref->old_oid.hash);
 }
 
 static void write_head_info(void)
@@ -280,10 +282,10 @@ static void rp_warning(const char *err, ...) __attribute__((format (printf, 1, 2
 
 static void report_message(const char *prefix, const char *err, va_list params)
 {
-       int sz = strlen(prefix);
+       int sz;
        char msg[4096];
 
-       strncpy(msg, prefix, sz);
+       sz = xsnprintf(msg, sizeof(msg), "%s", prefix);
        sz += vsnprintf(msg + sz, sizeof(msg) - sz, err, params);
        if (sz > (sizeof(msg) - 1))
                sz = sizeof(msg) - 1;
@@ -1071,8 +1073,11 @@ static void check_aliased_update(struct command *cmd, struct string_list *list)
        const char *dst_name;
        struct string_list_item *item;
        struct command *dst_cmd;
-       unsigned char sha1[20];
-       char cmd_oldh[41], cmd_newh[41], dst_oldh[41], dst_newh[41];
+       unsigned char sha1[GIT_SHA1_RAWSZ];
+       char cmd_oldh[GIT_SHA1_HEXSZ + 1],
+            cmd_newh[GIT_SHA1_HEXSZ + 1],
+            dst_oldh[GIT_SHA1_HEXSZ + 1],
+            dst_newh[GIT_SHA1_HEXSZ + 1];
        int flag;
 
        strbuf_addf(&buf, "%s%s", get_git_namespace(), cmd->ref_name);
@@ -1103,10 +1108,10 @@ static void check_aliased_update(struct command *cmd, struct string_list *list)
 
        dst_cmd->skip_update = 1;
 
-       strcpy(cmd_oldh, find_unique_abbrev(cmd->old_sha1, DEFAULT_ABBREV));
-       strcpy(cmd_newh, find_unique_abbrev(cmd->new_sha1, DEFAULT_ABBREV));
-       strcpy(dst_oldh, find_unique_abbrev(dst_cmd->old_sha1, DEFAULT_ABBREV));
-       strcpy(dst_newh, find_unique_abbrev(dst_cmd->new_sha1, DEFAULT_ABBREV));
+       find_unique_abbrev_r(cmd_oldh, cmd->old_sha1, DEFAULT_ABBREV);
+       find_unique_abbrev_r(cmd_newh, cmd->new_sha1, DEFAULT_ABBREV);
+       find_unique_abbrev_r(dst_oldh, dst_cmd->old_sha1, DEFAULT_ABBREV);
+       find_unique_abbrev_r(dst_newh, dst_cmd->new_sha1, DEFAULT_ABBREV);
        rp_error("refusing inconsistent update between symref '%s' (%s..%s) and"
                 " its target '%s' (%s..%s)",
                 cmd->ref_name, cmd_oldh, cmd_newh,
@@ -1192,16 +1197,29 @@ static int iterate_receive_command_list(void *cb_data, unsigned char sha1[20])
 
 static void reject_updates_to_hidden(struct command *commands)
 {
+       struct strbuf refname_full = STRBUF_INIT;
+       size_t prefix_len;
        struct command *cmd;
 
+       strbuf_addstr(&refname_full, get_git_namespace());
+       prefix_len = refname_full.len;
+
        for (cmd = commands; cmd; cmd = cmd->next) {
-               if (cmd->error_string || !ref_is_hidden(cmd->ref_name))
+               if (cmd->error_string)
+                       continue;
+
+               strbuf_setlen(&refname_full, prefix_len);
+               strbuf_addstr(&refname_full, cmd->ref_name);
+
+               if (!ref_is_hidden(cmd->ref_name, refname_full.buf))
                        continue;
                if (is_null_sha1(cmd->new_sha1))
                        cmd->error_string = "deny deleting a hidden ref";
                else
                        cmd->error_string = "deny updating a hidden ref";
        }
+
+       strbuf_release(&refname_full);
 }
 
 static int should_process_cmd(struct command *cmd)
@@ -1521,15 +1539,18 @@ static const char *unpack(int err_fd, struct shallow_info *si)
                if (status)
                        return "unpack-objects abnormal exit";
        } else {
-               int s;
-               char keep_arg[256];
-
-               s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
-               if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
-                       strcpy(keep_arg + s, "localhost");
+               char hostname[256];
 
                argv_array_pushl(&child.args, "index-pack",
-                                "--stdin", hdr_arg, keep_arg, NULL);
+                                "--stdin", hdr_arg, NULL);
+
+               if (gethostname(hostname, sizeof(hostname)))
+                       xsnprintf(hostname, sizeof(hostname), "localhost");
+               argv_array_pushf(&child.args,
+                                "--keep=receive-pack %"PRIuMAX" on %s",
+                                (uintmax_t)getpid(),
+                                hostname);
+
                if (fsck_objects)
                        argv_array_pushf(&child.args, "--strict%s",
                                fsck_msg_types.buf);