git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v4 15/28] fetch: add --update-shallow to accept refs that update .git/shallow

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Dec 5, 2013, 13:02 UTC
Message-ID
<1386248575-10206-16-git-send-email-pclouds@gmail.com>
In-Reply-To
<1386248575-10206-1-git-send-email-pclouds@gmail.com>

The same steps are done as in when --update-shallow is not given. The only difference is we now add all shallow commits in "ours" and "theirs" to .git/shallow (aka "step 8").

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/fetch-options.txt |  6 ++++++
 builtin/fetch.c                 |  6 +++++-
 fetch-pack.c                    | 27 +++++++++++++++++++++++++++
 fetch-pack.h                    |  1 +
 t/t5536-fetch-shallow.sh        | 32 ++++++++++++++++++++++++++++++++
 transport.c                     |  4 ++++
 transport.h                     |  4 ++++
 7 files changed, 79 insertions(+), 1 deletion(-)
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index a83d2b4..54043e3 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -21,6 +21,12 @@
 If the source repository is shallow, fetch as much as possible so that
 the current repository has the same history as the source repository.
 
+--update-shallow::
+	By default when fetching from a shallow repository,
+	`git fetch` refuses refs that require updating
+	.git/shallow. This option updates .git/shallow and accept such
+	refs.
+
 ifndef::git-pull[]
 --dry-run::
 	Show what would be done, without making any changes.
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 7b41a7e..d2e4fc0 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -36,7 +36,7 @@ static int prune = -1; /* unspecified */
 
 static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity;
 static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
-static int tags = TAGS_DEFAULT, unshallow;
+static int tags = TAGS_DEFAULT, unshallow, update_shallow;
 static const char *depth;
 static const char *upload_pack;
 static struct strbuf default_rla = STRBUF_INIT;
@@ -104,6 +104,8 @@ static struct option builtin_fetch_options[] = {
 	{ OPTION_STRING, 0, "recurse-submodules-default",
 		   &recurse_submodules_default, NULL,
 		   N_("default mode for recursion"), PARSE_OPT_HIDDEN },
+	OPT_BOOL(0, "update-shallow", &update_shallow,
+		 N_("accept refs that update .git/shallow")),
 	OPT_END()
 };
 
@@ -768,6 +770,8 @@ static struct transport *prepare_transport(struct remote *remote)
 		set_option(transport, TRANS_OPT_KEEP, "yes");
 	if (depth)
 		set_option(transport, TRANS_OPT_DEPTH, depth);
+	if (update_shallow)
+		set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
 	return transport;
 }
 
diff --git a/fetch-pack.c b/fetch-pack.c
index 7c11aff..cd219b8 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -993,6 +993,33 @@ static void update_shallow(struct fetch_pack_args *args,
 		sha1_array_append(&ref, sought[i]->old_sha1);
 	si->ref = &ref;
 
+	if (args->update_shallow) {
+		/*
+		 * remote is also shallow, .git/shallow may be updated
+		 * so all refs can be accepted. Make sure we only add
+		 * shallow roots that are actually reachable from new
+		 * refs.
+		 */
+		struct sha1_array extra = SHA1_ARRAY_INIT;
+		unsigned char (*sha1)[20] = si->shallow->sha1;
+		assign_shallow_commits_to_refs(si, NULL, NULL);
+		if (!si->nr_ours && !si->nr_theirs) {
+			sha1_array_clear(&ref);
+			return;
+		}
+		for (i = 0; i < si->nr_ours; i++)
+			sha1_array_append(&extra, sha1[si->ours[i]]);
+		for (i = 0; i < si->nr_theirs; i++)
+			sha1_array_append(&extra, sha1[si->theirs[i]]);
+		setup_alternate_shallow(&shallow_lock,
+					&alternate_shallow_file,
+					&extra);
+		commit_lock_file(&shallow_lock);
+		sha1_array_clear(&extra);
+		sha1_array_clear(&ref);
+		return;
+	}
+
 	/*
 	 * remote is also shallow, check what ref is safe to update
 	 * without updating .git/shallow
diff --git a/fetch-pack.h b/fetch-pack.h
index ce59537..ada02f5 100644
--- a/fetch-pack.h
+++ b/fetch-pack.h
@@ -23,6 +23,7 @@ struct fetch_pack_args {
 	unsigned check_self_contained_and_connected:1;
 	unsigned self_contained_and_connected:1;
 	unsigned cloning:1;
+	unsigned update_shallow:1;
 };
 
 /*
diff --git a/t/t5536-fetch-shallow.sh b/t/t5536-fetch-shallow.sh
index 022cb2c..3ae9092 100755
--- a/t/t5536-fetch-shallow.sh
+++ b/t/t5536-fetch-shallow.sh
@@ -141,4 +141,36 @@ EOF
 	)
 '
 
+test_expect_success 'fetch --update-shallow' '
+	(
+	cd shallow &&
+	git checkout master &&
+	commit 7 &&
+	git tag -m foo heavy-tag HEAD^ &&
+	git tag light-tag HEAD^:tracked
+	) &&
+	(
+	cd notshallow &&
+	git fetch --update-shallow ../shallow/.git refs/heads/*:refs/remotes/shallow/* &&
+	git fsck &&
+	git for-each-ref --sort=refname --format="%(refname)" >actual.refs &&
+	cat <<EOF >expect.refs &&
+refs/remotes/shallow/master
+refs/remotes/shallow/no-shallow
+refs/tags/heavy-tag
+refs/tags/light-tag
+EOF
+	test_cmp expect.refs actual.refs &&
+	git log --format=%s shallow/master >actual &&
+	cat <<EOF >expect &&
+7
+6
+5
+4
+3
+EOF
+	test_cmp expect actual
+	)
+'
+
 test_done
diff --git a/transport.c b/transport.c
index 491360b..a09fdb6 100644
--- a/transport.c
+++ b/transport.c
@@ -477,6 +477,9 @@ static int set_git_option(struct git_transport_options *opts,
 	} else if (!strcmp(name, TRANS_OPT_KEEP)) {
 		opts->keep = !!value;
 		return 0;
+	} else if (!strcmp(name, TRANS_OPT_UPDATE_SHALLOW)) {
+		opts->update_shallow = !!value;
+		return 0;
 	} else if (!strcmp(name, TRANS_OPT_DEPTH)) {
 		if (!value)
 			opts->depth = 0;
@@ -543,6 +546,7 @@ static int fetch_refs_via_pack(struct transport *transport,
 	args.check_self_contained_and_connected =
 		data->options.check_self_contained_and_connected;
 	args.cloning = transport->cloning;
+	args.update_shallow = data->options.update_shallow;
 
 	if (!data->got_remote_heads) {
 		connect_setup(transport, 0, 0);
diff --git a/transport.h b/transport.h
index 59842d4..02ea248 100644
--- a/transport.h
+++ b/transport.h
@@ -11,6 +11,7 @@ struct git_transport_options {
 	unsigned followtags : 1;
 	unsigned check_self_contained_and_connected : 1;
 	unsigned self_contained_and_connected : 1;
+	unsigned update_shallow : 1;
 	int depth;
 	const char *uploadpack;
 	const char *receivepack;
@@ -152,6 +153,9 @@ struct transport *transport_get(struct remote *, const char *);
 /* Aggressively fetch annotated tags if possible */
 #define TRANS_OPT_FOLLOWTAGS "followtags"
 
+/* Accept refs that may update .git/shallow without --depth */
+#define TRANS_OPT_UPDATE_SHALLOW "updateshallow"
+
 /**
  * Returns 0 if the option was used, non-zero otherwise. Prints a
  * message to stderr if the option is not used.
-- 
1.8.5.1.25.g8667982
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 63 of 79 in “First class shallow clone”
  1. 00/28 First class shallow cloneNguyễn Thái Ngọc Duy, Nov 25, 2013
  2. 01/28 transport.h: remove send_pack prototype, already defined in send-pack.hNguyễn Thái Ngọc Duy, Nov 25, 2013
  3. 02/28 send-pack: forbid pushing from a shallow repositoryNguyễn Thái Ngọc Duy, Nov 25, 2013
  4. 03/28 clone: prevent --reference to a shallow repositoryNguyễn Thái Ngọc Duy, Nov 25, 2013
  5. Eric SunshineNov 26, 2013
  6. 04/28 update-server-info: do not publish shallow clonesNguyễn Thái Ngọc Duy, Nov 25, 2013
  7. Junio C HamanoNov 25, 2013
  8. Duy NguyenNov 26, 2013
  9. 05/28 Advertise shallow graft information on the server endNguyễn Thái Ngọc Duy, Nov 25, 2013
  10. 06/28 connect.c: teach get_remote_heads to parse "shallow" linesNguyễn Thái Ngọc Duy, Nov 25, 2013
  11. Junio C HamanoNov 25, 2013
  12. Junio C HamanoNov 25, 2013
  13. Duy NguyenNov 27, 2013
  14. 07/28 shallow.c: add remove_reachable_shallow_points()Nguyễn Thái Ngọc Duy, Nov 25, 2013
  15. Junio C HamanoNov 25, 2013
  16. 08/28 shallow.c: add mark_new_shallow_refs()Nguyễn Thái Ngọc Duy, Nov 25, 2013
  17. Junio C HamanoNov 25, 2013
  18. Duy NguyenNov 26, 2013
  19. Junio C HamanoNov 26, 2013
  20. 09/28 shallow.c: extend setup_*_shallow() to accept extra shallow pointsNguyễn Thái Ngọc Duy, Nov 25, 2013
  21. Junio C HamanoNov 25, 2013
  22. 10/28 fetch-pack.c: move shallow update code out of fetch_pack()Nguyễn Thái Ngọc Duy, Nov 25, 2013
  23. 11/28 fetch-pack.h: one statement per bitfield declarationNguyễn Thái Ngọc Duy, Nov 25, 2013
  24. 12/28 clone: support remote shallow repositoryNguyễn Thái Ngọc Duy, Nov 25, 2013
  25. 13/28 fetch: support fetching from a shallow repositoryNguyễn Thái Ngọc Duy, Nov 25, 2013
  26. Eric SunshineNov 27, 2013
  27. 14/28 upload-pack: make sure deepening preserves shallow rootsNguyễn Thái Ngọc Duy, Nov 25, 2013
  28. 15/28 fetch: add --update-shallow to get refs that require updating .git/shallowNguyễn Thái Ngọc Duy, Nov 25, 2013
  29. Eric SunshineNov 27, 2013
  30. Duy NguyenNov 27, 2013
  31. Junio C HamanoNov 27, 2013
  32. 16/28 receive-pack: reorder some code in unpack()Nguyễn Thái Ngọc Duy, Nov 25, 2013
  33. Junio C HamanoDec 2, 2013
  34. 17/28 Support pushing from a shallow cloneNguyễn Thái Ngọc Duy, Nov 25, 2013
  35. Eric SunshineNov 26, 2013
  36. 18/28 New var GIT_SHALLOW_FILE to propagate --shallow-file to subprocessesNguyễn Thái Ngọc Duy, Nov 25, 2013
  37. 19/28 connected.c: add new variant that runs with --shallow-fileNguyễn Thái Ngọc Duy, Nov 25, 2013
  38. 20/28 receive-pack: allow pushing with new shallow rootsNguyễn Thái Ngọc Duy, Nov 25, 2013
  39. 21/28 send-pack: support pushing to a shallow cloneNguyễn Thái Ngọc Duy, Nov 25, 2013
  40. 22/28 remote-curl: pass ref SHA-1 to fetch-pack as wellNguyễn Thái Ngọc Duy, Nov 25, 2013
  41. 23/28 Support fetch/clone over httpNguyễn Thái Ngọc Duy, Nov 25, 2013
  42. 24/28 receive-pack: support pushing to a shallow clone via httpNguyễn Thái Ngọc Duy, Nov 25, 2013
  43. 25/28 send-pack: support pushing from a shallow clone via httpNguyễn Thái Ngọc Duy, Nov 25, 2013
  44. 26/28 git-clone.txt: remove shallow clone limitationsNguyễn Thái Ngọc Duy, Nov 25, 2013
  45. 27/28 clone: use git protocol for cloning shallow repo locallyNguyễn Thái Ngọc Duy, Nov 25, 2013
  46. Eric SunshineNov 27, 2013
  47. 28/28 prune: clean .git/shallow after pruning objectsNguyễn Thái Ngọc Duy, Nov 25, 2013
  48. 00/28 First class shallow cloneNguyễn Thái Ngọc Duy, Dec 5, 2013
  49. 01/28 transport.h: remove send_pack prototype, already defined in send-pack.hNguyễn Thái Ngọc Duy, Dec 5, 2013
  50. 02/28 Replace struct extra_have_objects with struct sha1_arrayNguyễn Thái Ngọc Duy, Dec 5, 2013
  51. 03/28 send-pack: forbid pushing from a shallow repositoryNguyễn Thái Ngọc Duy, Dec 5, 2013
  52. 04/28 clone: prevent --reference to a shallow repositoryNguyễn Thái Ngọc Duy, Dec 5, 2013
  53. 05/28 Make the sender advertise shallow commits to the receiverNguyễn Thái Ngọc Duy, Dec 5, 2013
  54. 06/28 connect.c: teach get_remote_heads to parse "shallow" linesNguyễn Thái Ngọc Duy, Dec 5, 2013
  55. 07/28 shallow.c: extend setup_*_shallow() to accept extra shallow commitsNguyễn Thái Ngọc Duy, Dec 5, 2013
  56. 08/28 shallow.c: the 8 steps to select new commits for .git/shallowNguyễn Thái Ngọc Duy, Dec 5, 2013
  57. 09/28 shallow.c: steps 6 and 7 to select new commits for .git/shallowNguyễn Thái Ngọc Duy, Dec 5, 2013
  58. 10/28 fetch-pack.c: move shallow update code out of fetch_pack()Nguyễn Thái Ngọc Duy, Dec 5, 2013
  59. 11/28 fetch-pack.h: one statement per bitfield declarationNguyễn Thái Ngọc Duy, Dec 5, 2013
  60. 12/28 clone: support remote shallow repositoryNguyễn Thái Ngọc Duy, Dec 5, 2013
  61. 13/28 fetch: support fetching from a shallow repositoryNguyễn Thái Ngọc Duy, Dec 5, 2013
  62. 14/28 upload-pack: make sure deepening preserves shallow rootsNguyễn Thái Ngọc Duy, Dec 5, 2013
  63. 15/28 fetch: add --update-shallow to accept refs that update .git/shallowNguyễn Thái Ngọc Duy, Dec 5, 2013
  64. 16/28 receive-pack: reorder some code in unpack()Nguyễn Thái Ngọc Duy, Dec 5, 2013
  65. 17/28 receive/send-pack: support pushing from a shallow cloneNguyễn Thái Ngọc Duy, Dec 5, 2013
  66. 18/28 New var GIT_SHALLOW_FILE to propagate --shallow-file to subprocessesNguyễn Thái Ngọc Duy, Dec 5, 2013
  67. 19/28 connected.c: add new variant that runs with --shallow-fileNguyễn Thái Ngọc Duy, Dec 5, 2013
  68. 20/28 receive-pack: allow pushes that update .git/shallowNguyễn Thái Ngọc Duy, Dec 5, 2013
  69. 21/28 send-pack: support pushing to a shallow cloneNguyễn Thái Ngọc Duy, Dec 5, 2013
  70. 22/28 remote-curl: pass ref SHA-1 to fetch-pack as wellNguyễn Thái Ngọc Duy, Dec 5, 2013
  71. 23/28 Support shallow fetch/clone over smart-httpNguyễn Thái Ngọc Duy, Dec 5, 2013
  72. Jeff KingJan 8, 2014
  73. t5537: fix incorrect expectation in test case 10Nguyễn Thái Ngọc Duy, Jan 8, 2014
  74. Jeff KingJan 9, 2014
  75. 24/28 receive-pack: support pushing to a shallow clone via httpNguyễn Thái Ngọc Duy, Dec 5, 2013
  76. 25/28 send-pack: support pushing from a shallow clone via httpNguyễn Thái Ngọc Duy, Dec 5, 2013
  77. 26/28 clone: use git protocol for cloning shallow repo locallyNguyễn Thái Ngọc Duy, Dec 5, 2013
  78. 27/28 prune: clean .git/shallow after pruning objectsNguyễn Thái Ngọc Duy, Dec 5, 2013
  79. 28/28 git-clone.txt: remove shallow clone limitationsNguyễn Thái Ngọc Duy, Dec 5, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.