summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2013-03-25 20:26:27 (GMT)
committerJunio C Hamano <gitster@pobox.com>2013-03-27 20:47:18 (GMT)
commit0433ad128c59f233046b3f8a68246ca3a8a77af8 (patch)
treef8d6980d69472867ced6b8d773aa3bcf69a33985
parent0aac7bb287645dd72ad8ad6b805128b8ff7f111f (diff)
downloadgit-0433ad128c59f233046b3f8a68246ca3a8a77af8.zip
git-0433ad128c59f233046b3f8a68246ca3a8a77af8.tar.gz
git-0433ad128c59f233046b3f8a68246ca3a8a77af8.tar.bz2
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 <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/clone.c26
-rwxr-xr-xt/t1060-object-corruption.sh2
-rwxr-xr-xt/t5710-info-alternate.sh8
3 files changed, 28 insertions, 8 deletions
diff --git a/builtin/clone.c b/builtin/clone.c
index 7d48ef3..eceaa74 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -23,6 +23,7 @@
#include "branch.h"
#include "remote.h"
#include "run-command.h"
+#include "connected.h"
/*
* Overall FIXMEs:
@@ -485,12 +486,37 @@ static void write_followtags(const struct ref *refs, const char *msg)
}
}
+static int iterate_ref_map(void *cb_data, unsigned char sha1[20])
+{
+ struct ref **rm = cb_data;
+ struct ref *ref = *rm;
+
+ /*
+ * Skip anything missing a peer_ref, which we are not
+ * actually going to write a ref for.
+ */
+ while (ref && !ref->peer_ref)
+ ref = ref->next;
+ /* Returning -1 notes "end of list" to the caller. */
+ if (!ref)
+ return -1;
+
+ hashcpy(sha1, ref->old_sha1);
+ *rm = ref->next;
+ return 0;
+}
+
static void update_remote_refs(const struct ref *refs,
const struct ref *mapped_refs,
const struct ref *remote_head_points_at,
const char *branch_top,
const char *msg)
{
+ const struct ref *rm = mapped_refs;
+
+ if (check_everything_connected(iterate_ref_map, 0, &rm))
+ die(_("remote did not send all necessary objects"));
+
if (refs) {
write_remote_refs(mapped_refs);
if (option_single_branch)
diff --git a/t/t1060-object-corruption.sh b/t/t1060-object-corruption.sh
index 4e7030e..c65a57c 100755
--- a/t/t1060-object-corruption.sh
+++ b/t/t1060-object-corruption.sh
@@ -79,7 +79,7 @@ test_expect_success 'clone --no-local --bare detects missing object' '
test_must_fail git clone --no-local --bare missing missing-transport
'
-test_expect_failure 'clone --no-local --bare detects misnamed object' '
+test_expect_success 'clone --no-local --bare detects misnamed object' '
test_must_fail git clone --no-local --bare misnamed misnamed-transport
'
diff --git a/t/t5710-info-alternate.sh b/t/t5710-info-alternate.sh
index 5a6e49d..8956c21 100755
--- a/t/t5710-info-alternate.sh
+++ b/t/t5710-info-alternate.sh
@@ -58,13 +58,7 @@ test_expect_success 'creating too deep nesting' \
git clone -l -s D E &&
git clone -l -s E F &&
git clone -l -s F G &&
-git clone --bare -l -s G H'
-
-test_expect_success 'invalidity of deepest repository' \
-'cd H && {
- test_valid_repo
- test $? -ne 0
-}'
+test_must_fail git clone --bare -l -s G H'
cd "$base_dir"