Skip to content

Commit 1494e03

Browse files
author
Junio C Hamano
committed
sha1_file.c: make sure packs in an alternate odb is named properly.
We somehow ended up registering packs in alternate object directories as "dir/object//pack/pack-*", which confusd the update-server-info code very badly. Also we did not attempt to detect a mistake of listing the object directory itself as one of the alternates. This does not lead to incorrect behaviour, but is simply wasteful, so try to do so when we are trivially able to. Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent b270c63 commit 1494e03

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

sha1_file.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,8 @@ static struct alternate_object_database **alt_odb_tail;
184184
* alternate_object_database. The elements on this list come from
185185
* non-empty elements from colon separated ALTERNATE_DB_ENVIRONMENT
186186
* environment variable, and $GIT_OBJECT_DIRECTORY/info/alternates,
187-
* whose contents is exactly in the same format as that environment
188-
* variable. Its base points at a statically allocated buffer that
187+
* whose contents is similar to that environment variable but can be
188+
* LF separated. Its base points at a statically allocated buffer that
189189
* contains "/the/directory/corresponding/to/.git/objects/...", while
190190
* its name points just after the slash at the end of ".git/objects/"
191191
* in the example above, and has enough space to hold 40-byte hex
@@ -197,6 +197,7 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep,
197197
{
198198
const char *cp, *last;
199199
struct alternate_object_database *ent;
200+
const char *objdir = get_object_directory();
200201
int base_len = -1;
201202

202203
last = alt;
@@ -211,6 +212,7 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep,
211212
for ( ; cp < ep && *cp != sep; cp++)
212213
;
213214
if (last != cp) {
215+
struct alternate_object_database *alt;
214216
/* 43 = 40-byte + 2 '/' + terminating NUL */
215217
int pfxlen = cp - last;
216218
int entlen = pfxlen + 43;
@@ -223,9 +225,7 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep,
223225
pfxlen += base_len;
224226
}
225227
ent = xmalloc(sizeof(*ent) + entlen);
226-
*alt_odb_tail = ent;
227-
alt_odb_tail = &(ent->next);
228-
ent->next = NULL;
228+
229229
if (*last != '/' && relative_base) {
230230
memcpy(ent->base, relative_base, base_len - 1);
231231
ent->base[base_len - 1] = '/';
@@ -237,6 +237,22 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep,
237237
ent->name = ent->base + pfxlen + 1;
238238
ent->base[pfxlen] = ent->base[pfxlen + 3] = '/';
239239
ent->base[entlen-1] = 0;
240+
241+
/* Prevent the common mistake of listing the same
242+
* thing twice, or object directory itself.
243+
*/
244+
for (alt = alt_odb_list; alt; alt = alt->next)
245+
if (!memcmp(ent->base, alt->base, pfxlen))
246+
goto bad;
247+
if (!memcmp(ent->base, objdir, pfxlen)) {
248+
bad:
249+
free(ent);
250+
}
251+
else {
252+
*alt_odb_tail = ent;
253+
alt_odb_tail = &(ent->next);
254+
ent->next = NULL;
255+
}
240256
}
241257
while (cp < ep && *cp == sep)
242258
cp++;
@@ -531,8 +547,9 @@ void prepare_packed_git(void)
531547
prepare_packed_git_one(get_object_directory(), 1);
532548
prepare_alt_odb();
533549
for (alt = alt_odb_list; alt; alt = alt->next) {
534-
alt->name[0] = 0;
550+
alt->name[-1] = 0;
535551
prepare_packed_git_one(alt->base, 0);
552+
alt->name[-1] = '/';
536553
}
537554
run_once = 1;
538555
}

0 commit comments

Comments
 (0)