Merge branch 'lt/abbrev-auto'
[gitweb.git] / sha1_file.c
index 7a3b74544803fb151b44fe76eab4b95b2ccaaa2c..2eda9291ee307127bdd715f0540994464534429d 100644 (file)
@@ -172,36 +172,42 @@ enum scld_error safe_create_leading_directories_const(const char *path)
        return result;
 }
 
-static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)
+static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)
 {
        int i;
        for (i = 0; i < 20; i++) {
                static char hex[] = "0123456789abcdef";
                unsigned int val = sha1[i];
-               char *pos = pathbuf + i*2 + (i > 0);
-               *pos++ = hex[val >> 4];
-               *pos = hex[val & 0xf];
+               strbuf_addch(buf, hex[val >> 4]);
+               strbuf_addch(buf, hex[val & 0xf]);
+               if (!i)
+                       strbuf_addch(buf, '/');
        }
 }
 
 const char *sha1_file_name(const unsigned char *sha1)
 {
-       static char buf[PATH_MAX];
-       const char *objdir;
-       int len;
+       static struct strbuf buf = STRBUF_INIT;
+
+       strbuf_reset(&buf);
+       strbuf_addf(&buf, "%s/", get_object_directory());
 
-       objdir = get_object_directory();
-       len = strlen(objdir);
+       fill_sha1_path(&buf, sha1);
+       return buf.buf;
+}
 
-       /* '/' + sha1(2) + '/' + sha1(38) + '\0' */
-       if (len + 43 > PATH_MAX)
-               die("insanely long object directory %s", objdir);
-       memcpy(buf, objdir, len);
-       buf[len] = '/';
-       buf[len+3] = '/';
-       buf[len+42] = '\0';
-       fill_sha1_path(buf + len + 1, sha1);
-       return buf;
+struct strbuf *alt_scratch_buf(struct alternate_object_database *alt)
+{
+       strbuf_setlen(&alt->scratch, alt->base_len);
+       return &alt->scratch;
+}
+
+static const char *alt_sha1_path(struct alternate_object_database *alt,
+                                const unsigned char *sha1)
+{
+       struct strbuf *buf = alt_scratch_buf(alt);
+       fill_sha1_path(buf, sha1);
+       return buf->buf;
 }
 
 /*
@@ -254,8 +260,7 @@ static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)
         * thing twice, or object directory itself.
         */
        for (alt = alt_odb_list; alt; alt = alt->next) {
-               if (path->len == alt->name - alt->base - 1 &&
-                   !memcmp(path->buf, alt->base, path->len))
+               if (!fspathcmp(path->buf, alt->path))
                        return 0;
        }
        if (!fspathcmp(path->buf, normalized_objdir))
@@ -283,7 +288,6 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
        int depth, const char *normalized_objdir)
 {
        struct alternate_object_database *ent;
-       size_t entlen;
        struct strbuf pathbuf = STRBUF_INIT;
 
        if (!is_absolute_path(entry) && relative_base) {
@@ -311,14 +315,7 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
                return -1;
        }
 
-       entlen = st_add(pathbuf.len, 43); /* '/' + 2 hex + '/' + 38 hex + NUL */
-       ent = xmalloc(st_add(sizeof(*ent), entlen));
-       memcpy(ent->base, pathbuf.buf, pathbuf.len);
-
-       ent->name = ent->base + pathbuf.len + 1;
-       ent->base[pathbuf.len] = '/';
-       ent->base[pathbuf.len + 3] = '/';
-       ent->base[entlen-1] = 0;
+       ent = alloc_alt_odb(pathbuf.buf);
 
        /* add the alternate entry */
        *alt_odb_tail = ent;
@@ -357,12 +354,7 @@ static void link_alt_odb_entries(const char *alt, int len, int sep,
                const char *entry = entries.items[i].string;
                if (entry[0] == '\0' || entry[0] == '#')
                        continue;
-               if (!is_absolute_path(entry) && depth) {
-                       error("%s: ignoring relative alternate object store %s",
-                                       relative_base, entry);
-               } else {
-                       link_alt_odb_entry(entry, relative_base, depth, objdirbuf.buf);
-               }
+               link_alt_odb_entry(entry, relative_base, depth, objdirbuf.buf);
        }
        string_list_clear(&entries, 0);
        free(alt_copy);
@@ -395,6 +387,18 @@ void read_info_alternates(const char * relative_base, int depth)
        munmap(map, mapsz);
 }
 
+struct alternate_object_database *alloc_alt_odb(const char *dir)
+{
+       struct alternate_object_database *ent;
+
+       FLEX_ALLOC_STR(ent, path, dir);
+       strbuf_init(&ent->scratch, 0);
+       strbuf_addf(&ent->scratch, "%s/", dir);
+       ent->base_len = ent->scratch.len;
+
+       return ent;
+}
+
 void add_to_alternates_file(const char *reference)
 {
        struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
@@ -591,8 +595,8 @@ static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen)
        struct alternate_object_database *alt;
        prepare_alt_odb();
        for (alt = alt_odb_list; alt; alt = alt->next) {
-               fill_sha1_path(alt->name, sha1);
-               if (check_and_freshen_file(alt->base, freshen))
+               const char *path = alt_sha1_path(alt, sha1);
+               if (check_and_freshen_file(path, freshen))
                        return 1;
        }
        return 0;
@@ -1468,11 +1472,8 @@ void prepare_packed_git(void)
                return;
        prepare_packed_git_one(get_object_directory(), 1);
        prepare_alt_odb();
-       for (alt = alt_odb_list; alt; alt = alt->next) {
-               alt->name[-1] = 0;
-               prepare_packed_git_one(alt->base, 0);
-               alt->name[-1] = '/';
-       }
+       for (alt = alt_odb_list; alt; alt = alt->next)
+               prepare_packed_git_one(alt->path, 0);
        rearrange_packed_git();
        prepare_packed_git_mru();
        prepare_packed_git_run_once = 1;
@@ -1590,8 +1591,8 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st)
        prepare_alt_odb();
        errno = ENOENT;
        for (alt = alt_odb_list; alt; alt = alt->next) {
-               fill_sha1_path(alt->name, sha1);
-               if (!lstat(alt->base, st))
+               const char *path = alt_sha1_path(alt, sha1);
+               if (!lstat(path, st))
                        return 0;
        }
 
@@ -1611,8 +1612,8 @@ static int open_sha1_file(const unsigned char *sha1)
 
        prepare_alt_odb();
        for (alt = alt_odb_list; alt; alt = alt->next) {
-               fill_sha1_path(alt->name, sha1);
-               fd = git_open_noatime(alt->base);
+               const char *path = alt_sha1_path(alt, sha1);
+               fd = git_open_noatime(path);
                if (fd >= 0)
                        return fd;
                if (most_interesting_errno == ENOENT)
@@ -1851,11 +1852,9 @@ static int parse_sha1_header_extended(const char *hdr, struct object_info *oi,
 
 int parse_sha1_header(const char *hdr, unsigned long *sizep)
 {
-       struct object_info oi;
+       struct object_info oi = OBJECT_INFO_INIT;
 
        oi.sizep = sizep;
-       oi.typename = NULL;
-       oi.typep = NULL;
        return parse_sha1_header_extended(hdr, &oi, LOOKUP_REPLACE_OBJECT);
 }
 
@@ -2093,8 +2092,8 @@ static enum object_type packed_to_object_type(struct packed_git *p,
        goto out;
 }
 
-static int packed_object_info(struct packed_git *p, off_t obj_offset,
-                             struct object_info *oi)
+int packed_object_info(struct packed_git *p, off_t obj_offset,
+                      struct object_info *oi)
 {
        struct pack_window *w_curs = NULL;
        unsigned long size;
@@ -2865,7 +2864,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
 int sha1_object_info(const unsigned char *sha1, unsigned long *sizep)
 {
        enum object_type type;
-       struct object_info oi = {NULL};
+       struct object_info oi = OBJECT_INFO_INIT;
 
        oi.typep = &type;
        oi.sizep = sizep;
@@ -3336,6 +3335,11 @@ int has_object_file(const struct object_id *oid)
        return has_sha1_file(oid->hash);
 }
 
+int has_object_file_with_flags(const struct object_id *oid, int flags)
+{
+       return has_sha1_file_with_flags(oid->hash, flags);
+}
+
 static void check_tree(const void *buf, size_t size)
 {
        struct tree_desc desc;
@@ -3675,8 +3679,7 @@ static int loose_from_alt_odb(struct alternate_object_database *alt,
        struct strbuf buf = STRBUF_INIT;
        int r;
 
-       /* copy base not including trailing '/' */
-       strbuf_add(&buf, alt->base, alt->name - alt->base - 1);
+       strbuf_addstr(&buf, alt->path);
        r = for_each_loose_file_in_objdir_buf(&buf,
                                              data->cb, NULL, NULL,
                                              data->data);