sha1_file.c: move delayed getenv(altdb) back to setup_git_env()
[gitweb.git] / sha1_file.c
index 3da70ac650a8cdeca6ef8a6a424a7740d38267d5..4af422e3cfe29c45816632a005510b0e71864eff 100644 (file)
 #include "bulk-checkin.h"
 #include "streaming.h"
 #include "dir.h"
-#include "mru.h"
 #include "list.h"
 #include "mergesort.h"
 #include "quote.h"
 #include "packfile.h"
+#include "fetch-object.h"
 
 const unsigned char null_sha1[GIT_MAX_RAWSZ];
 const struct object_id null_oid;
@@ -133,14 +133,14 @@ static struct cached_object *find_cached_object(const unsigned char *sha1)
 }
 
 
-static enum safe_crlf get_safe_crlf(unsigned flags)
+static int get_conv_flags(unsigned flags)
 {
        if (flags & HASH_RENORMALIZE)
-               return SAFE_CRLF_RENORMALIZE;
+               return CONV_EOL_RENORMALIZE;
        else if (flags & HASH_WRITE_OBJECT)
-               return safe_crlf;
+         return global_conv_flags_eol;
        else
-               return SAFE_CRLF_FALSE;
+               return 0;
 }
 
 
@@ -321,15 +321,11 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)
        }
 }
 
-const char *sha1_file_name(const unsigned char *sha1)
+void sha1_file_name(struct strbuf *buf, const unsigned char *sha1)
 {
-       static struct strbuf buf = STRBUF_INIT;
-
-       strbuf_reset(&buf);
-       strbuf_addf(&buf, "%s/", get_object_directory());
-
-       fill_sha1_path(&buf, sha1);
-       return buf.buf;
+       strbuf_addstr(buf, get_object_directory());
+       strbuf_addch(buf, '/');
+       fill_sha1_path(buf, sha1);
 }
 
 struct strbuf *alt_scratch_buf(struct alternate_object_database *alt)
@@ -671,15 +667,11 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
 
 void prepare_alt_odb(void)
 {
-       const char *alt;
-
        if (alt_odb_tail)
                return;
 
-       alt = getenv(ALTERNATE_DB_ENVIRONMENT);
-
        alt_odb_tail = &alt_odb_list;
-       link_alt_odb_entries(alt, PATH_SEP, NULL, 0);
+       link_alt_odb_entries(the_repository->alternate_db, PATH_SEP, NULL, 0);
 
        read_info_alternates(get_object_directory(), 0);
 }
@@ -710,7 +702,12 @@ int check_and_freshen_file(const char *fn, int freshen)
 
 static int check_and_freshen_local(const unsigned char *sha1, int freshen)
 {
-       return check_and_freshen_file(sha1_file_name(sha1), freshen);
+       static struct strbuf buf = STRBUF_INIT;
+
+       strbuf_reset(&buf);
+       sha1_file_name(&buf, sha1);
+
+       return check_and_freshen_file(buf.buf, freshen);
 }
 
 static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen)
@@ -866,8 +863,12 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st,
                          const char **path)
 {
        struct alternate_object_database *alt;
+       static struct strbuf buf = STRBUF_INIT;
+
+       strbuf_reset(&buf);
+       sha1_file_name(&buf, sha1);
+       *path = buf.buf;
 
-       *path = sha1_file_name(sha1);
        if (!lstat(*path, st))
                return 0;
 
@@ -891,8 +892,12 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)
        int fd;
        struct alternate_object_database *alt;
        int most_interesting_errno;
+       static struct strbuf buf = STRBUF_INIT;
+
+       strbuf_reset(&buf);
+       sha1_file_name(&buf, sha1);
+       *path = buf.buf;
 
-       *path = sha1_file_name(sha1);
        fd = git_open(*path);
        if (fd >= 0)
                return fd;
@@ -1213,6 +1218,8 @@ static int sha1_loose_object_info(const unsigned char *sha1,
        return (status < 0) ? status : 0;
 }
 
+int fetch_if_missing = 1;
+
 int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, unsigned flags)
 {
        static struct object_info blank_oi = OBJECT_INFO_INIT;
@@ -1221,6 +1228,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
        const unsigned char *real = (flags & OBJECT_INFO_LOOKUP_REPLACE) ?
                                    lookup_replace_object(sha1) :
                                    sha1;
+       int already_retried = 0;
 
        if (is_null_sha1(real))
                return -1;
@@ -1248,19 +1256,32 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
                }
        }
 
-       if (!find_pack_entry(real, &e)) {
+       while (1) {
+               if (find_pack_entry(real, &e))
+                       break;
+
                /* Most likely it's a loose object. */
                if (!sha1_loose_object_info(real, oi, flags))
                        return 0;
 
                /* Not a loose object; someone else may have just packed it. */
-               if (flags & OBJECT_INFO_QUICK) {
-                       return -1;
-               } else {
-                       reprepare_packed_git();
-                       if (!find_pack_entry(real, &e))
-                               return -1;
+               reprepare_packed_git();
+               if (find_pack_entry(real, &e))
+                       break;
+
+               /* Check if it is a missing object */
+               if (fetch_if_missing && repository_format_partial_clone &&
+                   !already_retried) {
+                       /*
+                        * TODO Investigate haveing fetch_object() return
+                        * TODO error/success and stopping the music here.
+                        */
+                       fetch_object(repository_format_partial_clone, real);
+                       already_retried = 1;
+                       continue;
                }
+
+               return -1;
        }
 
        if (oi == &blank_oi)
@@ -1269,7 +1290,6 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
                 * information below, so return early.
                 */
                return 0;
-
        rtype = packed_object_info(e.p, e.offset, oi);
        if (rtype < 0) {
                mark_bad_packed_object(e.p, real);
@@ -1557,9 +1577,12 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
        git_SHA_CTX c;
        unsigned char parano_sha1[20];
        static struct strbuf tmp_file = STRBUF_INIT;
-       const char *filename = sha1_file_name(sha1);
+       static struct strbuf filename = STRBUF_INIT;
+
+       strbuf_reset(&filename);
+       sha1_file_name(&filename, sha1);
 
-       fd = create_tmpfile(&tmp_file, filename);
+       fd = create_tmpfile(&tmp_file, filename.buf);
        if (fd < 0) {
                if (errno == EACCES)
                        return error("insufficient permission for adding an object to repository database %s", get_object_directory());
@@ -1612,7 +1635,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
                        warning_errno("failed utime() on %s", tmp_file.buf);
        }
 
-       return finalize_object_file(tmp_file.buf, filename);
+       return finalize_object_file(tmp_file.buf, filename.buf);
 }
 
 static int freshen_loose_object(const unsigned char *sha1)
@@ -1752,7 +1775,7 @@ static int index_mem(struct object_id *oid, void *buf, size_t size,
        if ((type == OBJ_BLOB) && path) {
                struct strbuf nbuf = STRBUF_INIT;
                if (convert_to_git(&the_index, path, buf, size, &nbuf,
-                                  get_safe_crlf(flags))) {
+                                  get_conv_flags(flags))) {
                        buf = strbuf_detach(&nbuf, &size);
                        re_allocated = 1;
                }
@@ -1786,7 +1809,7 @@ static int index_stream_convert_blob(struct object_id *oid, int fd,
        assert(would_convert_to_git_filter_fd(path));
 
        convert_to_git_filter_fd(&the_index, path, fd, &sbuf,
-                                get_safe_crlf(flags));
+                                get_conv_flags(flags));
 
        if (write_object)
                ret = write_sha1_file(sbuf.buf, sbuf.len, typename(OBJ_BLOB),