Skip to content

Commit 035bf8d

Browse files
committed
Merge branch 'sp/maint-dumb-http-pack-reidx'
* sp/maint-dumb-http-pack-reidx: http.c::new_http_pack_request: do away with the temp variable filename http-fetch: Use temporary files for pack-*.idx until verified http-fetch: Use index-pack rather than verify-pack to check packs Allow parse_pack_index on temporary files Extract verify_pack_index for reuse from verify_pack Introduce close_pack_index to permit replacement http.c: Remove unnecessary strdup of sha1_to_hex result http.c: Don't store destination name in request structures http.c: Drop useless != NULL test in finish_http_pack_request http.c: Tiny refactoring of finish_http_pack_request t5550-http-fetch: Use subshell for repository operations http.c: Remove bad free of static block
2 parents 465ef57 + 90d0571 commit 035bf8d

File tree

8 files changed

+149
-60
lines changed

8 files changed

+149
-60
lines changed

cache.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,7 @@ struct extra_have_objects {
907907
extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags, struct extra_have_objects *);
908908
extern int server_supports(const char *feature);
909909

910-
extern struct packed_git *parse_pack_index(unsigned char *sha1);
910+
extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
911911

912912
extern void prepare_packed_git(void);
913913
extern void reprepare_packed_git(void);
@@ -918,6 +918,7 @@ extern struct packed_git *find_sha1_pack(const unsigned char *sha1,
918918

919919
extern void pack_report(void);
920920
extern int open_pack_index(struct packed_git *);
921+
extern void close_pack_index(struct packed_git *);
921922
extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned int *);
922923
extern void close_pack_windows(struct packed_git *);
923924
extern void unuse_pack(struct pack_window **);

http-walker.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ static int fetch_object(struct walker *walker, struct alt_base *repo, unsigned c
510510
ret = error("File %s has bad hash", hex);
511511
} else if (req->rename < 0) {
512512
ret = error("unable to write sha1 filename %s",
513-
req->filename);
513+
sha1_file_name(req->sha1));
514514
}
515515

516516
release_http_object_request(req);

http.c

Lines changed: 89 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "http.h"
22
#include "pack.h"
33
#include "sideband.h"
4+
#include "run-command.h"
45

56
int data_received;
67
int active_requests;
@@ -914,47 +915,67 @@ int http_fetch_ref(const char *base, struct ref *ref)
914915
}
915916

916917
/* Helpers for fetching packs */
917-
static int fetch_pack_index(unsigned char *sha1, const char *base_url)
918+
static char *fetch_pack_index(unsigned char *sha1, const char *base_url)
918919
{
919-
int ret = 0;
920-
char *hex = xstrdup(sha1_to_hex(sha1));
921-
char *filename;
922-
char *url = NULL;
920+
char *url, *tmp;
923921
struct strbuf buf = STRBUF_INIT;
924922

925-
if (has_pack_index(sha1)) {
926-
ret = 0;
927-
goto cleanup;
928-
}
929-
930923
if (http_is_verbose)
931-
fprintf(stderr, "Getting index for pack %s\n", hex);
924+
fprintf(stderr, "Getting index for pack %s\n", sha1_to_hex(sha1));
932925

933926
end_url_with_slash(&buf, base_url);
934-
strbuf_addf(&buf, "objects/pack/pack-%s.idx", hex);
927+
strbuf_addf(&buf, "objects/pack/pack-%s.idx", sha1_to_hex(sha1));
935928
url = strbuf_detach(&buf, NULL);
936929

937-
filename = sha1_pack_index_name(sha1);
938-
if (http_get_file(url, filename, 0) != HTTP_OK)
939-
ret = error("Unable to get pack index %s\n", url);
930+
strbuf_addf(&buf, "%s.temp", sha1_pack_index_name(sha1));
931+
tmp = strbuf_detach(&buf, NULL);
932+
933+
if (http_get_file(url, tmp, 0) != HTTP_OK) {
934+
error("Unable to get pack index %s\n", url);
935+
free(tmp);
936+
tmp = NULL;
937+
}
940938

941-
cleanup:
942-
free(hex);
943939
free(url);
944-
return ret;
940+
return tmp;
945941
}
946942

947943
static int fetch_and_setup_pack_index(struct packed_git **packs_head,
948944
unsigned char *sha1, const char *base_url)
949945
{
950946
struct packed_git *new_pack;
947+
char *tmp_idx = NULL;
948+
int ret;
951949

952-
if (fetch_pack_index(sha1, base_url))
950+
if (has_pack_index(sha1)) {
951+
new_pack = parse_pack_index(sha1, NULL);
952+
if (!new_pack)
953+
return -1; /* parse_pack_index() already issued error message */
954+
goto add_pack;
955+
}
956+
957+
tmp_idx = fetch_pack_index(sha1, base_url);
958+
if (!tmp_idx)
953959
return -1;
954960

955-
new_pack = parse_pack_index(sha1);
956-
if (!new_pack)
961+
new_pack = parse_pack_index(sha1, tmp_idx);
962+
if (!new_pack) {
963+
unlink(tmp_idx);
964+
free(tmp_idx);
965+
957966
return -1; /* parse_pack_index() already issued error message */
967+
}
968+
969+
ret = verify_pack_index(new_pack);
970+
if (!ret) {
971+
close_pack_index(new_pack);
972+
ret = move_temp_to_file(tmp_idx, sha1_pack_index_name(sha1));
973+
}
974+
free(tmp_idx);
975+
if (ret)
976+
return -1;
977+
978+
add_pack:
958979
new_pack->next = *packs_head;
959980
*packs_head = new_pack;
960981
return 0;
@@ -1018,37 +1039,62 @@ void release_http_pack_request(struct http_pack_request *preq)
10181039

10191040
int finish_http_pack_request(struct http_pack_request *preq)
10201041
{
1021-
int ret;
10221042
struct packed_git **lst;
1043+
struct packed_git *p = preq->target;
1044+
char *tmp_idx;
1045+
struct child_process ip;
1046+
const char *ip_argv[8];
10231047

1024-
preq->target->pack_size = ftell(preq->packfile);
1048+
close_pack_index(p);
10251049

1026-
if (preq->packfile != NULL) {
1027-
fclose(preq->packfile);
1028-
preq->packfile = NULL;
1029-
preq->slot->local = NULL;
1030-
}
1031-
1032-
ret = move_temp_to_file(preq->tmpfile, preq->filename);
1033-
if (ret)
1034-
return ret;
1050+
fclose(preq->packfile);
1051+
preq->packfile = NULL;
1052+
preq->slot->local = NULL;
10351053

10361054
lst = preq->lst;
1037-
while (*lst != preq->target)
1055+
while (*lst != p)
10381056
lst = &((*lst)->next);
10391057
*lst = (*lst)->next;
10401058

1041-
if (verify_pack(preq->target))
1059+
tmp_idx = xstrdup(preq->tmpfile);
1060+
strcpy(tmp_idx + strlen(tmp_idx) - strlen(".pack.temp"),
1061+
".idx.temp");
1062+
1063+
ip_argv[0] = "index-pack";
1064+
ip_argv[1] = "-o";
1065+
ip_argv[2] = tmp_idx;
1066+
ip_argv[3] = preq->tmpfile;
1067+
ip_argv[4] = NULL;
1068+
1069+
memset(&ip, 0, sizeof(ip));
1070+
ip.argv = ip_argv;
1071+
ip.git_cmd = 1;
1072+
ip.no_stdin = 1;
1073+
ip.no_stdout = 1;
1074+
1075+
if (run_command(&ip)) {
1076+
unlink(preq->tmpfile);
1077+
unlink(tmp_idx);
1078+
free(tmp_idx);
1079+
return -1;
1080+
}
1081+
1082+
unlink(sha1_pack_index_name(p->sha1));
1083+
1084+
if (move_temp_to_file(preq->tmpfile, sha1_pack_name(p->sha1))
1085+
|| move_temp_to_file(tmp_idx, sha1_pack_index_name(p->sha1))) {
1086+
free(tmp_idx);
10421087
return -1;
1043-
install_packed_git(preq->target);
1088+
}
10441089

1090+
install_packed_git(p);
1091+
free(tmp_idx);
10451092
return 0;
10461093
}
10471094

10481095
struct http_pack_request *new_http_pack_request(
10491096
struct packed_git *target, const char *base_url)
10501097
{
1051-
char *filename;
10521098
long prev_posn = 0;
10531099
char range[RANGE_HEADER_SIZE];
10541100
struct strbuf buf = STRBUF_INIT;
@@ -1063,9 +1109,8 @@ struct http_pack_request *new_http_pack_request(
10631109
sha1_to_hex(target->sha1));
10641110
preq->url = strbuf_detach(&buf, NULL);
10651111

1066-
filename = sha1_pack_name(target->sha1);
1067-
snprintf(preq->filename, sizeof(preq->filename), "%s", filename);
1068-
snprintf(preq->tmpfile, sizeof(preq->tmpfile), "%s.temp", filename);
1112+
snprintf(preq->tmpfile, sizeof(preq->tmpfile), "%s.temp",
1113+
sha1_pack_name(target->sha1));
10691114
preq->packfile = fopen(preq->tmpfile, "a");
10701115
if (!preq->packfile) {
10711116
error("Unable to open local file %s for pack",
@@ -1100,7 +1145,6 @@ struct http_pack_request *new_http_pack_request(
11001145
return preq;
11011146

11021147
abort:
1103-
free(filename);
11041148
free(preq->url);
11051149
free(preq);
11061150
return NULL;
@@ -1155,7 +1199,6 @@ struct http_object_request *new_http_object_request(const char *base_url,
11551199
freq->localfile = -1;
11561200

11571201
filename = sha1_file_name(sha1);
1158-
snprintf(freq->filename, sizeof(freq->filename), "%s", filename);
11591202
snprintf(freq->tmpfile, sizeof(freq->tmpfile),
11601203
"%s.temp", filename);
11611204

@@ -1184,8 +1227,8 @@ struct http_object_request *new_http_object_request(const char *base_url,
11841227
}
11851228

11861229
if (freq->localfile < 0) {
1187-
error("Couldn't create temporary file %s for %s: %s",
1188-
freq->tmpfile, freq->filename, strerror(errno));
1230+
error("Couldn't create temporary file %s: %s",
1231+
freq->tmpfile, strerror(errno));
11891232
goto abort;
11901233
}
11911234

@@ -1232,8 +1275,8 @@ struct http_object_request *new_http_object_request(const char *base_url,
12321275
prev_posn = 0;
12331276
lseek(freq->localfile, 0, SEEK_SET);
12341277
if (ftruncate(freq->localfile, 0) < 0) {
1235-
error("Couldn't truncate temporary file %s for %s: %s",
1236-
freq->tmpfile, freq->filename, strerror(errno));
1278+
error("Couldn't truncate temporary file %s: %s",
1279+
freq->tmpfile, strerror(errno));
12371280
goto abort;
12381281
}
12391282
}
@@ -1309,7 +1352,7 @@ int finish_http_object_request(struct http_object_request *freq)
13091352
return -1;
13101353
}
13111354
freq->rename =
1312-
move_temp_to_file(freq->tmpfile, freq->filename);
1355+
move_temp_to_file(freq->tmpfile, sha1_file_name(freq->sha1));
13131356

13141357
return freq->rename;
13151358
}

http.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ struct http_pack_request
155155
struct packed_git *target;
156156
struct packed_git **lst;
157157
FILE *packfile;
158-
char filename[PATH_MAX];
159158
char tmpfile[PATH_MAX];
160159
struct curl_slist *range_header;
161160
struct active_request_slot *slot;
@@ -170,7 +169,6 @@ extern void release_http_pack_request(struct http_pack_request *preq);
170169
struct http_object_request
171170
{
172171
char *url;
173-
char filename[PATH_MAX];
174172
char tmpfile[PATH_MAX];
175173
int localfile;
176174
CURLcode curl_result;

pack-check.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,13 @@ static int verify_packfile(struct packed_git *p,
133133
return err;
134134
}
135135

136-
int verify_pack(struct packed_git *p)
136+
int verify_pack_index(struct packed_git *p)
137137
{
138138
off_t index_size;
139139
const unsigned char *index_base;
140140
git_SHA_CTX ctx;
141141
unsigned char sha1[20];
142142
int err = 0;
143-
struct pack_window *w_curs = NULL;
144143

145144
if (open_pack_index(p))
146145
return error("packfile %s index not opened", p->pack_name);
@@ -154,8 +153,18 @@ int verify_pack(struct packed_git *p)
154153
if (hashcmp(sha1, index_base + index_size - 20))
155154
err = error("Packfile index for %s SHA1 mismatch",
156155
p->pack_name);
156+
return err;
157+
}
158+
159+
int verify_pack(struct packed_git *p)
160+
{
161+
int err = 0;
162+
struct pack_window *w_curs = NULL;
163+
164+
err |= verify_pack_index(p);
165+
if (!p->index_data)
166+
return -1;
157167

158-
/* Verify pack file */
159168
err |= verify_packfile(p, &w_curs);
160169
unuse_pack(&w_curs);
161170

pack.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ struct pack_idx_entry {
5757

5858
extern const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects, int nr_objects, unsigned char *sha1);
5959
extern int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr);
60+
extern int verify_pack_index(struct packed_git *);
6061
extern int verify_pack(struct packed_git *);
6162
extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t, unsigned char *, off_t);
6263
extern char *index_pack_lockfile(int fd);

sha1_file.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,14 @@ void unuse_pack(struct pack_window **w_cursor)
599599
}
600600
}
601601

602+
void close_pack_index(struct packed_git *p)
603+
{
604+
if (p->index_data) {
605+
munmap((void *)p->index_data, p->index_size);
606+
p->index_data = NULL;
607+
}
608+
}
609+
602610
/*
603611
* This is used by git-repack in case a newly created pack happens to
604612
* contain the same set of objects as an existing one. In that case
@@ -620,8 +628,7 @@ void free_pack_by_name(const char *pack_name)
620628
close_pack_windows(p);
621629
if (p->pack_fd != -1)
622630
close(p->pack_fd);
623-
if (p->index_data)
624-
munmap((void *)p->index_data, p->index_size);
631+
close_pack_index(p);
625632
free(p->bad_object_sha1);
626633
*pp = p->next;
627634
free(p);
@@ -831,9 +838,8 @@ struct packed_git *add_packed_git(const char *path, int path_len, int local)
831838
return p;
832839
}
833840

834-
struct packed_git *parse_pack_index(unsigned char *sha1)
841+
struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path)
835842
{
836-
const char *idx_path = sha1_pack_index_name(sha1);
837843
const char *path = sha1_pack_name(sha1);
838844
struct packed_git *p = alloc_packed_git(strlen(path) + 1);
839845

0 commit comments

Comments
 (0)