fetch-pack: do not take shallow lock unnecessarily
When fetching using protocol v2, the remote may send a "shallow-info" section if the client is shallow. If so, Git as the client currently takes the shallow file lock, even if the "shallow-info" section is empty. This is not a problem except that Git does not support taking the shallow file lock after modifying the shallow file, because is_repository_shallow() stores information that is never cleared. And this take-after-modify occurs when Git does a tag-following fetch from a shallow repository on a transport that does not support tag following (since in this case, 2 fetches are performed). To solve this issue, take the shallow file lock (and perform all other shallow processing) only if the "shallow-info" section is non-empty; otherwise, behave as if it were empty. A full solution (probably, ensuring that any action of committing shallow file locks also includes clearing the information stored by is_repository_shallow()) would solve the issue without need for this patch, but this patch is independently useful (as an optimization to prevent writing a file in an unnecessary case), hence why I wrote it. I have included a NEEDSWORK outlining the full solution. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
ecbdaf0899
commit
bd0b42aed3
11
fetch-pack.c
11
fetch-pack.c
@ -1232,6 +1232,8 @@ static int process_acks(struct fetch_negotiator *negotiator,
|
||||
static void receive_shallow_info(struct fetch_pack_args *args,
|
||||
struct packet_reader *reader)
|
||||
{
|
||||
int line_received = 0;
|
||||
|
||||
process_section_header(reader, "shallow-info", 0);
|
||||
while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
|
||||
const char *arg;
|
||||
@ -1241,6 +1243,7 @@ static void receive_shallow_info(struct fetch_pack_args *args,
|
||||
if (get_oid_hex(arg, &oid))
|
||||
die(_("invalid shallow line: %s"), reader->line);
|
||||
register_shallow(the_repository, &oid);
|
||||
line_received = 1;
|
||||
continue;
|
||||
}
|
||||
if (skip_prefix(reader->line, "unshallow ", &arg)) {
|
||||
@ -1253,6 +1256,7 @@ static void receive_shallow_info(struct fetch_pack_args *args,
|
||||
die(_("error in object: %s"), reader->line);
|
||||
if (unregister_shallow(&oid))
|
||||
die(_("no shallow found: %s"), reader->line);
|
||||
line_received = 1;
|
||||
continue;
|
||||
}
|
||||
die(_("expected shallow/unshallow, got %s"), reader->line);
|
||||
@ -1262,8 +1266,11 @@ static void receive_shallow_info(struct fetch_pack_args *args,
|
||||
reader->status != PACKET_READ_DELIM)
|
||||
die(_("error processing shallow info: %d"), reader->status);
|
||||
|
||||
setup_alternate_shallow(&shallow_lock, &alternate_shallow_file, NULL);
|
||||
args->deepen = 1;
|
||||
if (line_received) {
|
||||
setup_alternate_shallow(&shallow_lock, &alternate_shallow_file,
|
||||
NULL);
|
||||
args->deepen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void receive_wanted_refs(struct packet_reader *reader,
|
||||
|
||||
Reference in New Issue
Block a user