Merge branch 'sp/pack'
* sp/pack: Style nit - don't put space after function names Ensure the pack index is opened before access Simplify index access condition in count-objects, pack-redundant Test for recent rev-parse $abbrev_sha1 regression rev-parse: Identify short sha1 sums correctly. Attempt to delay prepare_alt_odb during get_sha1 Micro-optimize prepare_alt_odb Lazily open pack index files on demand
This commit is contained in:
commit
17c2929aa2
@ -111,6 +111,8 @@ int cmd_count_objects(int ac, const char **av, const char *prefix)
|
|||||||
for (p = packed_git; p; p = p->next) {
|
for (p = packed_git; p; p = p->next) {
|
||||||
if (!p->pack_local)
|
if (!p->pack_local)
|
||||||
continue;
|
continue;
|
||||||
|
if (open_pack_index(p))
|
||||||
|
continue;
|
||||||
packed += p->num_objects;
|
packed += p->num_objects;
|
||||||
num_pack++;
|
num_pack++;
|
||||||
}
|
}
|
||||||
|
@ -668,7 +668,10 @@ int cmd_fsck(int argc, char **argv, const char *prefix)
|
|||||||
verify_pack(p, 0);
|
verify_pack(p, 0);
|
||||||
|
|
||||||
for (p = packed_git; p; p = p->next) {
|
for (p = packed_git; p; p = p->next) {
|
||||||
uint32_t i, num = p->num_objects;
|
uint32_t i, num;
|
||||||
|
if (open_pack_index(p))
|
||||||
|
continue;
|
||||||
|
num = p->num_objects;
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
fsck_sha1(nth_packed_object_sha1(p, i));
|
fsck_sha1(nth_packed_object_sha1(p, i));
|
||||||
}
|
}
|
||||||
|
3
cache.h
3
cache.h
@ -483,10 +483,11 @@ extern struct packed_git *find_sha1_pack(const unsigned char *sha1,
|
|||||||
struct packed_git *packs);
|
struct packed_git *packs);
|
||||||
|
|
||||||
extern void pack_report(void);
|
extern void pack_report(void);
|
||||||
|
extern int open_pack_index(struct packed_git *);
|
||||||
extern unsigned char* use_pack(struct packed_git *, struct pack_window **, off_t, unsigned int *);
|
extern unsigned char* use_pack(struct packed_git *, struct pack_window **, off_t, unsigned int *);
|
||||||
extern void unuse_pack(struct pack_window **);
|
extern void unuse_pack(struct pack_window **);
|
||||||
extern struct packed_git *add_packed_git(const char *, int, int);
|
extern struct packed_git *add_packed_git(const char *, int, int);
|
||||||
extern const unsigned char *nth_packed_object_sha1(const struct packed_git *, uint32_t);
|
extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t);
|
||||||
extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *);
|
extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *);
|
||||||
extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
|
extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
|
||||||
extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
|
extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
|
||||||
|
@ -128,12 +128,17 @@ static void show_pack_info(struct packed_git *p)
|
|||||||
|
|
||||||
int verify_pack(struct packed_git *p, int verbose)
|
int verify_pack(struct packed_git *p, int verbose)
|
||||||
{
|
{
|
||||||
off_t index_size = p->index_size;
|
off_t index_size;
|
||||||
const unsigned char *index_base = p->index_data;
|
const unsigned char *index_base;
|
||||||
SHA_CTX ctx;
|
SHA_CTX ctx;
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (open_pack_index(p))
|
||||||
|
return error("packfile %s index not opened", p->pack_name);
|
||||||
|
index_size = p->index_size;
|
||||||
|
index_base = p->index_data;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
/* Verify SHA1 sum of the index file */
|
/* Verify SHA1 sum of the index file */
|
||||||
SHA1_Init(&ctx);
|
SHA1_Init(&ctx);
|
||||||
|
@ -550,6 +550,9 @@ static struct pack_list * add_pack(struct packed_git *p)
|
|||||||
l.pack = p;
|
l.pack = p;
|
||||||
llist_init(&l.all_objects);
|
llist_init(&l.all_objects);
|
||||||
|
|
||||||
|
if (open_pack_index(p))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
base = p->index_data;
|
base = p->index_data;
|
||||||
base += 256 * 4 + ((p->index_version < 2) ? 4 : 8);
|
base += 256 * 4 + ((p->index_version < 2) ? 4 : 8);
|
||||||
step = (p->index_version < 2) ? 24 : 20;
|
step = (p->index_version < 2) ? 24 : 20;
|
||||||
|
43
sha1_file.c
43
sha1_file.c
@ -376,11 +376,12 @@ void prepare_alt_odb(void)
|
|||||||
{
|
{
|
||||||
const char *alt;
|
const char *alt;
|
||||||
|
|
||||||
|
if (alt_odb_tail)
|
||||||
|
return;
|
||||||
|
|
||||||
alt = getenv(ALTERNATE_DB_ENVIRONMENT);
|
alt = getenv(ALTERNATE_DB_ENVIRONMENT);
|
||||||
if (!alt) alt = "";
|
if (!alt) alt = "";
|
||||||
|
|
||||||
if (alt_odb_tail)
|
|
||||||
return;
|
|
||||||
alt_odb_tail = &alt_odb_list;
|
alt_odb_tail = &alt_odb_list;
|
||||||
link_alt_odb_entries(alt, alt + strlen(alt), ':', NULL, 0);
|
link_alt_odb_entries(alt, alt + strlen(alt), ':', NULL, 0);
|
||||||
|
|
||||||
@ -530,6 +531,21 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int open_pack_index(struct packed_git *p)
|
||||||
|
{
|
||||||
|
char *idx_name;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (p->index_data)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
idx_name = xstrdup(p->pack_name);
|
||||||
|
strcpy(idx_name + strlen(idx_name) - strlen(".pack"), ".idx");
|
||||||
|
ret = check_packed_git_idx(idx_name, p);
|
||||||
|
free(idx_name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void scan_windows(struct packed_git *p,
|
static void scan_windows(struct packed_git *p,
|
||||||
struct packed_git **lru_p,
|
struct packed_git **lru_p,
|
||||||
struct pack_window **lru_w,
|
struct pack_window **lru_w,
|
||||||
@ -605,6 +621,9 @@ static int open_packed_git_1(struct packed_git *p)
|
|||||||
unsigned char *idx_sha1;
|
unsigned char *idx_sha1;
|
||||||
long fd_flag;
|
long fd_flag;
|
||||||
|
|
||||||
|
if (!p->index_data && open_pack_index(p))
|
||||||
|
return error("packfile %s index unavailable", p->pack_name);
|
||||||
|
|
||||||
p->pack_fd = open(p->pack_name, O_RDONLY);
|
p->pack_fd = open(p->pack_name, O_RDONLY);
|
||||||
if (p->pack_fd < 0 || fstat(p->pack_fd, &st))
|
if (p->pack_fd < 0 || fstat(p->pack_fd, &st))
|
||||||
return -1;
|
return -1;
|
||||||
@ -757,8 +776,7 @@ struct packed_git *add_packed_git(const char *path, int path_len, int local)
|
|||||||
return NULL;
|
return NULL;
|
||||||
memcpy(p->pack_name, path, path_len);
|
memcpy(p->pack_name, path, path_len);
|
||||||
strcpy(p->pack_name + path_len, ".pack");
|
strcpy(p->pack_name + path_len, ".pack");
|
||||||
if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode) ||
|
if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) {
|
||||||
check_packed_git_idx(path, p)) {
|
|
||||||
free(p);
|
free(p);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -766,6 +784,10 @@ struct packed_git *add_packed_git(const char *path, int path_len, int local)
|
|||||||
/* ok, it looks sane as far as we can check without
|
/* ok, it looks sane as far as we can check without
|
||||||
* actually mapping the pack file.
|
* actually mapping the pack file.
|
||||||
*/
|
*/
|
||||||
|
p->index_version = 0;
|
||||||
|
p->index_data = NULL;
|
||||||
|
p->index_size = 0;
|
||||||
|
p->num_objects = 0;
|
||||||
p->pack_size = st.st_size;
|
p->pack_size = st.st_size;
|
||||||
p->next = NULL;
|
p->next = NULL;
|
||||||
p->windows = NULL;
|
p->windows = NULL;
|
||||||
@ -1572,10 +1594,15 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned char *nth_packed_object_sha1(const struct packed_git *p,
|
const unsigned char *nth_packed_object_sha1(struct packed_git *p,
|
||||||
uint32_t n)
|
uint32_t n)
|
||||||
{
|
{
|
||||||
const unsigned char *index = p->index_data;
|
const unsigned char *index = p->index_data;
|
||||||
|
if (!index) {
|
||||||
|
if (open_pack_index(p))
|
||||||
|
return NULL;
|
||||||
|
index = p->index_data;
|
||||||
|
}
|
||||||
if (n >= p->num_objects)
|
if (n >= p->num_objects)
|
||||||
return NULL;
|
return NULL;
|
||||||
index += 4 * 256;
|
index += 4 * 256;
|
||||||
@ -1612,6 +1639,12 @@ off_t find_pack_entry_one(const unsigned char *sha1,
|
|||||||
const unsigned char *index = p->index_data;
|
const unsigned char *index = p->index_data;
|
||||||
unsigned hi, lo;
|
unsigned hi, lo;
|
||||||
|
|
||||||
|
if (!index) {
|
||||||
|
if (open_pack_index(p))
|
||||||
|
return 0;
|
||||||
|
level1_ofs = p->index_data;
|
||||||
|
index = p->index_data;
|
||||||
|
}
|
||||||
if (p->index_version > 1) {
|
if (p->index_version > 1) {
|
||||||
level1_ofs += 2;
|
level1_ofs += 2;
|
||||||
index += 8;
|
index += 8;
|
||||||
|
@ -76,8 +76,11 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
|
|||||||
|
|
||||||
prepare_packed_git();
|
prepare_packed_git();
|
||||||
for (p = packed_git; p && found < 2; p = p->next) {
|
for (p = packed_git; p && found < 2; p = p->next) {
|
||||||
uint32_t num = p->num_objects;
|
uint32_t num, last;
|
||||||
uint32_t first = 0, last = num;
|
uint32_t first = 0;
|
||||||
|
open_pack_index(p);
|
||||||
|
num = p->num_objects;
|
||||||
|
last = num;
|
||||||
while (first < last) {
|
while (first < last) {
|
||||||
uint32_t mid = (first + last) / 2;
|
uint32_t mid = (first + last) / 2;
|
||||||
const unsigned char *now;
|
const unsigned char *now;
|
||||||
@ -133,6 +136,7 @@ static int find_unique_short_object(int len, char *canonical,
|
|||||||
int has_unpacked, has_packed;
|
int has_unpacked, has_packed;
|
||||||
unsigned char unpacked_sha1[20], packed_sha1[20];
|
unsigned char unpacked_sha1[20], packed_sha1[20];
|
||||||
|
|
||||||
|
prepare_alt_odb();
|
||||||
has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1);
|
has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1);
|
||||||
has_packed = find_short_packed_object(len, res, packed_sha1);
|
has_packed = find_short_packed_object(len, res, packed_sha1);
|
||||||
if (!has_unpacked && !has_packed)
|
if (!has_unpacked && !has_packed)
|
||||||
@ -654,7 +658,6 @@ int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
|
|||||||
const char *cp;
|
const char *cp;
|
||||||
|
|
||||||
*mode = S_IFINVALID;
|
*mode = S_IFINVALID;
|
||||||
prepare_alt_odb();
|
|
||||||
ret = get_sha1_1(name, namelen, sha1);
|
ret = get_sha1_1(name, namelen, sha1);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -29,5 +29,15 @@ test_expect_success 'final^1^3 not valid' "if git-rev-parse --verify final^1^3;
|
|||||||
test_expect_failure '--verify start2^1' 'git-rev-parse --verify start2^1'
|
test_expect_failure '--verify start2^1' 'git-rev-parse --verify start2^1'
|
||||||
test_expect_success '--verify start2^0' 'git-rev-parse --verify start2^0'
|
test_expect_success '--verify start2^0' 'git-rev-parse --verify start2^0'
|
||||||
|
|
||||||
|
test_expect_success 'repack for next test' 'git repack -a -d'
|
||||||
|
test_expect_success 'short SHA-1 works' '
|
||||||
|
start=`git rev-parse --verify start` &&
|
||||||
|
echo $start &&
|
||||||
|
abbrv=`echo $start | sed s/.\$//` &&
|
||||||
|
echo $abbrv &&
|
||||||
|
abbrv=`git rev-parse --verify $abbrv` &&
|
||||||
|
echo $abbrv &&
|
||||||
|
test $start = $abbrv'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user