Code

rev-list documentation: clarify the two parts of history simplification
[git.git] / sha1_file.c
index 9ee1ed16ad2df8847bd5008a5d61c807c145357a..ab2b520f033c75e5e8d3434376a203add59559a4 100644 (file)
@@ -99,7 +99,11 @@ int safe_create_leading_directories(char *path)
                pos = strchr(pos, '/');
                if (!pos)
                        break;
-               *pos = 0;
+               while (*++pos == '/')
+                       ;
+               if (!*pos)
+                       break;
+               *--pos = '\0';
                if (!stat(path, &st)) {
                        /* path exists */
                        if (!S_ISDIR(st.st_mode)) {
@@ -250,7 +254,6 @@ static void read_info_alternates(const char * alternates, int depth);
  */
 static int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth)
 {
-       struct stat st;
        const char *objdir = get_object_directory();
        struct alternate_object_database *ent;
        struct alternate_object_database *alt;
@@ -281,7 +284,7 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative
        ent->base[pfxlen] = ent->base[entlen-1] = 0;
 
        /* Detect cases where alternate disappeared */
-       if (stat(ent->base, &st) || !S_ISDIR(st.st_mode)) {
+       if (!is_directory(ent->base)) {
                error("object directory %s does not exist; "
                      "check .git/objects/info/alternates.",
                      ent->base);
@@ -385,7 +388,7 @@ static void read_info_alternates(const char * relative_base, int depth)
 void add_to_alternates_file(const char *reference)
 {
        struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
-       int fd = hold_lock_file_for_append(lock, git_path("objects/info/alternates"), 1);
+       int fd = hold_lock_file_for_append(lock, git_path("objects/info/alternates"), LOCK_DIE_ON_ERROR);
        char *alt = mkpath("%s/objects\n", reference);
        write_or_die(fd, alt, strlen(alt));
        if (commit_lock_file(lock))
@@ -394,6 +397,16 @@ void add_to_alternates_file(const char *reference)
                link_alt_odb_entries(alt, alt + strlen(alt), '\n', NULL, 0);
 }
 
+void foreach_alt_odb(alt_odb_fn fn, void *cb)
+{
+       struct alternate_object_database *ent;
+
+       prepare_alt_odb();
+       for (ent = alt_odb_list; ent; ent = ent->next)
+               if (fn(ent, cb))
+                       return;
+}
+
 void prepare_alt_odb(void)
 {
        const char *alt;
@@ -1558,11 +1571,9 @@ static void *cache_or_unpack_entry(struct packed_git *p, off_t base_offset,
        struct delta_base_cache_entry *ent = delta_base_cache + hash;
 
        ret = ent->data;
-       if (ret && ent->p == p && ent->base_offset == base_offset)
-               goto found_cache_entry;
-       return unpack_entry(p, base_offset, type, base_size);
+       if (!ret || ent->p != p || ent->base_offset != base_offset)
+               return unpack_entry(p, base_offset, type, base_size);
 
-found_cache_entry:
        if (!keep_cache) {
                ent->data = NULL;
                ent->lru.next->prev = ent->lru.prev;
@@ -2119,16 +2130,16 @@ static void write_sha1_file_prepare(const void *buf, unsigned long len,
                                     const char *type, unsigned char *sha1,
                                     char *hdr, int *hdrlen)
 {
-       SHA_CTX c;
+       git_SHA_CTX c;
 
        /* Generate the header */
        *hdrlen = sprintf(hdr, "%s %lu", type, len)+1;
 
        /* Sha1.. */
-       SHA1_Init(&c);
-       SHA1_Update(&c, hdr, *hdrlen);
-       SHA1_Update(&c, buf, len);
-       SHA1_Final(sha1, &c);
+       git_SHA1_Init(&c);
+       git_SHA1_Update(&c, hdr, *hdrlen);
+       git_SHA1_Update(&c, buf, len);
+       git_SHA1_Final(sha1, &c);
 }
 
 /*
@@ -2136,7 +2147,9 @@ static void write_sha1_file_prepare(const void *buf, unsigned long len,
  */
 int move_temp_to_file(const char *tmpfile, const char *filename)
 {
-       int ret = link(tmpfile, filename);
+       int ret = 0;
+       if (link(tmpfile, filename))
+               ret = errno;
 
        /*
         * Coda hack - coda doesn't like cross-directory links,
@@ -2320,6 +2333,7 @@ int force_object_loose(const unsigned char *sha1, time_t mtime)
        enum object_type type;
        char hdr[32];
        int hdrlen;
+       int ret;
 
        if (has_loose_object(sha1))
                return 0;
@@ -2327,7 +2341,10 @@ int force_object_loose(const unsigned char *sha1, time_t mtime)
        if (!buf)
                return error("cannot read sha1_file for %s", sha1_to_hex(sha1));
        hdrlen = sprintf(hdr, "%s %lu", typename(type), len) + 1;
-       return write_loose_object(sha1, hdr, hdrlen, buf, len, mtime);
+       ret = write_loose_object(sha1, hdr, hdrlen, buf, len, mtime);
+       free(buf);
+
+       return ret;
 }
 
 int has_pack_index(const unsigned char *sha1)
@@ -2373,8 +2390,7 @@ static int index_mem(unsigned char *sha1, void *buf, size_t size,
         * Convert blobs to git internal format
         */
        if ((type == OBJ_BLOB) && path) {
-               struct strbuf nbuf;
-               strbuf_init(&nbuf, 0);
+               struct strbuf nbuf = STRBUF_INIT;
                if (convert_to_git(path, buf, size, &nbuf,
                                   write_object ? safe_crlf : 0)) {
                        buf = strbuf_detach(&nbuf, &size);
@@ -2398,8 +2414,7 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object,
        size_t size = xsize_t(st->st_size);
 
        if (!S_ISREG(st->st_mode)) {
-               struct strbuf sbuf;
-               strbuf_init(&sbuf, 0);
+               struct strbuf sbuf = STRBUF_INIT;
                if (strbuf_read(&sbuf, fd, 4096) >= 0)
                        ret = index_mem(sha1, sbuf.buf, sbuf.len, write_object,
                                        type, path);