fetch: in partial clone, check presence of targets
When fetching an object that is known as a promisor object to the local
repository, the connectivity check in quickfetch() in builtin/fetch.c
succeeds, causing object transfer to be bypassed. However, this should
not happen if that object is merely promised and not actually present.
Because this happens, when a user invokes "git fetch origin <sha-1>" on
the command-line, the <sha-1> object may not actually be fetched even
though the command returns an exit code of 0. This is a similar issue
(but with a different cause) to the one fixed by a0c9016abd
("upload-pack: send refs' objects despite "filter"", 2018-07-09).
Therefore, update quickfetch() to also directly check for the presence
of all objects to be fetched. Its documentation and name are also
updated to better reflect what it does.
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
4937291b45
commit
35f9e3e5e7
@ -931,10 +931,11 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
|
||||
* everything we are going to fetch already exists and is connected
|
||||
* locally.
|
||||
*/
|
||||
static int quickfetch(struct ref *ref_map)
|
||||
static int check_exist_and_connected(struct ref *ref_map)
|
||||
{
|
||||
struct ref *rm = ref_map;
|
||||
struct check_connected_options opt = CHECK_CONNECTED_INIT;
|
||||
struct ref *r;
|
||||
|
||||
/*
|
||||
* If we are deepening a shallow clone we already have these
|
||||
@ -945,13 +946,23 @@ static int quickfetch(struct ref *ref_map)
|
||||
*/
|
||||
if (deepen)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* check_connected() allows objects to merely be promised, but
|
||||
* we need all direct targets to exist.
|
||||
*/
|
||||
for (r = rm; r; r = r->next) {
|
||||
if (!has_object_file(&r->old_oid))
|
||||
return -1;
|
||||
}
|
||||
|
||||
opt.quiet = 1;
|
||||
return check_connected(iterate_ref_map, &rm, &opt);
|
||||
}
|
||||
|
||||
static int fetch_refs(struct transport *transport, struct ref *ref_map)
|
||||
{
|
||||
int ret = quickfetch(ref_map);
|
||||
int ret = check_exist_and_connected(ref_map);
|
||||
if (ret)
|
||||
ret = transport_fetch_refs(transport, ref_map);
|
||||
if (!ret)
|
||||
|
Reference in New Issue
Block a user