git-merge: fix confusion between tag and branch
[gitweb.git] / sha1_file.c
index 4e5ee1054f6a4f5d1f50c8f93a3f45d6a6b1c72a..63f416bb5a900210d6b3ab15bb4ffe1e16244b9a 100644 (file)
@@ -663,7 +663,7 @@ void prepare_packed_git(void)
        prepare_packed_git_run_once = 1;
 }
 
-static void reprepare_packed_git(void)
+void reprepare_packed_git(void)
 {
        prepare_packed_git_run_once = 0;
        prepare_packed_git();
@@ -1203,6 +1203,24 @@ unsigned long find_pack_entry_one(const unsigned char *sha1,
        return 0;
 }
 
+static int matches_pack_name(struct packed_git *p, const char *ig)
+{
+       const char *last_c, *c;
+
+       if (!strcmp(p->pack_name, ig))
+               return 0;
+
+       for (c = p->pack_name, last_c = c; *c;)
+               if (*c == '/')
+                       last_c = ++c;
+               else
+                       ++c;
+       if (!strcmp(last_c, ig))
+               return 0;
+
+       return 1;
+}
+
 static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, const char **ignore_packed)
 {
        struct packed_git *p;
@@ -1214,7 +1232,7 @@ static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, cons
                if (ignore_packed) {
                        const char **ig;
                        for (ig = ignore_packed; *ig; ig++)
-                               if (!strcmp(p->pack_name, *ig))
+                               if (!matches_pack_name(p, *ig))
                                        break;
                        if (*ig)
                                continue;
@@ -1243,7 +1261,7 @@ struct packed_git *find_sha1_pack(const unsigned char *sha1,
        
 }
 
-int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep)
+static int sha1_loose_object_info(const unsigned char *sha1, char *type, unsigned long *sizep)
 {
        int status;
        unsigned long mapsize, size;
@@ -1252,20 +1270,8 @@ int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep
        char hdr[128];
 
        map = map_sha1_file(sha1, &mapsize);
-       if (!map) {
-               struct pack_entry e;
-
-               if (!find_pack_entry(sha1, &e, NULL)) {
-                       reprepare_packed_git();
-                       if (!find_pack_entry(sha1, &e, NULL))
-                               return error("unable to find %s", sha1_to_hex(sha1));
-               }
-               if (use_packed_git(e.p))
-                       die("cannot map packed file");
-               status = packed_object_info(e.p, e.offset, type, sizep);
-               unuse_packed_git(e.p);
-               return status;
-       }
+       if (!map)
+               return error("unable to find %s", sha1_to_hex(sha1));
        if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0)
                status = error("unable to unpack %s header",
                               sha1_to_hex(sha1));
@@ -1281,6 +1287,23 @@ int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep
        return status;
 }
 
+int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep)
+{
+       int status;
+       struct pack_entry e;
+
+       if (!find_pack_entry(sha1, &e, NULL)) {
+               reprepare_packed_git();
+               if (!find_pack_entry(sha1, &e, NULL))
+                       return sha1_loose_object_info(sha1, type, sizep);
+       }
+       if (use_packed_git(e.p))
+               die("cannot map packed file");
+       status = packed_object_info(e.p, e.offset, type, sizep);
+       unuse_packed_git(e.p);
+       return status;
+}
+
 static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned long *size)
 {
        struct pack_entry e;
@@ -1437,8 +1460,7 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
        unlink(tmpfile);
        if (ret) {
                if (ret != EEXIST) {
-                       fprintf(stderr, "unable to write sha1 filename %s: %s\n", filename, strerror(ret));
-                       return -1;
+                       return error("unable to write sha1 filename %s: %s\n", filename, strerror(ret));
                }
                /* FIXME!!! Collision check here ? */
        }
@@ -1548,16 +1570,17 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha
        }
 
        if (errno != ENOENT) {
-               fprintf(stderr, "sha1 file %s: %s\n", filename, strerror(errno));
-               return -1;
+               return error("sha1 file %s: %s\n", filename, strerror(errno));
        }
 
        snprintf(tmpfile, sizeof(tmpfile), "%s/obj_XXXXXX", get_object_directory());
 
        fd = mkstemp(tmpfile);
        if (fd < 0) {
-               fprintf(stderr, "unable to create temporary sha1 filename %s: %s\n", tmpfile, strerror(errno));
-               return -1;
+               if (errno == EPERM)
+                       return error("insufficient permission for adding an object to repository database %s\n", get_object_directory());
+               else
+                       return error("unable to create temporary sha1 filename %s: %s\n", tmpfile, strerror(errno));
        }
 
        /* Set it up */
@@ -1672,9 +1695,12 @@ int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
        snprintf(tmpfile, sizeof(tmpfile), "%s/obj_XXXXXX", get_object_directory());
 
        local = mkstemp(tmpfile);
-       if (local < 0)
-               return error("Couldn't open %s for %s",
-                            tmpfile, sha1_to_hex(sha1));
+       if (local < 0) {
+               if (errno == EPERM)
+                       return error("insufficient permission for adding an object to repository database %s\n", get_object_directory());
+               else
+                       return error("unable to create temporary sha1 filename %s: %s\n", tmpfile, strerror(errno));
+       }
 
        memset(&stream, 0, sizeof(stream));