#endif
#endif
+const unsigned char null_sha1[20] = { 0, };
+
static unsigned int sha1_file_open_flag = O_NOATIME;
static unsigned hexval(char c)
*git_graft_file;
static void setup_git_env(void)
{
- git_dir = gitenv(GIT_DIR_ENVIRONMENT);
+ git_dir = getenv(GIT_DIR_ENVIRONMENT);
if (!git_dir)
git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
- git_object_dir = gitenv(DB_ENVIRONMENT);
+ git_object_dir = getenv(DB_ENVIRONMENT);
if (!git_object_dir) {
git_object_dir = xmalloc(strlen(git_dir) + 9);
sprintf(git_object_dir, "%s/objects", git_dir);
}
git_refs_dir = xmalloc(strlen(git_dir) + 6);
sprintf(git_refs_dir, "%s/refs", git_dir);
- git_index_file = gitenv(INDEX_ENVIRONMENT);
+ git_index_file = getenv(INDEX_ENVIRONMENT);
if (!git_index_file) {
git_index_file = xmalloc(strlen(git_dir) + 7);
sprintf(git_index_file, "%s/index", git_dir);
}
- git_graft_file = gitenv(GRAFT_ENVIRONMENT);
+ git_graft_file = getenv(GRAFT_ENVIRONMENT);
if (!git_graft_file)
git_graft_file = strdup(git_path("info/grafts"));
}
+char *get_git_dir(void)
+{
+ if (!git_dir)
+ setup_git_env();
+ return git_dir;
+}
+
char *get_object_directory(void)
{
if (!git_object_dir)
* SHA1, an extra slash for the first level indirection, and the
* terminating NUL.
*/
-static void link_alt_odb_entries(const char *alt, const char *ep)
+static void link_alt_odb_entries(const char *alt, const char *ep, int sep,
+ const char *relative_base)
{
const char *cp, *last;
struct alternate_object_database *ent;
+ int base_len = -1;
last = alt;
- do {
- for (cp = last; cp < ep && *cp != ':'; cp++)
+ while (last < ep) {
+ cp = last;
+ if (cp < ep && *cp == '#') {
+ while (cp < ep && *cp != sep)
+ cp++;
+ last = cp + 1;
+ continue;
+ }
+ for ( ; cp < ep && *cp != sep; cp++)
;
if (last != cp) {
/* 43 = 40-byte + 2 '/' + terminating NUL */
int pfxlen = cp - last;
int entlen = pfxlen + 43;
+ if (*last != '/' && relative_base) {
+ /* Relative alt-odb */
+ if (base_len < 0)
+ base_len = strlen(relative_base) + 1;
+ entlen += base_len;
+ pfxlen += base_len;
+ }
ent = xmalloc(sizeof(*ent) + entlen);
*alt_odb_tail = ent;
alt_odb_tail = &(ent->next);
ent->next = NULL;
-
- memcpy(ent->base, last, pfxlen);
+ if (*last != '/' && relative_base) {
+ memcpy(ent->base, relative_base, base_len - 1);
+ ent->base[base_len - 1] = '/';
+ memcpy(ent->base + base_len,
+ last, cp - last);
+ }
+ else
+ memcpy(ent->base, last, pfxlen);
ent->name = ent->base + pfxlen + 1;
ent->base[pfxlen] = ent->base[pfxlen + 3] = '/';
ent->base[entlen-1] = 0;
}
- while (cp < ep && *cp == ':')
+ while (cp < ep && *cp == sep)
cp++;
last = cp;
- } while (cp < ep);
+ }
}
void prepare_alt_odb(void)
{
char path[PATH_MAX];
- char *map, *ep;
+ char *map;
int fd;
struct stat st;
- char *alt = gitenv(ALTERNATE_DB_ENVIRONMENT) ? : "";
+ char *alt;
+
+ alt = getenv(ALTERNATE_DB_ENVIRONMENT);
+ if (!alt) alt = "";
- sprintf(path, "%s/info/alternates", get_object_directory());
if (alt_odb_tail)
return;
alt_odb_tail = &alt_odb_list;
- link_alt_odb_entries(alt, alt + strlen(alt));
+ link_alt_odb_entries(alt, alt + strlen(alt), ':', NULL);
+ sprintf(path, "%s/info/alternates", get_object_directory());
fd = open(path, O_RDONLY);
if (fd < 0)
return;
if (map == MAP_FAILED)
return;
- /* Remove the trailing newline */
- for (ep = map + st.st_size - 1; map < ep && ep[-1] == '\n'; ep--)
- ;
- link_alt_odb_entries(map, ep);
+ link_alt_odb_entries(map, map + st.st_size, '\n',
+ get_object_directory());
munmap(map, st.st_size);
}
return parse_pack_index_file(sha1, path);
}
-struct packed_git *parse_pack_index_file(unsigned char *sha1, char *idx_path)
+struct packed_git *parse_pack_index_file(const unsigned char *sha1, char *idx_path)
{
struct packed_git *p;
unsigned long idx_size;
strcpy(type, "tag");
break;
default:
- die("corrupted pack file");
+ die("corrupted pack file %s containing object of kind %d",
+ p->pack_name, kind);
}
*store_size = 0; /* notyet */
}
strcpy(type, "tag");
break;
default:
- die("corrupted pack file");
+ die("corrupted pack file %s containing object of kind %d",
+ p->pack_name, kind);
}
if (sizep)
*sizep = size;
retval = unpack_entry_gently(entry, type, sizep);
unuse_packed_git(p);
if (!retval)
- die("corrupted pack file");
+ die("corrupted pack file %s", p->pack_name);
return retval;
}