Code

Merge branch 'jc/describe-always'
[git.git] / sha1_file.c
index b0c24356ae7358561300c9bb3a3f56ba502b2a3b..445a871db31673af20017d36ff22fd106f77f510 100644 (file)
@@ -14,6 +14,7 @@
 #include "tag.h"
 #include "tree.h"
 #include "refs.h"
+#include "pack-revindex.h"
 
 #ifndef O_NOATIME
 #if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
@@ -148,7 +149,7 @@ static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)
 
 /*
  * NOTE! This returns a statically allocated buffer, so you have to be
- * careful about using it. Do a "xstrdup()" if you need to save the
+ * careful about using it. Do an "xstrdup()" if you need to save the
  * filename.
  *
  * Also note that this returns the location for creating.  Reading
@@ -611,6 +612,22 @@ void release_pack_memory(size_t need, int fd)
                ; /* nothing */
 }
 
+void close_pack_windows(struct packed_git *p)
+{
+       while (p->windows) {
+               struct pack_window *w = p->windows;
+
+               if (w->inuse_cnt)
+                       die("pack '%s' still has open windows to it",
+                           p->pack_name);
+               munmap(w->base, w->len);
+               pack_mapped -= w->len;
+               pack_open_windows--;
+               p->windows = w->next;
+               free(w);
+       }
+}
+
 void unuse_pack(struct pack_window **w_cursor)
 {
        struct pack_window *w = *w_cursor;
@@ -1351,11 +1368,15 @@ const char *packed_object_info_detail(struct packed_git *p,
        unsigned long dummy;
        unsigned char *next_sha1;
        enum object_type type;
+       struct revindex_entry *revidx;
 
        *delta_chain_length = 0;
        curpos = obj_offset;
        type = unpack_object_header(p, &w_curs, &curpos, size);
 
+       revidx = find_pack_revindex(p, obj_offset);
+       *store_size = revidx[1].offset - obj_offset;
+
        for (;;) {
                switch (type) {
                default:
@@ -1365,14 +1386,13 @@ const char *packed_object_info_detail(struct packed_git *p,
                case OBJ_TREE:
                case OBJ_BLOB:
                case OBJ_TAG:
-                       *store_size = 0; /* notyet */
                        unuse_pack(&w_curs);
                        return typename(type);
                case OBJ_OFS_DELTA:
                        obj_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset);
                        if (*delta_chain_length == 0) {
-                               /* TODO: find base_sha1 as pointed by curpos */
-                               hashclr(base_sha1);
+                               revidx = find_pack_revindex(p, obj_offset);
+                               hashcpy(base_sha1, nth_packed_object_sha1(p, revidx->nr));
                        }
                        break;
                case OBJ_REF_DELTA:
@@ -1829,6 +1849,15 @@ static struct cached_object {
 } *cached_objects;
 static int cached_object_nr, cached_object_alloc;
 
+static struct cached_object empty_tree = {
+       /* empty tree sha1: 4b825dc642cb6eb9a060e54bf8d69288fbee4904 */
+       "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60"
+       "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04",
+       OBJ_TREE,
+       "",
+       0
+};
+
 static struct cached_object *find_cached_object(const unsigned char *sha1)
 {
        int i;
@@ -1838,6 +1867,8 @@ static struct cached_object *find_cached_object(const unsigned char *sha1)
                if (!hashcmp(co->sha1, sha1))
                        return co;
        }
+       if (!hashcmp(sha1, empty_tree.sha1))
+               return &empty_tree;
        return NULL;
 }
 
@@ -1927,7 +1958,8 @@ void *read_object_with_reference(const unsigned char *sha1,
                }
                ref_length = strlen(ref_type);
 
-               if (memcmp(buffer, ref_type, ref_length) ||
+               if (ref_length + 40 > isize ||
+                   memcmp(buffer, ref_type, ref_length) ||
                    get_sha1_hex((char *) buffer + ref_length, actual_sha1)) {
                        free(buffer);
                        return NULL;
@@ -2342,7 +2374,8 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object,
        if ((type == OBJ_BLOB) && S_ISREG(st->st_mode)) {
                struct strbuf nbuf;
                strbuf_init(&nbuf, 0);
-               if (convert_to_git(path, buf, size, &nbuf)) {
+               if (convert_to_git(path, buf, size, &nbuf,
+                                  write_object ? safe_crlf : 0)) {
                        munmap(buf, size);
                        buf = strbuf_detach(&nbuf, &size);
                        re_allocated = 1;