for ( ; cp < ep && *cp != sep; cp++)
;
if (last != cp) {
+ struct stat st;
struct alternate_object_database *alt;
/* 43 = 40-byte + 2 '/' + terminating NUL */
int pfxlen = 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;
+ ent->base[pfxlen + 3] = '/';
+ ent->base[pfxlen] = ent->base[entlen-1] = 0;
+
+ /* Detect cases where alternate disappeared */
+ if (stat(ent->base, &st) || !S_ISDIR(st.st_mode)) {
+ error("object directory %s does not exist; "
+ "check .git/objects/info/alternates.",
+ ent->base);
+ goto bad;
+ }
+ ent->base[pfxlen] = '/';
/* Prevent the common mistake of listing the same
* thing twice, or object directory itself.
sprintf(path, "%s/pack", objdir);
len = strlen(path);
dir = opendir(path);
- if (!dir)
+ if (!dir) {
+ if (errno != ENOENT)
+ error("unable to open object pack directory: %s: %s",
+ path, strerror(errno));
return;
+ }
path[len++] = '/';
while ((de = readdir(dir)) != NULL) {
int namelen = strlen(de->d_name);
if (left < 20)
die("truncated pack file");
+
+ /* The base entry _must_ be in the same pack */
+ if (!find_pack_entry_one(base_sha1, &base_ent, p))
+ die("failed to find delta-pack base object %s",
+ sha1_to_hex(base_sha1));
+ base = unpack_entry_gently(&base_ent, type, &base_size);
+ if (!base)
+ die("failed to read delta-pack base object %s",
+ sha1_to_hex(base_sha1));
+
data = base_sha1 + 20;
data_size = left - 20;
delta_data = xmalloc(delta_size);
if ((st != Z_STREAM_END) || stream.total_out != delta_size)
die("delta data unpack failed");
- /* The base entry _must_ be in the same pack */
- if (!find_pack_entry_one(base_sha1, &base_ent, p))
- die("failed to find delta-pack base object %s",
- sha1_to_hex(base_sha1));
- base = unpack_entry_gently(&base_ent, type, &base_size);
- if (!base)
- die("failed to read delta-pack base object %s",
- sha1_to_hex(base_sha1));
result = patch_delta(base, base_size,
delta_data, delta_size,
&result_size);
local = mkstemp(tmpfile);
if (local < 0)
- return error("Couldn't open %s for %s\n", tmpfile, sha1_to_hex(sha1));
+ return error("Couldn't open %s for %s",
+ tmpfile, sha1_to_hex(sha1));
memset(&stream, 0, sizeof(stream));
}
if (memcmp(sha1, real_sha1, 20)) {
unlink(tmpfile);
- return error("File %s has bad hash\n", sha1_to_hex(sha1));
+ return error("File %s has bad hash", sha1_to_hex(sha1));
}
return move_temp_to_file(tmpfile, sha1_file_name(sha1));