summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2018-10-19 04:34:04 (GMT)
committerJunio C Hamano <gitster@pobox.com>2018-10-19 04:34:04 (GMT)
commita1e9dff182b19a2620aab036c22389d22b9dd0be (patch)
treeadafb6980bea622e5447f219964e689e679032da
parent4d87b38e6c1a73dbe744a30b9b3cdf88e69de7b4 (diff)
parent35f9e3e5e7a6436b50a8709e7e14a65a10cc1e7a (diff)
downloadgit-a1e9dff182b19a2620aab036c22389d22b9dd0be.zip
git-a1e9dff182b19a2620aab036c22389d22b9dd0be.tar.gz
git-a1e9dff182b19a2620aab036c22389d22b9dd0be.tar.bz2
Merge branch 'jt/fetch-tips-in-partial-clone'
"git fetch $repo $object" in a partial clone did not correctly fetch the asked-for object that is referenced by an object in promisor packfile, which has been fixed. * jt/fetch-tips-in-partial-clone: fetch: in partial clone, check presence of targets connected: document connectivity in partial clones
-rw-r--r--builtin/fetch.c15
-rw-r--r--connected.h6
-rwxr-xr-xt/t5616-partial-clone.sh17
3 files changed, 33 insertions, 5 deletions
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 0696abf..6ce882c 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -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)
diff --git a/connected.h b/connected.h
index e4c9618..8d5a6b3 100644
--- a/connected.h
+++ b/connected.h
@@ -51,9 +51,9 @@ struct check_connected_options {
#define CHECK_CONNECTED_INIT { 0 }
/*
- * Make sure that our object store has all the commits necessary to
- * connect the ancestry chain to some of our existing refs, and all
- * the trees and blobs that these commits use.
+ * Make sure that all given objects and all objects reachable from them
+ * either exist in our object store or (if the repository is a partial
+ * clone) are promised to be available.
*
* Return 0 if Ok, non zero otherwise (i.e. some missing objects)
*
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 6ff6146..6391437 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -182,6 +182,23 @@ test_expect_success 'partial clone fetches blobs pointed to by refs even if norm
git -C dst fsck
'
+test_expect_success 'fetch what is specified on CLI even if already promised' '
+ rm -rf src dst.git &&
+ git init src &&
+ test_commit -C src foo &&
+ test_config -C src uploadpack.allowfilter 1 &&
+ test_config -C src uploadpack.allowanysha1inwant 1 &&
+
+ git hash-object --stdin <src/foo.t >blob &&
+
+ git clone --bare --filter=blob:none "file://$(pwd)/src" dst.git &&
+ git -C dst.git rev-list --objects --quiet --missing=print HEAD >missing_before &&
+ grep "?$(cat blob)" missing_before &&
+ git -C dst.git fetch origin $(cat blob) &&
+ git -C dst.git rev-list --objects --quiet --missing=print HEAD >missing_after &&
+ ! grep "?$(cat blob)" missing_after
+'
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd