aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2005-09-13 00:05:22 -0700
committerJunio C Hamano <junkio@cox.net>2005-09-13 13:39:23 -0700
commitccfd3e99621f489db4ea37a03be7674adbd03f6e (patch)
tree8ea9565ee2a7a9f08e56686963ee2b545c8f6afd
parenta5cd85e084458bf573d0d29fa79c4e1ad7973ed7 (diff)
downloadgit-ccfd3e99621f489db4ea37a03be7674adbd03f6e.tar.gz
git-ccfd3e99621f489db4ea37a03be7674adbd03f6e.tar.xz
[PATCH] Define relative .git/objects/info/alternates semantics.
An entry in the alternates file can name a directory relative to the object store it describes. A typical linux-2.6 maintainer repository would have "../../../torvalds/linux-2.6.git/objects" there, because the subsystem maintainer object store would live in /pub/scm/linux/kernel/git/$u/$system.git/objects/ and the object store of Linus tree is in /pub/scm/linux/kernel/git/torvalds/linux-2.6.git/objects/ This unfortunately is different from GIT_ALTERNATE_OBJECT_DIRECTORIES which is relative to the cwd of the running process, but there is no way to make it consistent with the behaviour of the environment variable. The process typically is run in $system.git/ directory for a naked repository, or one level up for a repository with a working tree, so we just define it to be relative to the objects/ directory to be different from either ;-). Later, the dumb transport could be updated to read from info/alternates and make requests for the repository the repository borrows from. Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r--sha1_file.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/sha1_file.c b/sha1_file.c
index f4c742eed..663820278 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -240,10 +240,12 @@ static struct alternate_object_database **alt_odb_tail;
* 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, int sep)
+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;
while (last < ep) {
@@ -261,12 +263,25 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep)
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;
@@ -288,12 +303,12 @@ void prepare_alt_odb(void)
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;
@@ -306,7 +321,8 @@ void prepare_alt_odb(void)
if (map == MAP_FAILED)
return;
- link_alt_odb_entries(map, map + st.st_size, '\n');
+ link_alt_odb_entries(map, map + st.st_size, '\n',
+ get_object_directory());
munmap(map, st.st_size);
}