Merge branch 'ma/up-to-date'
[gitweb.git] / sha1_file.c
index 20cb30b87bc7f5f2812bb28e7346d28577c72438..5f71bbac3ea9a11a4369ec0353e2e1258979ba19 100644 (file)
@@ -30,7 +30,7 @@
 #include "quote.h"
 #include "packfile.h"
 
-const unsigned char null_sha1[20];
+const unsigned char null_sha1[GIT_MAX_RAWSZ];
 const struct object_id null_oid;
 const struct object_id empty_tree_oid = {
        EMPTY_TREE_SHA1_BIN_LITERAL
@@ -1075,178 +1075,6 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep)
        return parse_sha1_header_extended(hdr, &oi, 0);
 }
 
-void check_pack_index_ptr(const struct packed_git *p, const void *vptr)
-{
-       const unsigned char *ptr = vptr;
-       const unsigned char *start = p->index_data;
-       const unsigned char *end = start + p->index_size;
-       if (ptr < start)
-               die(_("offset before start of pack index for %s (corrupt index?)"),
-                   p->pack_name);
-       /* No need to check for underflow; .idx files must be at least 8 bytes */
-       if (ptr >= end - 8)
-               die(_("offset beyond end of pack index for %s (truncated index?)"),
-                   p->pack_name);
-}
-
-off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n)
-{
-       const unsigned char *index = p->index_data;
-       index += 4 * 256;
-       if (p->index_version == 1) {
-               return ntohl(*((uint32_t *)(index + 24 * n)));
-       } else {
-               uint32_t off;
-               index += 8 + p->num_objects * (20 + 4);
-               off = ntohl(*((uint32_t *)(index + 4 * n)));
-               if (!(off & 0x80000000))
-                       return off;
-               index += p->num_objects * 4 + (off & 0x7fffffff) * 8;
-               check_pack_index_ptr(p, index);
-               return (((uint64_t)ntohl(*((uint32_t *)(index + 0)))) << 32) |
-                                  ntohl(*((uint32_t *)(index + 4)));
-       }
-}
-
-off_t find_pack_entry_one(const unsigned char *sha1,
-                                 struct packed_git *p)
-{
-       const uint32_t *level1_ofs = p->index_data;
-       const unsigned char *index = p->index_data;
-       unsigned hi, lo, stride;
-       static int debug_lookup = -1;
-
-       if (debug_lookup < 0)
-               debug_lookup = !!getenv("GIT_DEBUG_LOOKUP");
-
-       if (!index) {
-               if (open_pack_index(p))
-                       return 0;
-               level1_ofs = p->index_data;
-               index = p->index_data;
-       }
-       if (p->index_version > 1) {
-               level1_ofs += 2;
-               index += 8;
-       }
-       index += 4 * 256;
-       hi = ntohl(level1_ofs[*sha1]);
-       lo = ((*sha1 == 0x0) ? 0 : ntohl(level1_ofs[*sha1 - 1]));
-       if (p->index_version > 1) {
-               stride = 20;
-       } else {
-               stride = 24;
-               index += 4;
-       }
-
-       if (debug_lookup)
-               printf("%02x%02x%02x... lo %u hi %u nr %"PRIu32"\n",
-                      sha1[0], sha1[1], sha1[2], lo, hi, p->num_objects);
-
-       while (lo < hi) {
-               unsigned mi = (lo + hi) / 2;
-               int cmp = hashcmp(index + mi * stride, sha1);
-
-               if (debug_lookup)
-                       printf("lo %u hi %u rg %u mi %u\n",
-                              lo, hi, hi - lo, mi);
-               if (!cmp)
-                       return nth_packed_object_offset(p, mi);
-               if (cmp > 0)
-                       hi = mi;
-               else
-                       lo = mi+1;
-       }
-       return 0;
-}
-
-int is_pack_valid(struct packed_git *p)
-{
-       /* An already open pack is known to be valid. */
-       if (p->pack_fd != -1)
-               return 1;
-
-       /* If the pack has one window completely covering the
-        * file size, the pack is known to be valid even if
-        * the descriptor is not currently open.
-        */
-       if (p->windows) {
-               struct pack_window *w = p->windows;
-
-               if (!w->offset && w->len == p->pack_size)
-                       return 1;
-       }
-
-       /* Force the pack to open to prove its valid. */
-       return !open_packed_git(p);
-}
-
-static int fill_pack_entry(const unsigned char *sha1,
-                          struct pack_entry *e,
-                          struct packed_git *p)
-{
-       off_t offset;
-
-       if (p->num_bad_objects) {
-               unsigned i;
-               for (i = 0; i < p->num_bad_objects; i++)
-                       if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
-                               return 0;
-       }
-
-       offset = find_pack_entry_one(sha1, p);
-       if (!offset)
-               return 0;
-
-       /*
-        * We are about to tell the caller where they can locate the
-        * requested object.  We better make sure the packfile is
-        * still here and can be accessed before supplying that
-        * answer, as it may have been deleted since the index was
-        * loaded!
-        */
-       if (!is_pack_valid(p))
-               return 0;
-       e->offset = offset;
-       e->p = p;
-       hashcpy(e->sha1, sha1);
-       return 1;
-}
-
-/*
- * Iff a pack file contains the object named by sha1, return true and
- * store its location to e.
- */
-static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
-{
-       struct mru_entry *p;
-
-       prepare_packed_git();
-       if (!packed_git)
-               return 0;
-
-       for (p = packed_git_mru->head; p; p = p->next) {
-               if (fill_pack_entry(sha1, e, p->item)) {
-                       mru_mark(packed_git_mru, p);
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-struct packed_git *find_sha1_pack(const unsigned char *sha1,
-                                 struct packed_git *packs)
-{
-       struct packed_git *p;
-
-       for (p = packs; p; p = p->next) {
-               if (find_pack_entry_one(sha1, p))
-                       return p;
-       }
-       return NULL;
-
-}
-
 static int sha1_loose_object_info(const unsigned char *sha1,
                                  struct object_info *oi,
                                  int flags)
@@ -1753,7 +1581,7 @@ int write_sha1_file(const void *buf, unsigned long len, const char *type, unsign
 }
 
 int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type,
-                            unsigned char *sha1, unsigned flags)
+                            struct object_id *oid, unsigned flags)
 {
        char *header;
        int hdrlen, status = 0;
@@ -1761,13 +1589,13 @@ int hash_sha1_file_literally(const void *buf, unsigned long len, const char *typ
        /* type string, SP, %lu of the length plus NUL must fit this */
        hdrlen = strlen(type) + 32;
        header = xmalloc(hdrlen);
-       write_sha1_file_prepare(buf, len, type, sha1, header, &hdrlen);
+       write_sha1_file_prepare(buf, len, type, oid->hash, header, &hdrlen);
 
        if (!(flags & HASH_WRITE_OBJECT))
                goto cleanup;
-       if (freshen_packed_object(sha1) || freshen_loose_object(sha1))
+       if (freshen_packed_object(oid->hash) || freshen_loose_object(oid->hash))
                goto cleanup;
-       status = write_loose_object(sha1, header, hdrlen, buf, len, 0);
+       status = write_loose_object(oid->hash, header, hdrlen, buf, len, 0);
 
 cleanup:
        free(header);
@@ -1795,20 +1623,6 @@ int force_object_loose(const unsigned char *sha1, time_t mtime)
        return ret;
 }
 
-int has_pack_index(const unsigned char *sha1)
-{
-       struct stat st;
-       if (stat(sha1_pack_index_name(sha1), &st))
-               return 0;
-       return 1;
-}
-
-int has_sha1_pack(const unsigned char *sha1)
-{
-       struct pack_entry e;
-       return find_pack_entry(sha1, &e);
-}
-
 int has_sha1_file_with_flags(const unsigned char *sha1, int flags)
 {
        if (!startup_info->have_repository)
@@ -1971,14 +1785,14 @@ static int index_core(unsigned char *sha1, int fd, size_t size,
  * binary blobs, they generally do not want to get any conversion, and
  * callers should avoid this code path when filters are requested.
  */
-static int index_stream(unsigned char *sha1, int fd, size_t size,
+static int index_stream(struct object_id *oid, int fd, size_t size,
                        enum object_type type, const char *path,
                        unsigned flags)
 {
-       return index_bulk_checkin(sha1, fd, size, type, path, flags);
+       return index_bulk_checkin(oid->hash, fd, size, type, path, flags);
 }
 
-int index_fd(unsigned char *sha1, int fd, struct stat *st,
+int index_fd(struct object_id *oid, int fd, struct stat *st,
             enum object_type type, const char *path, unsigned flags)
 {
        int ret;
@@ -1988,21 +1802,21 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st,
         * die() for large files.
         */
        if (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(path))
-               ret = index_stream_convert_blob(sha1, fd, path, flags);
+               ret = index_stream_convert_blob(oid->hash, fd, path, flags);
        else if (!S_ISREG(st->st_mode))
-               ret = index_pipe(sha1, fd, type, path, flags);
+               ret = index_pipe(oid->hash, fd, type, path, flags);
        else if (st->st_size <= big_file_threshold || type != OBJ_BLOB ||
                 (path && would_convert_to_git(&the_index, path)))
-               ret = index_core(sha1, fd, xsize_t(st->st_size), type, path,
+               ret = index_core(oid->hash, fd, xsize_t(st->st_size), type, path,
                                 flags);
        else
-               ret = index_stream(sha1, fd, xsize_t(st->st_size), type, path,
+               ret = index_stream(oid, fd, xsize_t(st->st_size), type, path,
                                   flags);
        close(fd);
        return ret;
 }
 
-int index_path(unsigned char *sha1, const char *path, struct stat *st, unsigned flags)
+int index_path(struct object_id *oid, const char *path, struct stat *st, unsigned flags)
 {
        int fd;
        struct strbuf sb = STRBUF_INIT;
@@ -2012,7 +1826,7 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, unsigned
                fd = open(path, O_RDONLY);
                if (fd < 0)
                        return error_errno("open(\"%s\")", path);
-               if (index_fd(sha1, fd, st, OBJ_BLOB, path, flags) < 0)
+               if (index_fd(oid, fd, st, OBJ_BLOB, path, flags) < 0)
                        return error("%s: failed to insert into database",
                                     path);
                break;
@@ -2020,14 +1834,14 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, unsigned
                if (strbuf_readlink(&sb, path, st->st_size))
                        return error_errno("readlink(\"%s\")", path);
                if (!(flags & HASH_WRITE_OBJECT))
-                       hash_sha1_file(sb.buf, sb.len, blob_type, sha1);
-               else if (write_sha1_file(sb.buf, sb.len, blob_type, sha1))
+                       hash_sha1_file(sb.buf, sb.len, blob_type, oid->hash);
+               else if (write_sha1_file(sb.buf, sb.len, blob_type, oid->hash))
                        return error("%s: failed to insert into database",
                                     path);
                strbuf_release(&sb);
                break;
        case S_IFDIR:
-               return resolve_gitlink_ref(path, "HEAD", sha1);
+               return resolve_gitlink_ref(path, "HEAD", oid->hash);
        default:
                return error("%s: unsupported file type", path);
        }
@@ -2201,46 +2015,6 @@ int for_each_loose_object(each_loose_object_fn cb, void *data, unsigned flags)
        return foreach_alt_odb(loose_from_alt_odb, &alt);
 }
 
-static int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn cb, void *data)
-{
-       uint32_t i;
-       int r = 0;
-
-       for (i = 0; i < p->num_objects; i++) {
-               struct object_id oid;
-
-               if (!nth_packed_object_oid(&oid, p, i))
-                       return error("unable to get sha1 of object %u in %s",
-                                    i, p->pack_name);
-
-               r = cb(&oid, p, i, data);
-               if (r)
-                       break;
-       }
-       return r;
-}
-
-int for_each_packed_object(each_packed_object_fn cb, void *data, unsigned flags)
-{
-       struct packed_git *p;
-       int r = 0;
-       int pack_errors = 0;
-
-       prepare_packed_git();
-       for (p = packed_git; p; p = p->next) {
-               if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
-                       continue;
-               if (open_pack_index(p)) {
-                       pack_errors = 1;
-                       continue;
-               }
-               r = for_each_object_in_pack(p, cb, data);
-               if (r)
-                       break;
-       }
-       return r ? r : pack_errors;
-}
-
 static int check_stream_sha1(git_zstream *stream,
                             const char *hdr,
                             unsigned long size,