fetch: add test to make sure we stay backwards compatible
[gitweb.git] / sha1_file.c
index 7c81790759765373b0d0daf0828df5ec63769e0b..09ad64ce555e0b908ce0d9f22219026a2d37ae0c 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
@@ -398,7 +398,7 @@ static const char *parse_alt_odb_entry(const char *string,
        return end;
 }
 
-static void link_alt_odb_entries(const char *alt, int len, int sep,
+static void link_alt_odb_entries(const char *alt, int sep,
                                 const char *relative_base, int depth)
 {
        struct strbuf objdirbuf = STRBUF_INIT;
@@ -427,28 +427,19 @@ static void link_alt_odb_entries(const char *alt, int len, int sep,
 
 static void read_info_alternates(const char * relative_base, int depth)
 {
-       char *map;
-       size_t mapsz;
-       struct stat st;
        char *path;
-       int fd;
+       struct strbuf buf = STRBUF_INIT;
 
        path = xstrfmt("%s/info/alternates", relative_base);
-       fd = git_open(path);
-       free(path);
-       if (fd < 0)
-               return;
-       if (fstat(fd, &st) || (st.st_size == 0)) {
-               close(fd);
+       if (strbuf_read_file(&buf, path, 1024) < 0) {
+               warn_on_fopen_errors(path);
+               free(path);
                return;
        }
-       mapsz = xsize_t(st.st_size);
-       map = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0);
-       close(fd);
-
-       link_alt_odb_entries(map, mapsz, '\n', relative_base, depth);
 
-       munmap(map, mapsz);
+       link_alt_odb_entries(buf.buf, '\n', relative_base, depth);
+       strbuf_release(&buf);
+       free(path);
 }
 
 struct alternate_object_database *alloc_alt_odb(const char *dir)
@@ -503,7 +494,7 @@ void add_to_alternates_file(const char *reference)
                if (commit_lock_file(lock))
                        die_errno("unable to move new alternates file into place");
                if (alt_odb_tail)
-                       link_alt_odb_entries(reference, strlen(reference), '\n', NULL, 0);
+                       link_alt_odb_entries(reference, '\n', NULL, 0);
        }
        free(alts);
 }
@@ -516,7 +507,7 @@ void add_to_alternates_memory(const char *reference)
         */
        prepare_alt_odb();
 
-       link_alt_odb_entries(reference, strlen(reference), '\n', NULL, 0);
+       link_alt_odb_entries(reference, '\n', NULL, 0);
 }
 
 /*
@@ -619,7 +610,7 @@ void prepare_alt_odb(void)
        if (!alt) alt = "";
 
        alt_odb_tail = &alt_odb_list;
-       link_alt_odb_entries(alt, strlen(alt), PATH_SEP, NULL, 0);
+       link_alt_odb_entries(alt, PATH_SEP, NULL, 0);
 
        read_info_alternates(get_object_directory(), 0);
 }
@@ -1581,7 +1572,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;
@@ -1589,13 +1580,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);
@@ -1757,10 +1748,15 @@ static int index_core(unsigned char *sha1, int fd, size_t size,
                ret = index_mem(sha1, "", size, type, path, flags);
        } else if (size <= SMALL_FILE_SIZE) {
                char *buf = xmalloc(size);
-               if (size == read_in_full(fd, buf, size))
-                       ret = index_mem(sha1, buf, size, type, path, flags);
+               ssize_t read_result = read_in_full(fd, buf, size);
+               if (read_result < 0)
+                       ret = error_errno("read error while indexing %s",
+                                         path ? path : "<unknown>");
+               else if (read_result != size)
+                       ret = error("short read while indexing %s",
+                                   path ? path : "<unknown>");
                else
-                       ret = error_errno("short read");
+                       ret = index_mem(sha1, buf, size, type, path, flags);
                free(buf);
        } else {
                void *buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
@@ -1785,14 +1781,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;
@@ -1802,31 +1798,32 @@ 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;
+       int rc = 0;
 
        switch (st->st_mode & S_IFMT) {
        case S_IFREG:
                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;
@@ -1834,23 +1831,22 @@ 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))
-                       return error("%s: failed to insert into database",
-                                    path);
+                       hash_sha1_file(sb.buf, sb.len, blob_type, oid->hash);
+               else if (write_sha1_file(sb.buf, sb.len, blob_type, oid->hash))
+                       rc = 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);
        }
-       return 0;
+       return rc;
 }
 
 int read_pack_header(int fd, struct pack_header *header)
 {
-       if (read_in_full(fd, header, sizeof(*header)) < sizeof(*header))
+       if (read_in_full(fd, header, sizeof(*header)) != sizeof(*header))
                /* "eof before pack header was fully read" */
                return PH_ERROR_EOF;
 
@@ -2015,46 +2011,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,