Skip to content

Commit 1c5a712

Browse files
committed
Merge branch 'jk/dumb-http-finalize'
The dumb-http code regressed when the result of re-indexing a pack yielded an *.idx file that differs in content from the *.idx file it downloaded from the remote. This has been corrected by no longer relying on the *.idx file we got from the remote. * jk/dumb-http-finalize: packfile: use oidread() instead of hashcpy() to fill object_id packfile: use object_id in find_pack_entry_one() packfile: convert find_sha1_pack() to use object_id http-walker: use object_id instead of bare hash packfile: warn people away from parse_packed_git() packfile: drop sha1_pack_index_name() packfile: drop sha1_pack_name() packfile: drop has_pack_index() dumb-http: store downloaded pack idx as tempfile t5550: count fetches in "previously-fetched .idx" test midx: avoid duplicate packed_git entries
2 parents 6d81fe6 + 863f245 commit 1c5a712

16 files changed

+153
-101
lines changed

builtin/fast-import.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -966,8 +966,7 @@ static int store_object(
966966
if (e->idx.offset) {
967967
duplicate_count_by_type[type]++;
968968
return 1;
969-
} else if (find_sha1_pack(oid.hash,
970-
get_all_packs(the_repository))) {
969+
} else if (find_oid_pack(&oid, get_all_packs(the_repository))) {
971970
e->type = type;
972971
e->pack_id = MAX_PACK_ID;
973972
e->idx.offset = 1; /* just not zero! */
@@ -1167,8 +1166,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
11671166
duplicate_count_by_type[OBJ_BLOB]++;
11681167
truncate_pack(&checkpoint);
11691168

1170-
} else if (find_sha1_pack(oid.hash,
1171-
get_all_packs(the_repository))) {
1169+
} else if (find_oid_pack(&oid, get_all_packs(the_repository))) {
11721170
e->type = OBJ_BLOB;
11731171
e->pack_id = MAX_PACK_ID;
11741172
e->idx.offset = 1; /* just not zero! */

builtin/pack-objects.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,7 @@ static int want_object_in_pack_one(struct packed_git *p,
15561556
if (p == *found_pack)
15571557
offset = *found_offset;
15581558
else
1559-
offset = find_pack_entry_one(oid->hash, p);
1559+
offset = find_pack_entry_one(oid, p);
15601560

15611561
if (offset) {
15621562
if (!*found_pack) {
@@ -3984,7 +3984,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)
39843984
while (p) {
39853985
if ((!p->pack_local || p->pack_keep ||
39863986
p->pack_keep_in_core) &&
3987-
find_pack_entry_one(oid->hash, p)) {
3987+
find_pack_entry_one(oid, p)) {
39883988
last_found = p;
39893989
return 1;
39903990
}

builtin/pack-redundant.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "packfile.h"
1515
#include "object-store-ll.h"
16+
#include "strbuf.h"
1617

1718
#define BLKSIZE 512
1819

@@ -591,6 +592,7 @@ static void load_all(void)
591592
int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, struct repository *repo UNUSED) {
592593
int i; int i_still_use_this = 0; struct pack_list *min = NULL, *red, *pl;
593594
struct llist *ignore;
595+
struct strbuf idx_name = STRBUF_INIT;
594596
char buf[GIT_MAX_HEXSZ + 2]; /* hex hash + \n + \0 */
595597

596598
if (argc == 2 && !strcmp(argv[1], "-h"))
@@ -688,7 +690,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s
688690
pl = red = pack_list_difference(local_packs, min);
689691
while (pl) {
690692
printf("%s\n%s\n",
691-
sha1_pack_index_name(pl->pack->hash),
693+
odb_pack_name(&idx_name, pl->pack->hash, "idx"),
692694
pl->pack->pack_name);
693695
pl = pl->next;
694696
}
@@ -699,5 +701,6 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s
699701
pack_list_free(red);
700702
pack_list_free(min);
701703
llist_free(ignore);
704+
strbuf_release(&idx_name);
702705
return 0;
703706
}

connected.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
7878
for (p = get_all_packs(the_repository); p; p = p->next) {
7979
if (!p->pack_promisor)
8080
continue;
81-
if (find_pack_entry_one(oid->hash, p))
81+
if (find_pack_entry_one(oid, p))
8282
goto promisor_pack_found;
8383
}
8484
/*
@@ -144,7 +144,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
144144
* are sure the ref is good and not sending it to
145145
* rev-list for verification.
146146
*/
147-
if (new_pack && find_pack_entry_one(oid->hash, new_pack))
147+
if (new_pack && find_pack_entry_one(oid, new_pack))
148148
continue;
149149

150150
if (fprintf(rev_list_in, "%s\n", oid_to_hex(oid)) < 0)

http-push.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ static void start_fetch_packed(struct transfer_request *request)
309309
struct transfer_request *check_request = request_queue_head;
310310
struct http_pack_request *preq;
311311

312-
target = find_sha1_pack(request->obj->oid.hash, repo->packs);
312+
target = find_oid_pack(&request->obj->oid, repo->packs);
313313
if (!target) {
314314
fprintf(stderr, "Unable to fetch %s, will not be able to update server info refs\n", oid_to_hex(&request->obj->oid));
315315
repo->can_update_info_refs = 0;
@@ -681,7 +681,7 @@ static int add_send_request(struct object *obj, struct remote_lock *lock)
681681
get_remote_object_list(obj->oid.hash[0]);
682682
if (obj->flags & (REMOTE | PUSHING))
683683
return 0;
684-
target = find_sha1_pack(obj->oid.hash, repo->packs);
684+
target = find_oid_pack(&obj->oid, repo->packs);
685685
if (target) {
686686
obj->flags |= REMOTE;
687687
return 0;

http-walker.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,14 @@ static int fill_active_slot(void *data UNUSED)
147147
return 0;
148148
}
149149

150-
static void prefetch(struct walker *walker, unsigned char *sha1)
150+
static void prefetch(struct walker *walker, const struct object_id *oid)
151151
{
152152
struct object_request *newreq;
153153
struct walker_data *data = walker->data;
154154

155155
newreq = xmalloc(sizeof(*newreq));
156156
newreq->walker = walker;
157-
oidread(&newreq->oid, sha1, the_repository->hash_algo);
157+
oidcpy(&newreq->oid, oid);
158158
newreq->repo = data->alt;
159159
newreq->state = WAITING;
160160
newreq->req = NULL;
@@ -422,7 +422,8 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)
422422
return ret;
423423
}
424424

425-
static int http_fetch_pack(struct walker *walker, struct alt_base *repo, unsigned char *sha1)
425+
static int http_fetch_pack(struct walker *walker, struct alt_base *repo,
426+
const struct object_id *oid)
426427
{
427428
struct packed_git *target;
428429
int ret;
@@ -431,7 +432,7 @@ static int http_fetch_pack(struct walker *walker, struct alt_base *repo, unsigne
431432

432433
if (fetch_indices(walker, repo))
433434
return -1;
434-
target = find_sha1_pack(sha1, repo->packs);
435+
target = find_oid_pack(oid, repo->packs);
435436
if (!target)
436437
return -1;
437438
close_pack_index(target);
@@ -440,7 +441,7 @@ static int http_fetch_pack(struct walker *walker, struct alt_base *repo, unsigne
440441
fprintf(stderr, "Getting pack %s\n",
441442
hash_to_hex(target->hash));
442443
fprintf(stderr, " which contains %s\n",
443-
hash_to_hex(sha1));
444+
oid_to_hex(oid));
444445
}
445446

446447
preq = new_http_pack_request(target->hash, repo->base);
@@ -477,17 +478,17 @@ static void abort_object_request(struct object_request *obj_req)
477478
release_object_request(obj_req);
478479
}
479480

480-
static int fetch_object(struct walker *walker, unsigned char *hash)
481+
static int fetch_object(struct walker *walker, const struct object_id *oid)
481482
{
482-
char *hex = hash_to_hex(hash);
483+
char *hex = oid_to_hex(oid);
483484
int ret = 0;
484485
struct object_request *obj_req = NULL;
485486
struct http_object_request *req;
486487
struct list_head *pos, *head = &object_queue_head;
487488

488489
list_for_each(pos, head) {
489490
obj_req = list_entry(pos, struct object_request, node);
490-
if (hasheq(obj_req->oid.hash, hash, the_repository->hash_algo))
491+
if (oideq(&obj_req->oid, oid))
491492
break;
492493
}
493494
if (!obj_req)
@@ -548,20 +549,20 @@ static int fetch_object(struct walker *walker, unsigned char *hash)
548549
return ret;
549550
}
550551

551-
static int fetch(struct walker *walker, unsigned char *hash)
552+
static int fetch(struct walker *walker, const struct object_id *oid)
552553
{
553554
struct walker_data *data = walker->data;
554555
struct alt_base *altbase = data->alt;
555556

556-
if (!fetch_object(walker, hash))
557+
if (!fetch_object(walker, oid))
557558
return 0;
558559
while (altbase) {
559-
if (!http_fetch_pack(walker, altbase, hash))
560+
if (!http_fetch_pack(walker, altbase, oid))
560561
return 0;
561562
fetch_alternates(walker, data->alt->base);
562563
altbase = altbase->next;
563564
}
564-
return error("Unable to find %s under %s", hash_to_hex(hash),
565+
return error("Unable to find %s under %s", oid_to_hex(oid),
565566
data->alt->base);
566567
}
567568

http.c

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "string-list.h"
2020
#include "object-file.h"
2121
#include "object-store-ll.h"
22+
#include "tempfile.h"
2223

2324
static struct trace_key trace_curl = TRACE_KEY_INIT(CURL);
2425
static int trace_curl_data = 1;
@@ -2390,8 +2391,24 @@ static char *fetch_pack_index(unsigned char *hash, const char *base_url)
23902391
strbuf_addf(&buf, "objects/pack/pack-%s.idx", hash_to_hex(hash));
23912392
url = strbuf_detach(&buf, NULL);
23922393

2393-
strbuf_addf(&buf, "%s.temp", sha1_pack_index_name(hash));
2394-
tmp = strbuf_detach(&buf, NULL);
2394+
/*
2395+
* Don't put this into packs/, since it's just temporary and we don't
2396+
* want to confuse it with our local .idx files. We'll generate our
2397+
* own index if we choose to download the matching packfile.
2398+
*
2399+
* It's tempting to use xmks_tempfile() here, but it's important that
2400+
* the file not exist, otherwise http_get_file() complains. So we
2401+
* create a filename that should be unique, and then just register it
2402+
* as a tempfile so that it will get cleaned up on exit.
2403+
*
2404+
* In theory we could hold on to the tempfile and delete these as soon
2405+
* as we download the matching pack, but it would take a bit of
2406+
* refactoring. Leaving them until the process ends is probably OK.
2407+
*/
2408+
tmp = xstrfmt("%s/tmp_pack_%s.idx",
2409+
repo_get_object_directory(the_repository),
2410+
hash_to_hex(hash));
2411+
register_tempfile(tmp);
23952412

23962413
if (http_get_file(url, tmp, NULL) != HTTP_OK) {
23972414
error("Unable to get pack index %s", url);
@@ -2405,15 +2422,17 @@ static char *fetch_pack_index(unsigned char *hash, const char *base_url)
24052422
static int fetch_and_setup_pack_index(struct packed_git **packs_head,
24062423
unsigned char *sha1, const char *base_url)
24072424
{
2408-
struct packed_git *new_pack;
2425+
struct packed_git *new_pack, *p;
24092426
char *tmp_idx = NULL;
24102427
int ret;
24112428

2412-
if (has_pack_index(sha1)) {
2413-
new_pack = parse_pack_index(sha1, sha1_pack_index_name(sha1));
2414-
if (!new_pack)
2415-
return -1; /* parse_pack_index() already issued error message */
2416-
goto add_pack;
2429+
/*
2430+
* If we already have the pack locally, no need to fetch its index or
2431+
* even add it to list; we already have all of its objects.
2432+
*/
2433+
for (p = get_all_packs(the_repository); p; p = p->next) {
2434+
if (hasheq(p->hash, sha1, the_repository->hash_algo))
2435+
return 0;
24172436
}
24182437

24192438
tmp_idx = fetch_pack_index(sha1, base_url);
@@ -2429,15 +2448,12 @@ static int fetch_and_setup_pack_index(struct packed_git **packs_head,
24292448
}
24302449

24312450
ret = verify_pack_index(new_pack);
2432-
if (!ret) {
2451+
if (!ret)
24332452
close_pack_index(new_pack);
2434-
ret = finalize_object_file(tmp_idx, sha1_pack_index_name(sha1));
2435-
}
24362453
free(tmp_idx);
24372454
if (ret)
24382455
return -1;
24392456

2440-
add_pack:
24412457
new_pack->next = *packs_head;
24422458
*packs_head = new_pack;
24432459
return 0;
@@ -2565,7 +2581,8 @@ struct http_pack_request *new_direct_http_pack_request(
25652581

25662582
preq->url = url;
25672583

2568-
strbuf_addf(&preq->tmpfile, "%s.temp", sha1_pack_name(packed_git_hash));
2584+
odb_pack_name(&preq->tmpfile, packed_git_hash, "pack");
2585+
strbuf_addstr(&preq->tmpfile, ".temp");
25692586
preq->packfile = fopen(preq->tmpfile.buf, "a");
25702587
if (!preq->packfile) {
25712588
error("Unable to open local file %s for pack",

midx.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m,
445445
uint32_t pack_int_id)
446446
{
447447
struct strbuf pack_name = STRBUF_INIT;
448+
struct strbuf key = STRBUF_INIT;
448449
struct packed_git *p;
449450

450451
pack_int_id = midx_for_pack(&m, pack_int_id);
@@ -455,16 +456,29 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m,
455456
strbuf_addf(&pack_name, "%s/pack/%s", m->object_dir,
456457
m->pack_names[pack_int_id]);
457458

458-
p = add_packed_git(pack_name.buf, pack_name.len, m->local);
459+
/* pack_map holds the ".pack" name, but we have the .idx */
460+
strbuf_addbuf(&key, &pack_name);
461+
strbuf_strip_suffix(&key, ".idx");
462+
strbuf_addstr(&key, ".pack");
463+
p = hashmap_get_entry_from_hash(&r->objects->pack_map,
464+
strhash(key.buf), key.buf,
465+
struct packed_git, packmap_ent);
466+
if (!p) {
467+
p = add_packed_git(pack_name.buf, pack_name.len, m->local);
468+
if (p) {
469+
install_packed_git(r, p);
470+
list_add_tail(&p->mru, &r->objects->packed_git_mru);
471+
}
472+
}
473+
459474
strbuf_release(&pack_name);
475+
strbuf_release(&key);
460476

461477
if (!p)
462478
return 1;
463479

464480
p->multi_pack_index = 1;
465481
m->packs[pack_int_id] = p;
466-
install_packed_git(r, p);
467-
list_add_tail(&p->mru, &r->objects->packed_git_mru);
468482

469483
return 0;
470484
}
@@ -973,7 +987,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
973987
}
974988

975989
m_offset = e.offset;
976-
p_offset = find_pack_entry_one(oid.hash, e.p);
990+
p_offset = find_pack_entry_one(&oid, e.p);
977991

978992
if (m_offset != p_offset)
979993
midx_report(_("incorrect object offset for oid[%d] = %s: %"PRIx64" != %"PRIx64),

pack-bitmap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,7 @@ static inline int bitmap_position_packfile(struct bitmap_index *bitmap_git,
935935
const struct object_id *oid)
936936
{
937937
uint32_t pos;
938-
off_t offset = find_pack_entry_one(oid->hash, bitmap_git->pack);
938+
off_t offset = find_pack_entry_one(oid, bitmap_git->pack);
939939
if (!offset)
940940
return -1;
941941

@@ -1609,7 +1609,7 @@ static int in_bitmapped_pack(struct bitmap_index *bitmap_git,
16091609
if (bsearch_midx(&object->oid, bitmap_git->midx, NULL))
16101610
return 1;
16111611
} else {
1612-
if (find_pack_entry_one(object->oid.hash, bitmap_git->pack) > 0)
1612+
if (find_pack_entry_one(&object->oid, bitmap_git->pack) > 0)
16131613
return 1;
16141614
}
16151615
}

0 commit comments

Comments
 (0)