fetch: support hideRefs to speed up connectivity checks
With roughly 800 remotes all fetching into their own refs/remotes/$REMOTE/* island, the connectivity check[1] gets expensive for each fetch on systems which lack sufficient RAM to cache objects. To do a no-op fetch on one $REMOTE out of hundreds, hideRefs now allows the no-op fetch to take ~30 seconds instead of ~20 minutes on a noisy, RAM-constrained machine (localhost, so no network latency): git -c fetch.hideRefs=refs \ -c fetch.hideRefs='!refs/remotes/$REMOTE/' \ fetch $REMOTE [1] `git rev-list --objects --stdin --not --all --quiet --alternate-refs' Signed-off-by: Eric Wong <e@80x24.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									dadc8e6dac
								
							
						
					
					
						commit
						c6ce27ab08
					
				|  | @ -197,10 +197,11 @@ respectively, and they must begin with `refs/` when applied to `--glob` | ||||||
| or `--all`. If a trailing '/{asterisk}' is intended, it must be given | or `--all`. If a trailing '/{asterisk}' is intended, it must be given | ||||||
| explicitly. | explicitly. | ||||||
|  |  | ||||||
| --exclude-hidden=[receive|uploadpack]:: | --exclude-hidden=[fetch|receive|uploadpack]:: | ||||||
| 	Do not include refs that would be hidden by `git-receive-pack` or | 	Do not include refs that would be hidden by `git-fetch`, | ||||||
| 	`git-upload-pack` by consulting the appropriate `receive.hideRefs` or | 	`git-receive-pack` or `git-upload-pack` by consulting the appropriate | ||||||
| 	`uploadpack.hideRefs` configuration along with `transfer.hideRefs` (see | 	`fetch.hideRefs`, `receive.hideRefs` or `uploadpack.hideRefs` | ||||||
|  | 	configuration along with `transfer.hideRefs` (see | ||||||
| 	linkgit:git-config[1]). This option affects the next pseudo-ref option | 	linkgit:git-config[1]). This option affects the next pseudo-ref option | ||||||
| 	`--all` or `--glob` and is cleared after processing them. | 	`--all` or `--glob` and is cleared after processing them. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -195,10 +195,11 @@ respectively, and they must begin with `refs/` when applied to `--glob` | ||||||
| or `--all`. If a trailing '/{asterisk}' is intended, it must be given | or `--all`. If a trailing '/{asterisk}' is intended, it must be given | ||||||
| explicitly. | explicitly. | ||||||
|  |  | ||||||
| --exclude-hidden=[receive|uploadpack]:: | --exclude-hidden=[fetch|receive|uploadpack]:: | ||||||
| 	Do not include refs that would be hidden by `git-receive-pack` or | 	Do not include refs that would be hidden by `git-fetch`, | ||||||
| 	`git-upload-pack` by consulting the appropriate `receive.hideRefs` or | 	`git-receive-pack` or `git-upload-pack` by consulting the appropriate | ||||||
| 	`uploadpack.hideRefs` configuration along with `transfer.hideRefs` (see | 	`fetch.hideRefs`, `receive.hideRefs` or `uploadpack.hideRefs` | ||||||
|  | 	configuration along with `transfer.hideRefs` (see | ||||||
| 	linkgit:git-config[1]). This option affects the next pseudo-ref option | 	linkgit:git-config[1]). This option affects the next pseudo-ref option | ||||||
| 	`--all` or `--glob` and is cleared after processing them. | 	`--all` or `--glob` and is cleared after processing them. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -1132,6 +1132,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name, | ||||||
| 	if (!connectivity_checked) { | 	if (!connectivity_checked) { | ||||||
| 		struct check_connected_options opt = CHECK_CONNECTED_INIT; | 		struct check_connected_options opt = CHECK_CONNECTED_INIT; | ||||||
|  |  | ||||||
|  | 		opt.exclude_hidden_refs_section = "fetch"; | ||||||
| 		rm = ref_map; | 		rm = ref_map; | ||||||
| 		if (check_connected(iterate_ref_map, &rm, &opt)) { | 		if (check_connected(iterate_ref_map, &rm, &opt)) { | ||||||
| 			rc = error(_("%s did not send all necessary objects\n"), url); | 			rc = error(_("%s did not send all necessary objects\n"), url); | ||||||
|  | @ -1325,6 +1326,7 @@ static int check_exist_and_connected(struct ref *ref_map) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	opt.quiet = 1; | 	opt.quiet = 1; | ||||||
|  | 	opt.exclude_hidden_refs_section = "fetch"; | ||||||
| 	return check_connected(iterate_ref_map, &rm, &opt); | 	return check_connected(iterate_ref_map, &rm, &opt); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -38,7 +38,7 @@ static const char rev_list_usage[] = | ||||||
| "    --tags\n" | "    --tags\n" | ||||||
| "    --remotes\n" | "    --remotes\n" | ||||||
| "    --stdin\n" | "    --stdin\n" | ||||||
| "    --exclude-hidden=[receive|uploadpack]\n" | "    --exclude-hidden=[fetch|receive|uploadpack]\n" | ||||||
| "    --quiet\n" | "    --quiet\n" | ||||||
| "  ordering output:\n" | "  ordering output:\n" | ||||||
| "    --topo-order\n" | "    --topo-order\n" | ||||||
|  |  | ||||||
|  | @ -1574,7 +1574,8 @@ void exclude_hidden_refs(struct ref_exclusions *exclusions, const char *section) | ||||||
| { | { | ||||||
| 	struct exclude_hidden_refs_cb cb; | 	struct exclude_hidden_refs_cb cb; | ||||||
|  |  | ||||||
| 	if (strcmp(section, "receive") && strcmp(section, "uploadpack")) | 	if (strcmp(section, "fetch") && strcmp(section, "receive") && | ||||||
|  | 			strcmp(section, "uploadpack")) | ||||||
| 		die(_("unsupported section for hidden refs: %s"), section); | 		die(_("unsupported section for hidden refs: %s"), section); | ||||||
|  |  | ||||||
| 	if (exclusions->hidden_refs_configured) | 	if (exclusions->hidden_refs_configured) | ||||||
|  |  | ||||||
|  | @ -1171,6 +1171,15 @@ test_expect_success '--no-show-forced-updates' ' | ||||||
| 	) | 	) | ||||||
| ' | ' | ||||||
|  |  | ||||||
|  | for section in fetch transfer | ||||||
|  | do | ||||||
|  | 	test_expect_success "$section.hideRefs affects connectivity check" ' | ||||||
|  | 		GIT_TRACE="$PWD"/trace git -c $section.hideRefs=refs -c \ | ||||||
|  | 			$section.hideRefs="!refs/tags/" fetch && | ||||||
|  | 		grep "git rev-list .*--exclude-hidden=fetch" trace | ||||||
|  | 	' | ||||||
|  | done | ||||||
|  |  | ||||||
| setup_negotiation_tip () { | setup_negotiation_tip () { | ||||||
| 	SERVER="$1" | 	SERVER="$1" | ||||||
| 	URL="$2" | 	URL="$2" | ||||||
|  |  | ||||||
|  | @ -187,7 +187,7 @@ test_expect_success 'rev-parse --exclude=ref with --remotes=glob' ' | ||||||
| 	compare rev-parse "--exclude=upstream/x --remotes=upstream/*" "upstream/one upstream/two" | 	compare rev-parse "--exclude=upstream/x --remotes=upstream/*" "upstream/one upstream/two" | ||||||
| ' | ' | ||||||
|  |  | ||||||
| for section in receive uploadpack | for section in fetch receive uploadpack | ||||||
| do | do | ||||||
| 	test_expect_success "rev-parse --exclude-hidden=$section with --all" ' | 	test_expect_success "rev-parse --exclude-hidden=$section with --all" ' | ||||||
| 		compare "-c transfer.hideRefs=refs/remotes/ rev-parse" "--branches --tags" "--exclude-hidden=$section --all" | 		compare "-c transfer.hideRefs=refs/remotes/ rev-parse" "--branches --tags" "--exclude-hidden=$section --all" | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ test_expect_success 'invalid section' ' | ||||||
| 	test_cmp expected err | 	test_cmp expected err | ||||||
| ' | ' | ||||||
|  |  | ||||||
| for section in receive uploadpack | for section in fetch receive uploadpack | ||||||
| do | do | ||||||
| 	test_expect_success "$section: passed multiple times" ' | 	test_expect_success "$section: passed multiple times" ' | ||||||
| 		echo "fatal: --exclude-hidden= passed more than once" >expected && | 		echo "fatal: --exclude-hidden= passed more than once" >expected && | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Eric Wong
						Eric Wong