Skip to content

Commit 9da69a6

Browse files
jonathantanmygitster
authored andcommitted
fetch-pack: support more than one pack lockfile
Whenever a fetch results in a packfile being downloaded, a .keep file is generated, so that the packfile can be preserved (from, say, a running "git repack") until refs are written referring to the contents of the packfile. In a subsequent patch, a successful fetch using protocol v2 may result in more than one .keep file being generated. Therefore, teach fetch_pack() and the transport mechanism to support multiple .keep files. Implementation notes: - builtin/fetch-pack.c normally does not generate .keep files, and thus is unaffected by this or future changes. However, it has an undocumented "--lock-pack" feature, used by remote-curl.c when implementing the "fetch" remote helper command. In keeping with the remote helper protocol, only one "lock" line will ever be written; the rest will result in warnings to stderr. However, in practice, warnings will never be written because the remote-curl.c "fetch" is only used for protocol v0/v1 (which will not generate multiple .keep files). (Protocol v2 uses the "stateless-connect" command, not the "fetch" command.) - connected.c has an optimization in that connectivity checks on a ref need not be done if the target object is in a pack known to be self-contained and connected. If there are multiple packfiles, this optimization can no longer be done. Signed-off-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent acaaca7 commit 9da69a6

File tree

7 files changed

+46
-35
lines changed

7 files changed

+46
-35
lines changed

builtin/fetch-pack.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
4848
struct ref **sought = NULL;
4949
int nr_sought = 0, alloc_sought = 0;
5050
int fd[2];
51-
char *pack_lockfile = NULL;
52-
char **pack_lockfile_ptr = NULL;
51+
struct string_list pack_lockfiles = STRING_LIST_INIT_DUP;
52+
struct string_list *pack_lockfiles_ptr = NULL;
5353
struct child_process *conn;
5454
struct fetch_pack_args args;
5555
struct oid_array shallow = OID_ARRAY_INIT;
@@ -134,7 +134,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
134134
}
135135
if (!strcmp("--lock-pack", arg)) {
136136
args.lock_pack = 1;
137-
pack_lockfile_ptr = &pack_lockfile;
137+
pack_lockfiles_ptr = &pack_lockfiles;
138138
continue;
139139
}
140140
if (!strcmp("--check-self-contained-and-connected", arg)) {
@@ -235,10 +235,15 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
235235
}
236236

237237
ref = fetch_pack(&args, fd, ref, sought, nr_sought,
238-
&shallow, pack_lockfile_ptr, version);
239-
if (pack_lockfile) {
240-
printf("lock %s\n", pack_lockfile);
238+
&shallow, pack_lockfiles_ptr, version);
239+
if (pack_lockfiles.nr) {
240+
int i;
241+
242+
printf("lock %s\n", pack_lockfiles.items[0].string);
241243
fflush(stdout);
244+
for (i = 1; i < pack_lockfiles.nr; i++)
245+
warning(_("Lockfile created but not reported: %s"),
246+
pack_lockfiles.items[i].string);
242247
}
243248
if (args.check_self_contained_and_connected &&
244249
args.self_contained_and_connected) {

connected.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
4343

4444
if (transport && transport->smart_options &&
4545
transport->smart_options->self_contained_and_connected &&
46-
transport->pack_lockfile &&
47-
strip_suffix(transport->pack_lockfile, ".keep", &base_len)) {
46+
transport->pack_lockfiles.nr == 1 &&
47+
strip_suffix(transport->pack_lockfiles.items[0].string,
48+
".keep", &base_len)) {
4849
struct strbuf idx_file = STRBUF_INIT;
49-
strbuf_add(&idx_file, transport->pack_lockfile, base_len);
50+
strbuf_add(&idx_file, transport->pack_lockfiles.items[0].string,
51+
base_len);
5052
strbuf_addstr(&idx_file, ".idx");
5153
new_pack = add_packed_git(idx_file.buf, idx_file.len, 1);
5254
strbuf_release(&idx_file);

fetch-pack.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ static void write_promisor_file(const char *keep_name,
794794
}
795795

796796
static int get_pack(struct fetch_pack_args *args,
797-
int xd[2], char **pack_lockfile,
797+
int xd[2], struct string_list *pack_lockfiles,
798798
struct ref **sought, int nr_sought)
799799
{
800800
struct async demux;
@@ -838,7 +838,7 @@ static int get_pack(struct fetch_pack_args *args,
838838
}
839839

840840
if (do_keep || args->from_promisor) {
841-
if (pack_lockfile)
841+
if (pack_lockfiles)
842842
cmd.out = -1;
843843
cmd_name = "index-pack";
844844
argv_array_push(&cmd.args, cmd_name);
@@ -863,7 +863,7 @@ static int get_pack(struct fetch_pack_args *args,
863863
* information below. If not, we need index-pack to do it for
864864
* us.
865865
*/
866-
if (!(do_keep && pack_lockfile) && args->from_promisor)
866+
if (!(do_keep && pack_lockfiles) && args->from_promisor)
867867
argv_array_push(&cmd.args, "--promisor");
868868
}
869869
else {
@@ -899,8 +899,9 @@ static int get_pack(struct fetch_pack_args *args,
899899
cmd.git_cmd = 1;
900900
if (start_command(&cmd))
901901
die(_("fetch-pack: unable to fork off %s"), cmd_name);
902-
if (do_keep && pack_lockfile) {
903-
*pack_lockfile = index_pack_lockfile(cmd.out);
902+
if (do_keep && pack_lockfiles) {
903+
string_list_append_nodup(pack_lockfiles,
904+
index_pack_lockfile(cmd.out));
904905
close(cmd.out);
905906
}
906907

@@ -922,8 +923,8 @@ static int get_pack(struct fetch_pack_args *args,
922923
* Now that index-pack has succeeded, write the promisor file using the
923924
* obtained .keep filename if necessary
924925
*/
925-
if (do_keep && pack_lockfile && args->from_promisor)
926-
write_promisor_file(*pack_lockfile, sought, nr_sought);
926+
if (do_keep && pack_lockfiles && pack_lockfiles->nr && args->from_promisor)
927+
write_promisor_file(pack_lockfiles->items[0].string, sought, nr_sought);
927928

928929
return 0;
929930
}
@@ -940,7 +941,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
940941
const struct ref *orig_ref,
941942
struct ref **sought, int nr_sought,
942943
struct shallow_info *si,
943-
char **pack_lockfile)
944+
struct string_list *pack_lockfiles)
944945
{
945946
struct repository *r = the_repository;
946947
struct ref *ref = copy_ref_list(orig_ref);
@@ -1067,7 +1068,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
10671068
alternate_shallow_file = setup_temporary_shallow(si->shallow);
10681069
else
10691070
alternate_shallow_file = NULL;
1070-
if (get_pack(args, fd, pack_lockfile, sought, nr_sought))
1071+
if (get_pack(args, fd, pack_lockfiles, sought, nr_sought))
10711072
die(_("git fetch-pack: fetch failed."));
10721073

10731074
all_done:
@@ -1457,7 +1458,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
14571458
struct ref **sought, int nr_sought,
14581459
struct oid_array *shallows,
14591460
struct shallow_info *si,
1460-
char **pack_lockfile)
1461+
struct string_list *pack_lockfiles)
14611462
{
14621463
struct repository *r = the_repository;
14631464
struct ref *ref = copy_ref_list(orig_ref);
@@ -1559,7 +1560,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
15591560

15601561
/* get the pack */
15611562
process_section_header(&reader, "packfile", 0);
1562-
if (get_pack(args, fd, pack_lockfile, sought, nr_sought))
1563+
if (get_pack(args, fd, pack_lockfiles, sought, nr_sought))
15631564
die(_("git fetch-pack: fetch failed."));
15641565

15651566
state = FETCH_DONE;
@@ -1759,7 +1760,7 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
17591760
const struct ref *ref,
17601761
struct ref **sought, int nr_sought,
17611762
struct oid_array *shallow,
1762-
char **pack_lockfile,
1763+
struct string_list *pack_lockfiles,
17631764
enum protocol_version version)
17641765
{
17651766
struct ref *ref_cpy;
@@ -1794,11 +1795,11 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
17941795
memset(&si, 0, sizeof(si));
17951796
ref_cpy = do_fetch_pack_v2(args, fd, ref, sought, nr_sought,
17961797
&shallows_scratch, &si,
1797-
pack_lockfile);
1798+
pack_lockfiles);
17981799
} else {
17991800
prepare_shallow_info(&si, shallow);
18001801
ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought,
1801-
&si, pack_lockfile);
1802+
&si, pack_lockfiles);
18021803
}
18031804
reprepare_packed_git(the_repository);
18041805

fetch-pack.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
8383
struct ref **sought,
8484
int nr_sought,
8585
struct oid_array *shallow,
86-
char **pack_lockfile,
86+
struct string_list *pack_lockfiles,
8787
enum protocol_version version);
8888

8989
/*

transport-helper.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,10 +410,11 @@ static int fetch_with_fetch(struct transport *transport,
410410
exit(128);
411411

412412
if (skip_prefix(buf.buf, "lock ", &name)) {
413-
if (transport->pack_lockfile)
413+
if (transport->pack_lockfiles.nr)
414414
warning(_("%s also locked %s"), data->name, name);
415415
else
416-
transport->pack_lockfile = xstrdup(name);
416+
string_list_append(&transport->pack_lockfiles,
417+
name);
417418
}
418419
else if (data->check_connectivity &&
419420
data->transport_options.check_self_contained_and_connected &&

transport.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -374,15 +374,15 @@ static int fetch_refs_via_pack(struct transport *transport,
374374
refs = fetch_pack(&args, data->fd,
375375
refs_tmp ? refs_tmp : transport->remote_refs,
376376
to_fetch, nr_heads, &data->shallow,
377-
&transport->pack_lockfile, data->version);
377+
&transport->pack_lockfiles, data->version);
378378
break;
379379
case protocol_v1:
380380
case protocol_v0:
381381
die_if_server_options(transport);
382382
refs = fetch_pack(&args, data->fd,
383383
refs_tmp ? refs_tmp : transport->remote_refs,
384384
to_fetch, nr_heads, &data->shallow,
385-
&transport->pack_lockfile, data->version);
385+
&transport->pack_lockfiles, data->version);
386386
break;
387387
case protocol_unknown_version:
388388
BUG("unknown protocol version");
@@ -929,6 +929,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
929929
struct transport *ret = xcalloc(1, sizeof(*ret));
930930

931931
ret->progress = isatty(2);
932+
string_list_init(&ret->pack_lockfiles, 1);
932933

933934
if (!remote)
934935
BUG("No remote provided to transport_get()");
@@ -1324,10 +1325,11 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs)
13241325

13251326
void transport_unlock_pack(struct transport *transport)
13261327
{
1327-
if (transport->pack_lockfile) {
1328-
unlink_or_warn(transport->pack_lockfile);
1329-
FREE_AND_NULL(transport->pack_lockfile);
1330-
}
1328+
int i;
1329+
1330+
for (i = 0; i < transport->pack_lockfiles.nr; i++)
1331+
unlink_or_warn(transport->pack_lockfiles.items[i].string);
1332+
string_list_clear(&transport->pack_lockfiles, 0);
13311333
}
13321334

13331335
int transport_connect(struct transport *transport, const char *name,

transport.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
#include "run-command.h"
66
#include "remote.h"
77
#include "list-objects-filter-options.h"
8-
9-
struct string_list;
8+
#include "string-list.h"
109

1110
struct git_transport_options {
1211
unsigned thin : 1;
@@ -98,7 +97,8 @@ struct transport {
9897
*/
9998
const struct string_list *server_options;
10099

101-
char *pack_lockfile;
100+
struct string_list pack_lockfiles;
101+
102102
signed verbose : 3;
103103
/**
104104
* Transports should not set this directly, and should use this

0 commit comments

Comments
 (0)