merge(3p/git): Merge git upstream at v2.26.2
This commit is contained in:
commit
5229c9b232
1006 changed files with 149006 additions and 60819 deletions
161
third_party/git/fetch-pack.c
vendored
161
third_party/git/fetch-pack.c
vendored
|
@ -36,7 +36,6 @@ static int agent_supported;
|
|||
static int server_supports_filtering;
|
||||
static struct lock_file shallow_lock;
|
||||
static const char *alternate_shallow_file;
|
||||
static char *negotiation_algorithm;
|
||||
static struct strbuf fsck_msg_types = STRBUF_INIT;
|
||||
|
||||
/* Remember to update object flag allocation in object.h */
|
||||
|
@ -168,16 +167,16 @@ static enum ack_type get_ack(struct packet_reader *reader,
|
|||
if (!strcmp(reader->line, "NAK"))
|
||||
return NAK;
|
||||
if (skip_prefix(reader->line, "ACK ", &arg)) {
|
||||
if (!get_oid_hex(arg, result_oid)) {
|
||||
arg += 40;
|
||||
len -= arg - reader->line;
|
||||
const char *p;
|
||||
if (!parse_oid_hex(arg, result_oid, &p)) {
|
||||
len -= p - reader->line;
|
||||
if (len < 1)
|
||||
return ACK;
|
||||
if (strstr(arg, "continue"))
|
||||
if (strstr(p, "continue"))
|
||||
return ACK_continue;
|
||||
if (strstr(arg, "common"))
|
||||
if (strstr(p, "common"))
|
||||
return ACK_common;
|
||||
if (strstr(arg, "ready"))
|
||||
if (strstr(p, "ready"))
|
||||
return ACK_ready;
|
||||
return ACK;
|
||||
}
|
||||
|
@ -339,12 +338,9 @@ static int find_common(struct fetch_negotiator *negotiator,
|
|||
}
|
||||
}
|
||||
if (server_supports_filtering && args->filter_options.choice) {
|
||||
struct strbuf expanded_filter_spec = STRBUF_INIT;
|
||||
expand_list_objects_filter_spec(&args->filter_options,
|
||||
&expanded_filter_spec);
|
||||
packet_buf_write(&req_buf, "filter %s",
|
||||
expanded_filter_spec.buf);
|
||||
strbuf_release(&expanded_filter_spec);
|
||||
const char *spec =
|
||||
expand_list_objects_filter_spec(&args->filter_options);
|
||||
packet_buf_write(&req_buf, "filter %s", spec);
|
||||
}
|
||||
packet_buf_flush(&req_buf);
|
||||
state_len = req_buf.len;
|
||||
|
@ -386,6 +382,7 @@ static int find_common(struct fetch_negotiator *negotiator,
|
|||
state_len = 0;
|
||||
}
|
||||
|
||||
trace2_region_enter("fetch-pack", "negotiation_v0_v1", the_repository);
|
||||
flushes = 0;
|
||||
retval = -1;
|
||||
if (args->no_dependents)
|
||||
|
@ -470,6 +467,7 @@ static int find_common(struct fetch_negotiator *negotiator,
|
|||
}
|
||||
}
|
||||
done:
|
||||
trace2_region_leave("fetch-pack", "negotiation_v0_v1", the_repository);
|
||||
if (!got_ready || !no_done) {
|
||||
packet_buf_write(&req_buf, "done\n");
|
||||
send_request(args, fd[1], &req_buf);
|
||||
|
@ -671,17 +669,20 @@ static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
|
|||
|
||||
save_commit_buffer = 0;
|
||||
|
||||
trace2_region_enter("fetch-pack", "parse_remote_refs_and_find_cutoff", NULL);
|
||||
for (ref = *refs; ref; ref = ref->next) {
|
||||
struct object *o;
|
||||
|
||||
if (!has_object_file_with_flags(&ref->old_oid,
|
||||
OBJECT_INFO_QUICK))
|
||||
OBJECT_INFO_QUICK |
|
||||
OBJECT_INFO_SKIP_FETCH_OBJECT))
|
||||
continue;
|
||||
o = parse_object(the_repository, &ref->old_oid);
|
||||
if (!o)
|
||||
continue;
|
||||
|
||||
/* We already have it -- which may mean that we were
|
||||
/*
|
||||
* We already have it -- which may mean that we were
|
||||
* in sync with the other side at some time after
|
||||
* that (it is OK if we guess wrong here).
|
||||
*/
|
||||
|
@ -691,7 +692,13 @@ static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
|
|||
cutoff = commit->date;
|
||||
}
|
||||
}
|
||||
trace2_region_leave("fetch-pack", "parse_remote_refs_and_find_cutoff", NULL);
|
||||
|
||||
/*
|
||||
* This block marks all local refs as COMPLETE, and then recursively marks all
|
||||
* parents of those refs as COMPLETE.
|
||||
*/
|
||||
trace2_region_enter("fetch-pack", "mark_complete_local_refs", NULL);
|
||||
if (!args->deepen) {
|
||||
for_each_ref(mark_complete_oid, NULL);
|
||||
for_each_cached_alternate(NULL, mark_alternate_complete);
|
||||
|
@ -699,11 +706,13 @@ static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
|
|||
if (cutoff)
|
||||
mark_recent_complete_commits(args, cutoff);
|
||||
}
|
||||
trace2_region_leave("fetch-pack", "mark_complete_local_refs", NULL);
|
||||
|
||||
/*
|
||||
* Mark all complete remote refs as common refs.
|
||||
* Don't mark them common yet; the server has to be told so first.
|
||||
*/
|
||||
trace2_region_enter("fetch-pack", "mark_common_remote_refs", NULL);
|
||||
for (ref = *refs; ref; ref = ref->next) {
|
||||
struct object *o = deref_tag(the_repository,
|
||||
lookup_object(the_repository,
|
||||
|
@ -716,6 +725,7 @@ static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
|
|||
negotiator->known_common(negotiator,
|
||||
(struct commit *)o);
|
||||
}
|
||||
trace2_region_leave("fetch-pack", "mark_common_remote_refs", NULL);
|
||||
|
||||
save_commit_buffer = old_save_commit_buffer;
|
||||
}
|
||||
|
@ -758,8 +768,33 @@ static int sideband_demux(int in, int out, void *data)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void write_promisor_file(const char *keep_name,
|
||||
struct ref **sought, int nr_sought)
|
||||
{
|
||||
struct strbuf promisor_name = STRBUF_INIT;
|
||||
int suffix_stripped;
|
||||
FILE *output;
|
||||
int i;
|
||||
|
||||
strbuf_addstr(&promisor_name, keep_name);
|
||||
suffix_stripped = strbuf_strip_suffix(&promisor_name, ".keep");
|
||||
if (!suffix_stripped)
|
||||
BUG("name of pack lockfile should end with .keep (was '%s')",
|
||||
keep_name);
|
||||
strbuf_addstr(&promisor_name, ".promisor");
|
||||
|
||||
output = xfopen(promisor_name.buf, "w");
|
||||
for (i = 0; i < nr_sought; i++)
|
||||
fprintf(output, "%s %s\n", oid_to_hex(&sought[i]->old_oid),
|
||||
sought[i]->name);
|
||||
fclose(output);
|
||||
|
||||
strbuf_release(&promisor_name);
|
||||
}
|
||||
|
||||
static int get_pack(struct fetch_pack_args *args,
|
||||
int xd[2], char **pack_lockfile)
|
||||
int xd[2], char **pack_lockfile,
|
||||
struct ref **sought, int nr_sought)
|
||||
{
|
||||
struct async demux;
|
||||
int do_keep = args->keep_pack;
|
||||
|
@ -821,7 +856,13 @@ static int get_pack(struct fetch_pack_args *args,
|
|||
}
|
||||
if (args->check_self_contained_and_connected)
|
||||
argv_array_push(&cmd.args, "--check-self-contained-and-connected");
|
||||
if (args->from_promisor)
|
||||
/*
|
||||
* If we're obtaining the filename of a lockfile, we'll use
|
||||
* that filename to write a .promisor file with more
|
||||
* information below. If not, we need index-pack to do it for
|
||||
* us.
|
||||
*/
|
||||
if (!(do_keep && pack_lockfile) && args->from_promisor)
|
||||
argv_array_push(&cmd.args, "--promisor");
|
||||
}
|
||||
else {
|
||||
|
@ -875,6 +916,14 @@ static int get_pack(struct fetch_pack_args *args,
|
|||
die(_("%s failed"), cmd_name);
|
||||
if (use_sideband && finish_async(&demux))
|
||||
die(_("error in sideband demultiplexer"));
|
||||
|
||||
/*
|
||||
* Now that index-pack has succeeded, write the promisor file using the
|
||||
* obtained .keep filename if necessary
|
||||
*/
|
||||
if (do_keep && pack_lockfile && args->from_promisor)
|
||||
write_promisor_file(*pack_lockfile, sought, nr_sought);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -892,12 +941,20 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
|
|||
struct shallow_info *si,
|
||||
char **pack_lockfile)
|
||||
{
|
||||
struct repository *r = the_repository;
|
||||
struct ref *ref = copy_ref_list(orig_ref);
|
||||
struct object_id oid;
|
||||
const char *agent_feature;
|
||||
int agent_len;
|
||||
struct fetch_negotiator negotiator;
|
||||
fetch_negotiator_init(&negotiator, negotiation_algorithm);
|
||||
struct fetch_negotiator negotiator_alloc;
|
||||
struct fetch_negotiator *negotiator;
|
||||
|
||||
if (args->no_dependents) {
|
||||
negotiator = NULL;
|
||||
} else {
|
||||
negotiator = &negotiator_alloc;
|
||||
fetch_negotiator_init(r, negotiator);
|
||||
}
|
||||
|
||||
sort_ref_list(&ref, ref_compare_name);
|
||||
QSORT(sought, nr_sought, cmp_ref_by_name);
|
||||
|
@ -911,7 +968,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
|
|||
|
||||
if (server_supports("shallow"))
|
||||
print_verbose(args, _("Server supports %s"), "shallow");
|
||||
else if (args->depth > 0 || is_repository_shallow(the_repository))
|
||||
else if (args->depth > 0 || is_repository_shallow(r))
|
||||
die(_("Server does not support shallow clients"));
|
||||
if (args->depth > 0 || args->deepen_since || args->deepen_not)
|
||||
args->deepen = 1;
|
||||
|
@ -984,7 +1041,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
|
|||
die(_("Server does not support --deepen"));
|
||||
|
||||
if (!args->no_dependents) {
|
||||
mark_complete_and_common_ref(&negotiator, args, &ref);
|
||||
mark_complete_and_common_ref(negotiator, args, &ref);
|
||||
filter_refs(args, &ref, sought, nr_sought);
|
||||
if (everything_local(args, &ref)) {
|
||||
packet_flush(fd[1]);
|
||||
|
@ -993,7 +1050,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
|
|||
} else {
|
||||
filter_refs(args, &ref, sought, nr_sought);
|
||||
}
|
||||
if (find_common(&negotiator, args, fd, &oid, ref) < 0)
|
||||
if (find_common(negotiator, args, fd, &oid, ref) < 0)
|
||||
if (!args->keep_pack)
|
||||
/* When cloning, it is not unusual to have
|
||||
* no common commit.
|
||||
|
@ -1009,11 +1066,12 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
|
|||
alternate_shallow_file = setup_temporary_shallow(si->shallow);
|
||||
else
|
||||
alternate_shallow_file = NULL;
|
||||
if (get_pack(args, fd, pack_lockfile))
|
||||
if (get_pack(args, fd, pack_lockfile, sought, nr_sought))
|
||||
die(_("git fetch-pack: fetch failed."));
|
||||
|
||||
all_done:
|
||||
negotiator.release(&negotiator);
|
||||
if (negotiator)
|
||||
negotiator->release(negotiator);
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
@ -1112,7 +1170,7 @@ static int add_haves(struct fetch_negotiator *negotiator,
|
|||
}
|
||||
|
||||
static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out,
|
||||
const struct fetch_pack_args *args,
|
||||
struct fetch_pack_args *args,
|
||||
const struct ref *wants, struct oidset *common,
|
||||
int *haves_to_send, int *in_vain,
|
||||
int sideband_all)
|
||||
|
@ -1153,13 +1211,10 @@ static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out,
|
|||
/* Add filter */
|
||||
if (server_supports_feature("fetch", "filter", 0) &&
|
||||
args->filter_options.choice) {
|
||||
struct strbuf expanded_filter_spec = STRBUF_INIT;
|
||||
const char *spec =
|
||||
expand_list_objects_filter_spec(&args->filter_options);
|
||||
print_verbose(args, _("Server supports filter"));
|
||||
expand_list_objects_filter_spec(&args->filter_options,
|
||||
&expanded_filter_spec);
|
||||
packet_buf_write(&req_buf, "filter %s",
|
||||
expanded_filter_spec.buf);
|
||||
strbuf_release(&expanded_filter_spec);
|
||||
packet_buf_write(&req_buf, "filter %s", spec);
|
||||
} else if (args->filter_options.choice) {
|
||||
warning("filtering not recognized by server, ignoring");
|
||||
}
|
||||
|
@ -1234,7 +1289,8 @@ static int process_acks(struct fetch_negotiator *negotiator,
|
|||
struct commit *commit;
|
||||
oidset_insert(common, &oid);
|
||||
commit = lookup_commit(the_repository, &oid);
|
||||
negotiator->ack(negotiator, commit);
|
||||
if (negotiator)
|
||||
negotiator->ack(negotiator, commit);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -1379,14 +1435,23 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
|
|||
struct shallow_info *si,
|
||||
char **pack_lockfile)
|
||||
{
|
||||
struct repository *r = the_repository;
|
||||
struct ref *ref = copy_ref_list(orig_ref);
|
||||
enum fetch_state state = FETCH_CHECK_LOCAL;
|
||||
struct oidset common = OIDSET_INIT;
|
||||
struct packet_reader reader;
|
||||
int in_vain = 0;
|
||||
int in_vain = 0, negotiation_started = 0;
|
||||
int haves_to_send = INITIAL_FLUSH;
|
||||
struct fetch_negotiator negotiator;
|
||||
fetch_negotiator_init(&negotiator, negotiation_algorithm);
|
||||
struct fetch_negotiator negotiator_alloc;
|
||||
struct fetch_negotiator *negotiator;
|
||||
|
||||
if (args->no_dependents) {
|
||||
negotiator = NULL;
|
||||
} else {
|
||||
negotiator = &negotiator_alloc;
|
||||
fetch_negotiator_init(r, negotiator);
|
||||
}
|
||||
|
||||
packet_reader_init(&reader, fd[0], NULL, 0,
|
||||
PACKET_READ_CHOMP_NEWLINE |
|
||||
PACKET_READ_DIE_ON_ERR_PACKET);
|
||||
|
@ -1410,15 +1475,15 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
|
|||
|
||||
/* Filter 'ref' by 'sought' and those that aren't local */
|
||||
if (!args->no_dependents) {
|
||||
mark_complete_and_common_ref(&negotiator, args, &ref);
|
||||
mark_complete_and_common_ref(negotiator, args, &ref);
|
||||
filter_refs(args, &ref, sought, nr_sought);
|
||||
if (everything_local(args, &ref))
|
||||
state = FETCH_DONE;
|
||||
else
|
||||
state = FETCH_SEND_REQUEST;
|
||||
|
||||
mark_tips(&negotiator, args->negotiation_tips);
|
||||
for_each_cached_alternate(&negotiator,
|
||||
mark_tips(negotiator, args->negotiation_tips);
|
||||
for_each_cached_alternate(negotiator,
|
||||
insert_one_alternate_object);
|
||||
} else {
|
||||
filter_refs(args, &ref, sought, nr_sought);
|
||||
|
@ -1426,7 +1491,13 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
|
|||
}
|
||||
break;
|
||||
case FETCH_SEND_REQUEST:
|
||||
if (send_fetch_request(&negotiator, fd[1], args, ref,
|
||||
if (!negotiation_started) {
|
||||
negotiation_started = 1;
|
||||
trace2_region_enter("fetch-pack",
|
||||
"negotiation_v2",
|
||||
the_repository);
|
||||
}
|
||||
if (send_fetch_request(negotiator, fd[1], args, ref,
|
||||
&common,
|
||||
&haves_to_send, &in_vain,
|
||||
reader.use_sideband))
|
||||
|
@ -1436,7 +1507,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
|
|||
break;
|
||||
case FETCH_PROCESS_ACKS:
|
||||
/* Process ACKs/NAKs */
|
||||
switch (process_acks(&negotiator, &reader, &common)) {
|
||||
switch (process_acks(negotiator, &reader, &common)) {
|
||||
case 2:
|
||||
state = FETCH_GET_PACK;
|
||||
break;
|
||||
|
@ -1449,6 +1520,9 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
|
|||
}
|
||||
break;
|
||||
case FETCH_GET_PACK:
|
||||
trace2_region_leave("fetch-pack",
|
||||
"negotiation_v2",
|
||||
the_repository);
|
||||
/* Check for shallow-info section */
|
||||
if (process_section_header(&reader, "shallow-info", 1))
|
||||
receive_shallow_info(args, &reader, shallows, si);
|
||||
|
@ -1458,7 +1532,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
|
|||
|
||||
/* get the pack */
|
||||
process_section_header(&reader, "packfile", 0);
|
||||
if (get_pack(args, fd, pack_lockfile))
|
||||
if (get_pack(args, fd, pack_lockfile, sought, nr_sought))
|
||||
die(_("git fetch-pack: fetch failed."));
|
||||
|
||||
state = FETCH_DONE;
|
||||
|
@ -1468,7 +1542,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
|
|||
}
|
||||
}
|
||||
|
||||
negotiator.release(&negotiator);
|
||||
if (negotiator)
|
||||
negotiator->release(negotiator);
|
||||
oidset_clear(&common);
|
||||
return ref;
|
||||
}
|
||||
|
@ -1505,8 +1580,6 @@ static void fetch_pack_config(void)
|
|||
git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta);
|
||||
git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects);
|
||||
git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects);
|
||||
git_config_get_string("fetch.negotiationalgorithm",
|
||||
&negotiation_algorithm);
|
||||
|
||||
git_config(fetch_pack_config_cb, NULL);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue