git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH v3 13/28] fetch: support fetching from a shallow repository
Date: Mon, 25 Nov 2013 10:55:39 +0700	[thread overview]
Message-ID: <1385351754-9954-14-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1385351754-9954-1-git-send-email-pclouds@gmail.com>

This patch just put together pieces from the previous patches:

 - Before getting the new pack, we need to remove all new reachable
   shallow roots. The remaining roots may or may not be added to
   .git/shallow.

 - After getting the pack, walk all new refs until they connect to
   current refs, or hit the bottom of current repo, or hit new
   shallow roots.

Those refs that hit new shallow roots are rejected because by default
we do not allow to update .git/shallow (the only exception so far is
cloning from a shallow repo, which is more like creating .git/shallow
than updating it)

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/fetch.c                   |   9 +++
 fetch-pack.c                      |  35 ++++++++++-
 remote.h                          |   1 +
 t/t5536-fetch-shallow.sh (new +x) | 128 ++++++++++++++++++++++++++++++++++++++
 transport.c                       |  11 +++-
 5 files changed, 179 insertions(+), 5 deletions(-)
 create mode 100755 t/t5536-fetch-shallow.sh

diff --git a/builtin/fetch.c b/builtin/fetch.c
index bd7a101..7b41a7e 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -405,6 +405,8 @@ static int iterate_ref_map(void *cb_data, unsigned char sha1[20])
 	struct ref **rm = cb_data;
 	struct ref *ref = *rm;
 
+	while (ref && ref->status == REF_STATUS_REJECT_SHALLOW)
+		ref = ref->next;
 	if (!ref)
 		return -1; /* end of the list */
 	*rm = ref->next;
@@ -451,6 +453,13 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
 			struct ref *ref = NULL;
 			const char *merge_status_marker = "";
 
+			if (rm->status == REF_STATUS_REJECT_SHALLOW) {
+				if (want_status == FETCH_HEAD_MERGE)
+					warning(_("reject %s because shallow roots are not allowed to be updated"),
+						rm->peer_ref ? rm->peer_ref->name : rm->name);
+				continue;
+			}
+
 			commit = lookup_commit_reference_gently(rm->old_sha1, 1);
 			if (!commit)
 				rm->fetch_head_status = FETCH_HEAD_NOT_FOR_MERGE;
diff --git a/fetch-pack.c b/fetch-pack.c
index b76581a..64fa5d2 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -855,7 +855,17 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
 					NULL);
 	else if (args->cloning && shallow && shallow->nr)
 		alternate_shallow_file = setup_temporary_shallow(shallow);
-	else
+	else if (!args->cloning && shallow && shallow->nr) {
+		struct extra_have_objects extra;
+		memset(&extra, 0, sizeof(extra));
+		remove_reachable_shallow_points(&extra, shallow);
+		if (extra.nr) {
+			alternate_shallow_file = setup_temporary_shallow(&extra);
+			free(shallow->array);
+			*shallow = extra;
+		} else
+			alternate_shallow_file = NULL;
+	} else
 		alternate_shallow_file = NULL;
 	if (get_pack(args, fd, pack_lockfile))
 		die("git fetch-pack: fetch failed.");
@@ -929,8 +939,11 @@ static int remove_duplicates_in_refs(struct ref **ref, int nr)
 }
 
 static void update_shallow(struct fetch_pack_args *args,
+			   struct ref **sought, int nr_sought,
 			   struct extra_have_objects *shallow)
 {
+	struct extra_have_objects ref;
+	int *status;
 	int i;
 
 	if (args->depth > 0 && alternate_shallow_file) {
@@ -977,6 +990,24 @@ static void update_shallow(struct fetch_pack_args *args,
 		free(extra.array);
 		return;
 	}
+
+	memset(&ref, 0, sizeof(ref));
+	for (i = 0; i < nr_sought; i++)
+		add_extra_have(&ref, sought[i]->old_sha1);
+
+	status = xcalloc(nr_sought, sizeof(*status));
+
+	/*
+	 * remote is also shallow, check what ref is safe to update
+	 * without updating .git/shallow
+	 */
+	if (mark_new_shallow_refs(&ref, status, NULL, shallow)) {
+		for (i = 0; i < nr_sought; i++)
+			if (status[i])
+				sought[i]->status = REF_STATUS_REJECT_SHALLOW;
+	}
+	free(status);
+	free(ref.array);
 }
 
 struct ref *fetch_pack(struct fetch_pack_args *args,
@@ -1000,6 +1031,6 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
 	ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought,
 				shallow, pack_lockfile);
 	reprepare_packed_git();
-	update_shallow(args, shallow);
+	update_shallow(args, sought, nr_sought, shallow);
 	return ref_cpy;
 }
diff --git a/remote.h b/remote.h
index ff604ff..e519c26 100644
--- a/remote.h
+++ b/remote.h
@@ -109,6 +109,7 @@ struct ref {
 		REF_STATUS_REJECT_FETCH_FIRST,
 		REF_STATUS_REJECT_NEEDS_FORCE,
 		REF_STATUS_REJECT_STALE,
+		REF_STATUS_REJECT_SHALLOW,
 		REF_STATUS_UPTODATE,
 		REF_STATUS_REMOTE_REJECT,
 		REF_STATUS_EXPECTING_REPORT
diff --git a/t/t5536-fetch-shallow.sh b/t/t5536-fetch-shallow.sh
new file mode 100755
index 0000000..41de74d
--- /dev/null
+++ b/t/t5536-fetch-shallow.sh
@@ -0,0 +1,128 @@
+#!/bin/sh
+
+test_description='fetch/clone from a shallow clone'
+
+. ./test-lib.sh
+
+commit() {
+	echo "$1" >tracked &&
+	git add tracked &&
+	git commit -m "$1"
+}
+
+test_expect_success 'setup' '
+	commit 1 &&
+	commit 2 &&
+	commit 3 &&
+	commit 4 &&
+	git config --global transfer.fsckObjects true
+'
+
+test_expect_success 'setup shallow clone' '
+	git clone --no-local --depth=2 .git shallow &&
+	git --git-dir=shallow/.git log --format=%s >actual &&
+	cat <<EOF >expect &&
+4
+3
+EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'clone from shallow clone' '
+	git clone --no-local shallow shallow2 &&
+	(
+	cd shallow2 &&
+	git fsck &&
+	git log --format=%s >actual &&
+	cat <<EOF >expect &&
+4
+3
+EOF
+	test_cmp expect actual
+	)
+'
+
+test_expect_success 'fetch from shallow clone' '
+	(
+	cd shallow &&
+	commit 5
+	) &&
+	(
+	cd shallow2 &&
+	git fetch &&
+	git fsck &&
+	git log --format=%s origin/master >actual &&
+	cat <<EOF >expect &&
+5
+4
+3
+EOF
+	test_cmp expect actual
+	)
+'
+
+test_expect_success 'fetch --depth from shallow clone' '
+	(
+	cd shallow &&
+	commit 6
+	) &&
+	(
+	cd shallow2 &&
+	git fetch --depth=2 &&
+	git fsck &&
+	git log --format=%s origin/master >actual &&
+	cat <<EOF >expect &&
+6
+5
+EOF
+	test_cmp expect actual
+	)
+'
+
+test_expect_success 'fetch something upstream has but hidden by clients shallow boundaries' '
+	# the blob "1" is available in .git but hidden by the
+	# shallow2/.git/shallow and it should be resent
+	! git --git-dir=shallow2/.git cat-file blob `echo 1|git hash-object --stdin` >/dev/null &&
+	echo 1 > 1.t &&
+	git add 1.t &&
+	git commit -m add-1-back &&
+	(
+	cd shallow2 &&
+	git fetch ../.git +refs/heads/master:refs/remotes/top/master &&
+	git fsck &&
+	git log --format=%s top/master >actual &&
+	cat <<EOF >expect &&
+add-1-back
+4
+3
+EOF
+	test_cmp expect actual
+	) &&
+	git --git-dir=shallow2/.git cat-file blob `echo 1|git hash-object --stdin` >/dev/null
+
+'
+
+test_expect_success 'fetch that requires changes in .git/shallow is filtered' '
+	(
+	cd shallow &&
+	git checkout --orphan no-shallow &&
+	commit no-shallow
+	) &&
+	git init notshallow &&
+	(
+	cd notshallow &&
+	git fetch ../shallow/.git refs/heads/*:refs/remotes/shallow/*&&
+	git for-each-ref --format="%(refname)" >actual.refs &&
+	cat <<EOF >expect.refs &&
+refs/remotes/shallow/no-shallow
+EOF
+	test_cmp expect.refs actual.refs &&
+	git log --format=%s shallow/no-shallow >actual &&
+	cat <<EOF >expect &&
+no-shallow
+EOF
+	test_cmp expect actual
+	)
+'
+
+test_done
diff --git a/transport.c b/transport.c
index fa3dc16..d6d14eb 100644
--- a/transport.c
+++ b/transport.c
@@ -514,7 +514,7 @@ static struct ref *get_refs_via_connect(struct transport *transport, int for_pus
 	get_remote_heads(data->fd[0], NULL, 0, &refs,
 			 for_push ? REF_NORMAL : 0,
 			 &data->extra_have,
-			 transport->cloning ? &data->shallow : NULL);
+			 &data->shallow);
 	data->got_remote_heads = 1;
 
 	return refs;
@@ -546,8 +546,7 @@ static int fetch_refs_via_pack(struct transport *transport,
 	if (!data->got_remote_heads) {
 		connect_setup(transport, 0, 0);
 		get_remote_heads(data->fd[0], NULL, 0, &refs_tmp, 0,
-				 NULL,
-				 transport->cloning ? &data->shallow : NULL);
+				 NULL, &data->shallow);
 		data->got_remote_heads = 1;
 	}
 
@@ -719,6 +718,10 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count, i
 		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
 						 "stale info", porcelain);
 		break;
+	case REF_STATUS_REJECT_SHALLOW:
+		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
+						 "new shallow roots not allowed", porcelain);
+		break;
 	case REF_STATUS_REMOTE_REJECT:
 		print_ref_status('!', "[remote rejected]", ref,
 						 ref->deletion ? NULL : ref->peer_ref,
@@ -814,6 +817,8 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
 		get_remote_heads(data->fd[0], NULL, 0, &tmp_refs, REF_NORMAL, NULL, NULL);
 		data->got_remote_heads = 1;
 	}
+	if (data->shallow.nr)
+		die("pushing to a shallow repository is not supported");
 
 	memset(&args, 0, sizeof(args));
 	args.send_mirror = !!(flags & TRANSPORT_PUSH_MIRROR);
-- 
1.8.2.83.gc99314b

  parent reply	other threads:[~2013-11-25  3:52 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-25  3:55 [PATCH v3 00/28] First class shallow clone Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 01/28] transport.h: remove send_pack prototype, already defined in send-pack.h Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 02/28] send-pack: forbid pushing from a shallow repository Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 03/28] clone: prevent --reference to " Nguyễn Thái Ngọc Duy
2013-11-26  5:52   ` Eric Sunshine
2013-11-25  3:55 ` [PATCH v3 04/28] update-server-info: do not publish shallow clones Nguyễn Thái Ngọc Duy
2013-11-25 20:08   ` Junio C Hamano
2013-11-26 12:41     ` Duy Nguyen
2013-11-25  3:55 ` [PATCH v3 05/28] Advertise shallow graft information on the server end Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 06/28] connect.c: teach get_remote_heads to parse "shallow" lines Nguyễn Thái Ngọc Duy
2013-11-25 21:42   ` Junio C Hamano
2013-11-25 22:42     ` Junio C Hamano
2013-11-27 13:02       ` Duy Nguyen
2013-11-25  3:55 ` [PATCH v3 07/28] shallow.c: add remove_reachable_shallow_points() Nguyễn Thái Ngọc Duy
2013-11-25 21:53   ` Junio C Hamano
2013-11-25  3:55 ` [PATCH v3 08/28] shallow.c: add mark_new_shallow_refs() Nguyễn Thái Ngọc Duy
2013-11-25 22:20   ` Junio C Hamano
2013-11-26 13:18     ` Duy Nguyen
2013-11-26 22:20       ` Junio C Hamano
2013-11-25  3:55 ` [PATCH v3 09/28] shallow.c: extend setup_*_shallow() to accept extra shallow points Nguyễn Thái Ngọc Duy
2013-11-25 22:25   ` Junio C Hamano
2013-11-25  3:55 ` [PATCH v3 10/28] fetch-pack.c: move shallow update code out of fetch_pack() Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 11/28] fetch-pack.h: one statement per bitfield declaration Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 12/28] clone: support remote shallow repository Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` Nguyễn Thái Ngọc Duy [this message]
2013-11-27  9:47   ` [PATCH v3 13/28] fetch: support fetching from a " Eric Sunshine
2013-11-25  3:55 ` [PATCH v3 14/28] upload-pack: make sure deepening preserves shallow roots Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 15/28] fetch: add --update-shallow to get refs that require updating .git/shallow Nguyễn Thái Ngọc Duy
2013-11-27  1:53   ` Eric Sunshine
2013-11-27 12:54     ` Duy Nguyen
2013-11-27 19:04       ` Junio C Hamano
2013-11-25  3:55 ` [PATCH v3 16/28] receive-pack: reorder some code in unpack() Nguyễn Thái Ngọc Duy
2013-12-02 22:25   ` Junio C Hamano
2013-11-25  3:55 ` [PATCH v3 17/28] Support pushing from a shallow clone Nguyễn Thái Ngọc Duy
2013-11-26 20:38   ` Eric Sunshine
2013-11-25  3:55 ` [PATCH v3 18/28] New var GIT_SHALLOW_FILE to propagate --shallow-file to subprocesses Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 19/28] connected.c: add new variant that runs with --shallow-file Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 20/28] receive-pack: allow pushing with new shallow roots Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 21/28] send-pack: support pushing to a shallow clone Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 22/28] remote-curl: pass ref SHA-1 to fetch-pack as well Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 23/28] Support fetch/clone over http Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 24/28] receive-pack: support pushing to a shallow clone via http Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 25/28] send-pack: support pushing from " Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 26/28] git-clone.txt: remove shallow clone limitations Nguyễn Thái Ngọc Duy
2013-11-25  3:55 ` [PATCH v3 27/28] clone: use git protocol for cloning shallow repo locally Nguyễn Thái Ngọc Duy
2013-11-27  1:36   ` Eric Sunshine
2013-11-25  3:55 ` [PATCH v3 28/28] prune: clean .git/shallow after pruning objects Nguyễn Thái Ngọc Duy
2013-12-05 13:02 ` [PATCH v4 00/28] First class shallow clone Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 01/28] transport.h: remove send_pack prototype, already defined in send-pack.h Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 02/28] Replace struct extra_have_objects with struct sha1_array Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 03/28] send-pack: forbid pushing from a shallow repository Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 04/28] clone: prevent --reference to " Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 05/28] Make the sender advertise shallow commits to the receiver Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 06/28] connect.c: teach get_remote_heads to parse "shallow" lines Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 07/28] shallow.c: extend setup_*_shallow() to accept extra shallow commits Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 08/28] shallow.c: the 8 steps to select new commits for .git/shallow Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 09/28] shallow.c: steps 6 and 7 " Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 10/28] fetch-pack.c: move shallow update code out of fetch_pack() Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 11/28] fetch-pack.h: one statement per bitfield declaration Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 12/28] clone: support remote shallow repository Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 13/28] fetch: support fetching from a " Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 14/28] upload-pack: make sure deepening preserves shallow roots Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 15/28] fetch: add --update-shallow to accept refs that update .git/shallow Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 16/28] receive-pack: reorder some code in unpack() Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 17/28] receive/send-pack: support pushing from a shallow clone Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 18/28] New var GIT_SHALLOW_FILE to propagate --shallow-file to subprocesses Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 19/28] connected.c: add new variant that runs with --shallow-file Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 20/28] receive-pack: allow pushes that update .git/shallow Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 21/28] send-pack: support pushing to a shallow clone Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 22/28] remote-curl: pass ref SHA-1 to fetch-pack as well Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 23/28] Support shallow fetch/clone over smart-http Nguyễn Thái Ngọc Duy
2014-01-08 11:25     ` Jeff King
2014-01-08 12:13       ` [PATCH] t5537: fix incorrect expectation in test case 10 Nguyễn Thái Ngọc Duy
2014-01-09 21:57         ` Jeff King
2013-12-05 13:02   ` [PATCH v4 24/28] receive-pack: support pushing to a shallow clone via http Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 25/28] send-pack: support pushing from " Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 26/28] clone: use git protocol for cloning shallow repo locally Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 27/28] prune: clean .git/shallow after pruning objects Nguyễn Thái Ngọc Duy
2013-12-05 13:02   ` [PATCH v4 28/28] git-clone.txt: remove shallow clone limitations Nguyễn Thái Ngọc Duy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1385351754-9954-14-git-send-email-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).