Skip to content

Commit 0433ad1

Browse files
peffgitster
authored andcommitted
clone: run check_everything_connected
When we fetch from a remote, we do a revision walk to make sure that what we received is connected to our existing history. We do not do the same check for clone, which should be able to check that we received an intact history graph. The upside of this patch is that it will make clone more resilient against propagating repository corruption. The downside is that we will now traverse "rev-list --objects --all" down to the roots, which may take some time (it is especially noticeable for a "--local --bare" clone). Note that we need to adjust t5710, which tries to make such a bogus clone. Rather than checking after the fact that our clone is bogus, we can simplify it to just make sure "git clone" reports failure. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0aac7bb commit 0433ad1

File tree

3 files changed

+28
-8
lines changed

3 files changed

+28
-8
lines changed

builtin/clone.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "branch.h"
2424
#include "remote.h"
2525
#include "run-command.h"
26+
#include "connected.h"
2627

2728
/*
2829
* Overall FIXMEs:
@@ -485,12 +486,37 @@ static void write_followtags(const struct ref *refs, const char *msg)
485486
}
486487
}
487488

489+
static int iterate_ref_map(void *cb_data, unsigned char sha1[20])
490+
{
491+
struct ref **rm = cb_data;
492+
struct ref *ref = *rm;
493+
494+
/*
495+
* Skip anything missing a peer_ref, which we are not
496+
* actually going to write a ref for.
497+
*/
498+
while (ref && !ref->peer_ref)
499+
ref = ref->next;
500+
/* Returning -1 notes "end of list" to the caller. */
501+
if (!ref)
502+
return -1;
503+
504+
hashcpy(sha1, ref->old_sha1);
505+
*rm = ref->next;
506+
return 0;
507+
}
508+
488509
static void update_remote_refs(const struct ref *refs,
489510
const struct ref *mapped_refs,
490511
const struct ref *remote_head_points_at,
491512
const char *branch_top,
492513
const char *msg)
493514
{
515+
const struct ref *rm = mapped_refs;
516+
517+
if (check_everything_connected(iterate_ref_map, 0, &rm))
518+
die(_("remote did not send all necessary objects"));
519+
494520
if (refs) {
495521
write_remote_refs(mapped_refs);
496522
if (option_single_branch)

t/t1060-object-corruption.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ test_expect_success 'clone --no-local --bare detects missing object' '
7979
test_must_fail git clone --no-local --bare missing missing-transport
8080
'
8181

82-
test_expect_failure 'clone --no-local --bare detects misnamed object' '
82+
test_expect_success 'clone --no-local --bare detects misnamed object' '
8383
test_must_fail git clone --no-local --bare misnamed misnamed-transport
8484
'
8585

t/t5710-info-alternate.sh

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,7 @@ test_expect_success 'creating too deep nesting' \
5858
git clone -l -s D E &&
5959
git clone -l -s E F &&
6060
git clone -l -s F G &&
61-
git clone --bare -l -s G H'
62-
63-
test_expect_success 'invalidity of deepest repository' \
64-
'cd H && {
65-
test_valid_repo
66-
test $? -ne 0
67-
}'
61+
test_must_fail git clone --bare -l -s G H'
6862

6963
cd "$base_dir"
7064

0 commit comments

Comments
 (0)