Code

t/t4202-log.sh: Add testcases
[git.git] / sha1_file.c
index 6c0e251e02e20aed1eaa3bc1737e3e606cb4e23e..360f7e5a028b4842b152f1fcbd9f39f3a8623b5c 100644 (file)
@@ -672,6 +672,37 @@ void unuse_pack(struct pack_window **w_cursor)
        }
 }
 
+/*
+ * This is used by git-repack in case a newly created pack happens to
+ * contain the same set of objects as an existing one.  In that case
+ * the resulting file might be different even if its name would be the
+ * same.  It is best to close any reference to the old pack before it is
+ * replaced on disk.  Of course no index pointers nor windows for given pack
+ * must subsist at this point.  If ever objects from this pack are requested
+ * again, the new version of the pack will be reinitialized through
+ * reprepare_packed_git().
+ */
+void free_pack_by_name(const char *pack_name)
+{
+       struct packed_git *p, **pp = &packed_git;
+
+       while (*pp) {
+               p = *pp;
+               if (strcmp(pack_name, p->pack_name) == 0) {
+                       close_pack_windows(p);
+                       if (p->pack_fd != -1)
+                               close(p->pack_fd);
+                       if (p->index_data)
+                               munmap((void *)p->index_data, p->index_size);
+                       free(p->bad_object_sha1);
+                       *pp = p->next;
+                       free(p);
+                       return;
+               }
+               pp = &p->next;
+       }
+}
+
 /*
  * Do not call this directly as this leaks p->pack_fd on error return;
  * call open_packed_git() instead.
@@ -1165,8 +1196,8 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
        stream->avail_out = bufsiz;
 
        if (legacy_loose_object(map)) {
-               inflateInit(stream);
-               return inflate(stream, 0);
+               git_inflate_init(stream);
+               return git_inflate(stream, 0);
        }
 
 
@@ -1186,7 +1217,7 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
        /* Set up the stream for the rest.. */
        stream->next_in = map;
        stream->avail_in = mapsize;
-       inflateInit(stream);
+       git_inflate_init(stream);
 
        /* And generate the fake traditional header */
        stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",
@@ -1223,11 +1254,11 @@ static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size
                stream->next_out = buf + bytes;
                stream->avail_out = size - bytes;
                while (status == Z_OK)
-                       status = inflate(stream, Z_FINISH);
+                       status = git_inflate(stream, Z_FINISH);
        }
        buf[size] = 0;
        if (status == Z_STREAM_END && !stream->avail_in) {
-               inflateEnd(stream);
+               git_inflate_end(stream);
                return buf;
        }
 
@@ -1317,15 +1348,15 @@ unsigned long get_size_from_delta(struct packed_git *p,
        stream.next_out = delta_head;
        stream.avail_out = sizeof(delta_head);
 
-       inflateInit(&stream);
+       git_inflate_init(&stream);
        do {
                in = use_pack(p, w_curs, curpos, &stream.avail_in);
                stream.next_in = in;
-               st = inflate(&stream, Z_FINISH);
+               st = git_inflate(&stream, Z_FINISH);
                curpos += stream.next_in - in;
        } while ((st == Z_OK || st == Z_BUF_ERROR) &&
                 stream.total_out < sizeof(delta_head));
-       inflateEnd(&stream);
+       git_inflate_end(&stream);
        if ((st != Z_STREAM_END) && stream.total_out != sizeof(delta_head)) {
                error("delta data unpack-initial failed");
                return 0;
@@ -1554,14 +1585,14 @@ static void *unpack_compressed_entry(struct packed_git *p,
        stream.next_out = buffer;
        stream.avail_out = size;
 
-       inflateInit(&stream);
+       git_inflate_init(&stream);
        do {
                in = use_pack(p, w_curs, curpos, &stream.avail_in);
                stream.next_in = in;
-               st = inflate(&stream, Z_FINISH);
+               st = git_inflate(&stream, Z_FINISH);
                curpos += stream.next_in - in;
        } while (st == Z_OK || st == Z_BUF_ERROR);
-       inflateEnd(&stream);
+       git_inflate_end(&stream);
        if ((st != Z_STREAM_END) || stream.total_out != size) {
                free(buffer);
                return NULL;
@@ -1669,6 +1700,9 @@ static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
        delta_base_cache_lru.prev = &ent->lru;
 }
 
+static void *read_object(const unsigned char *sha1, enum object_type *type,
+                        unsigned long *size);
+
 static void *unpack_delta_entry(struct packed_git *p,
                                struct pack_window **w_curs,
                                off_t curpos,
@@ -1986,7 +2020,7 @@ static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *size
                status = error("unable to parse %s header", sha1_to_hex(sha1));
        else if (sizep)
                *sizep = size;
-       inflateEnd(&stream);
+       git_inflate_end(&stream);
        munmap(map, mapsize);
        return status;
 }
@@ -2099,8 +2133,8 @@ int pretend_sha1_file(void *buf, unsigned long len, enum object_type type,
        return 0;
 }
 
-void *read_object(const unsigned char *sha1, enum object_type *type,
-                 unsigned long *size)
+static void *read_object(const unsigned char *sha1, enum object_type *type,
+                        unsigned long *size)
 {
        unsigned long mapsize;
        void *map, *buf;
@@ -2492,8 +2526,7 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object,
 int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object)
 {
        int fd;
-       char *target;
-       size_t len;
+       struct strbuf sb = STRBUF_INIT;
 
        switch (st->st_mode & S_IFMT) {
        case S_IFREG:
@@ -2506,20 +2539,17 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, int write
                                     path);
                break;
        case S_IFLNK:
-               len = xsize_t(st->st_size);
-               target = xmalloc(len + 1);
-               if (readlink(path, target, len + 1) != st->st_size) {
+               if (strbuf_readlink(&sb, path, st->st_size)) {
                        char *errstr = strerror(errno);
-                       free(target);
                        return error("readlink(\"%s\"): %s", path,
                                     errstr);
                }
                if (!write_object)
-                       hash_sha1_file(target, len, blob_type, sha1);
-               else if (write_sha1_file(target, len, blob_type, sha1))
+                       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);
-               free(target);
+               strbuf_release(&sb);
                break;
        case S_IFDIR:
                return resolve_gitlink_ref(path, "HEAD", sha1);