Merge branch 'fixes/2.45.1/2.44' into jc/fix-2.45.1-and-friends-for-maint
* fixes/2.45.1/2.44: Revert "fsck: warn about symlink pointing inside a gitdir" Revert "Add a helper function to compare file contents" clone: drop the protections where hooks aren't run tests: verify that `clone -c core.hooksPath=/dev/null` works again Revert "core.hooksPath: add some protection while cloning" init: use the correct path of the templates directory again hook: plug a new memory leak ci: stop installing "gcc-13" for osx-gcc ci: avoid bare "gcc" for osx-gcc job ci: drop mention of BREW_INSTALL_PACKAGES variable send-email: avoid creating more than one Term::ReadLine object send-email: drop FakeTerm hackmaint
						commit
						d36cc0d5a4
					
				|  | @ -284,8 +284,7 @@ jobs: | |||
|             cc: clang | ||||
|             pool: macos-13 | ||||
|           - jobname: osx-gcc | ||||
|             cc: gcc | ||||
|             cc_package: gcc-13 | ||||
|             cc: gcc-13 | ||||
|             pool: macos-13 | ||||
|           - jobname: linux-gcc-default | ||||
|             cc: gcc | ||||
|  |  | |||
|  | @ -164,18 +164,6 @@ | |||
| `nullSha1`:: | ||||
| 	(WARN) Tree contains entries pointing to a null sha1. | ||||
|  | ||||
| `symlinkPointsToGitDir`:: | ||||
| 	(WARN) Symbolic link points inside a gitdir. | ||||
|  | ||||
| `symlinkTargetBlob`:: | ||||
| 	(ERROR) A non-blob found instead of a symbolic link's target. | ||||
|  | ||||
| `symlinkTargetLength`:: | ||||
| 	(WARN) Symbolic link target longer than maximum path length. | ||||
|  | ||||
| `symlinkTargetMissing`:: | ||||
| 	(ERROR) Unable to read symbolic link target's blob. | ||||
|  | ||||
| `treeNotSorted`:: | ||||
| 	(ERROR) A tree is not properly sorted. | ||||
|  | ||||
|  |  | |||
|  | @ -967,8 +967,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix) | |||
| 	int hash_algo; | ||||
| 	unsigned int ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN; | ||||
| 	const int do_not_override_repo_unix_permissions = -1; | ||||
| 	const char *template_dir; | ||||
| 	char *template_dir_dup = NULL; | ||||
|  | ||||
| 	struct transport_ls_refs_options transport_ls_refs_options = | ||||
| 		TRANSPORT_LS_REFS_OPTIONS_INIT; | ||||
|  | @ -988,13 +986,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix) | |||
| 		usage_msg_opt(_("You must specify a repository to clone."), | ||||
| 			builtin_clone_usage, builtin_clone_options); | ||||
|  | ||||
| 	xsetenv("GIT_CLONE_PROTECTION_ACTIVE", "true", 0 /* allow user override */); | ||||
| 	template_dir = get_template_dir(option_template); | ||||
| 	if (*template_dir && !is_absolute_path(template_dir)) | ||||
| 		template_dir = template_dir_dup = | ||||
| 			absolute_pathdup(template_dir); | ||||
| 	xsetenv("GIT_CLONE_TEMPLATE_DIR", template_dir, 1); | ||||
|  | ||||
| 	if (option_depth || option_since || option_not.nr) | ||||
| 		deepen = 1; | ||||
| 	if (option_single_branch == -1) | ||||
|  | @ -1156,7 +1147,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) | |||
| 	 * repository, and reference backends may persist that information into | ||||
| 	 * their on-disk data structures. | ||||
| 	 */ | ||||
| 	init_db(git_dir, real_git_dir, template_dir, GIT_HASH_UNKNOWN, | ||||
| 	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, | ||||
| 		ref_storage_format, NULL, | ||||
| 		do_not_override_repo_unix_permissions, INIT_DB_QUIET | INIT_DB_SKIP_REFDB); | ||||
|  | ||||
|  | @ -1545,7 +1536,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) | |||
| 	free(dir); | ||||
| 	free(path); | ||||
| 	free(repo_to_free); | ||||
| 	free(template_dir_dup); | ||||
| 	UNLEAK(repo); | ||||
| 	junk_mode = JUNK_LEAVE_ALL; | ||||
|  | ||||
| 	transport_ls_refs_options_release(&transport_ls_refs_options); | ||||
|  |  | |||
|  | @ -34,8 +34,6 @@ macos-*) | |||
| 	export HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 | ||||
| 	# Uncomment this if you want to run perf tests: | ||||
| 	# brew install gnu-time | ||||
| 	test -z "$BREW_INSTALL_PACKAGES" || | ||||
| 	brew install $BREW_INSTALL_PACKAGES | ||||
| 	brew link --force gettext | ||||
|  | ||||
| 	mkdir -p "$P4_PATH" | ||||
|  |  | |||
							
								
								
									
										13
									
								
								config.c
								
								
								
								
							
							
						
						
									
										13
									
								
								config.c
								
								
								
								
							|  | @ -1416,19 +1416,8 @@ static int git_default_core_config(const char *var, const char *value, | |||
| 	if (!strcmp(var, "core.attributesfile")) | ||||
| 		return git_config_pathname(&git_attributes_file, var, value); | ||||
|  | ||||
| 	if (!strcmp(var, "core.hookspath")) { | ||||
| 		if (ctx->kvi && ctx->kvi->scope == CONFIG_SCOPE_LOCAL && | ||||
| 		    git_env_bool("GIT_CLONE_PROTECTION_ACTIVE", 0)) | ||||
| 			die(_("active `core.hooksPath` found in the local " | ||||
| 			      "repository config:\n\t%s\nFor security " | ||||
| 			      "reasons, this is disallowed by default.\nIf " | ||||
| 			      "this is intentional and the hook should " | ||||
| 			      "actually be run, please\nrun the command " | ||||
| 			      "again with " | ||||
| 			      "`GIT_CLONE_PROTECTION_ACTIVE=false`"), | ||||
| 			    value); | ||||
| 	if (!strcmp(var, "core.hookspath")) | ||||
| 		return git_config_pathname(&git_hooks_path, var, value); | ||||
| 	} | ||||
|  | ||||
| 	if (!strcmp(var, "core.bare")) { | ||||
| 		is_bare_repository_cfg = git_config_bool(var, value); | ||||
|  |  | |||
							
								
								
									
										58
									
								
								copy.c
								
								
								
								
							
							
						
						
									
										58
									
								
								copy.c
								
								
								
								
							|  | @ -70,61 +70,3 @@ int copy_file_with_time(const char *dst, const char *src, int mode) | |||
| 		return copy_times(dst, src); | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| static int do_symlinks_match(const char *path1, const char *path2) | ||||
| { | ||||
| 	struct strbuf buf1 = STRBUF_INIT, buf2 = STRBUF_INIT; | ||||
| 	int ret = 0; | ||||
|  | ||||
| 	if (!strbuf_readlink(&buf1, path1, 0) && | ||||
| 	    !strbuf_readlink(&buf2, path2, 0)) | ||||
| 		ret = !strcmp(buf1.buf, buf2.buf); | ||||
|  | ||||
| 	strbuf_release(&buf1); | ||||
| 	strbuf_release(&buf2); | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| int do_files_match(const char *path1, const char *path2) | ||||
| { | ||||
| 	struct stat st1, st2; | ||||
| 	int fd1 = -1, fd2 = -1, ret = 1; | ||||
| 	char buf1[8192], buf2[8192]; | ||||
|  | ||||
| 	if ((fd1 = open_nofollow(path1, O_RDONLY)) < 0 || | ||||
| 	    fstat(fd1, &st1) || !S_ISREG(st1.st_mode)) { | ||||
| 		if (fd1 < 0 && errno == ELOOP) | ||||
| 			/* maybe this is a symbolic link? */ | ||||
| 			return do_symlinks_match(path1, path2); | ||||
| 		ret = 0; | ||||
| 	} else if ((fd2 = open_nofollow(path2, O_RDONLY)) < 0 || | ||||
| 		   fstat(fd2, &st2) || !S_ISREG(st2.st_mode)) { | ||||
| 		ret = 0; | ||||
| 	} | ||||
|  | ||||
| 	if (ret) | ||||
| 		/* to match, neither must be executable, or both */ | ||||
| 		ret = !(st1.st_mode & 0111) == !(st2.st_mode & 0111); | ||||
|  | ||||
| 	if (ret) | ||||
| 		ret = st1.st_size == st2.st_size; | ||||
|  | ||||
| 	while (ret) { | ||||
| 		ssize_t len1 = read_in_full(fd1, buf1, sizeof(buf1)); | ||||
| 		ssize_t len2 = read_in_full(fd2, buf2, sizeof(buf2)); | ||||
|  | ||||
| 		if (len1 < 0 || len2 < 0 || len1 != len2) | ||||
| 			ret = 0; /* read error or different file size */ | ||||
| 		else if (!len1) /* len2 is also 0; hit EOF on both */ | ||||
| 			break; /* ret is still true */ | ||||
| 		else | ||||
| 			ret = !memcmp(buf1, buf2, len1); | ||||
| 	} | ||||
|  | ||||
| 	if (fd1 >= 0) | ||||
| 		close(fd1); | ||||
| 	if (fd2 >= 0) | ||||
| 		close(fd2); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										14
									
								
								copy.h
								
								
								
								
							
							
						
						
									
										14
									
								
								copy.h
								
								
								
								
							|  | @ -7,18 +7,4 @@ int copy_fd(int ifd, int ofd); | |||
| int copy_file(const char *dst, const char *src, int mode); | ||||
| int copy_file_with_time(const char *dst, const char *src, int mode); | ||||
|  | ||||
| /* | ||||
|  * Compare the file mode and contents of two given files. | ||||
|  * | ||||
|  * If both files are actually symbolic links, the function returns 1 if the link | ||||
|  * targets are identical or 0 if they are not. | ||||
|  * | ||||
|  * If any of the two files cannot be accessed or in case of read failures, this | ||||
|  * function returns 0. | ||||
|  * | ||||
|  * If the file modes and contents are identical, the function returns 1, | ||||
|  * otherwise it returns 0. | ||||
|  */ | ||||
| int do_files_match(const char *path1, const char *path2); | ||||
|  | ||||
| #endif /* COPY_H */ | ||||
|  |  | |||
							
								
								
									
										56
									
								
								fsck.c
								
								
								
								
							
							
						
						
									
										56
									
								
								fsck.c
								
								
								
								
							|  | @ -658,8 +658,6 @@ static int fsck_tree(const struct object_id *tree_oid, | |||
| 				retval += report(options, tree_oid, OBJ_TREE, | ||||
| 						 FSCK_MSG_MAILMAP_SYMLINK, | ||||
| 						 ".mailmap is a symlink"); | ||||
| 			oidset_insert(&options->symlink_targets_found, | ||||
| 				      entry_oid); | ||||
| 		} | ||||
|  | ||||
| 		if ((backslash = strchr(name, '\\'))) { | ||||
|  | @ -1168,56 +1166,6 @@ static int fsck_blob(const struct object_id *oid, const char *buf, | |||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (oidset_contains(&options->symlink_targets_found, oid)) { | ||||
| 		const char *ptr = buf; | ||||
| 		const struct object_id *reported = NULL; | ||||
|  | ||||
| 		oidset_insert(&options->symlink_targets_done, oid); | ||||
|  | ||||
| 		if (!buf || size > PATH_MAX) { | ||||
| 			/* | ||||
| 			 * A missing buffer here is a sign that the caller found the | ||||
| 			 * blob too gigantic to load into memory. Let's just consider | ||||
| 			 * that an error. | ||||
| 			 */ | ||||
| 			return report(options, oid, OBJ_BLOB, | ||||
| 					FSCK_MSG_SYMLINK_TARGET_LENGTH, | ||||
| 					"symlink target too long"); | ||||
| 		} | ||||
|  | ||||
| 		while (!reported && ptr) { | ||||
| 			const char *p = ptr; | ||||
| 			char c, *slash = strchrnul(ptr, '/'); | ||||
| 			char *backslash = memchr(ptr, '\\', slash - ptr); | ||||
|  | ||||
| 			c = *slash; | ||||
| 			*slash = '\0'; | ||||
|  | ||||
| 			while (!reported && backslash) { | ||||
| 				*backslash = '\0'; | ||||
| 				if (is_ntfs_dotgit(p)) | ||||
| 					ret |= report(options, reported = oid, OBJ_BLOB, | ||||
| 						      FSCK_MSG_SYMLINK_POINTS_TO_GIT_DIR, | ||||
| 						      "symlink target points to git dir"); | ||||
| 				*backslash = '\\'; | ||||
| 				p = backslash + 1; | ||||
| 				backslash = memchr(p, '\\', slash - p); | ||||
| 			} | ||||
| 			if (!reported && is_ntfs_dotgit(p)) | ||||
| 				ret |= report(options, reported = oid, OBJ_BLOB, | ||||
| 					      FSCK_MSG_SYMLINK_POINTS_TO_GIT_DIR, | ||||
| 					      "symlink target points to git dir"); | ||||
|  | ||||
| 			if (!reported && is_hfs_dotgit(ptr)) | ||||
| 				ret |= report(options, reported = oid, OBJ_BLOB, | ||||
| 					      FSCK_MSG_SYMLINK_POINTS_TO_GIT_DIR, | ||||
| 					      "symlink target points to git dir"); | ||||
|  | ||||
| 			*slash = c; | ||||
| 			ptr = c ? slash + 1 : NULL; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
|  | @ -1316,10 +1264,6 @@ int fsck_finish(struct fsck_options *options) | |||
| 			  FSCK_MSG_GITATTRIBUTES_MISSING, FSCK_MSG_GITATTRIBUTES_BLOB, | ||||
| 			  options, ".gitattributes"); | ||||
|  | ||||
| 	ret |= fsck_blobs(&options->symlink_targets_found, &options->symlink_targets_done, | ||||
| 			  FSCK_MSG_SYMLINK_TARGET_MISSING, FSCK_MSG_SYMLINK_TARGET_BLOB, | ||||
| 			  options, "<symlink-target>"); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
|  |  | |||
							
								
								
									
										12
									
								
								fsck.h
								
								
								
								
							
							
						
						
									
										12
									
								
								fsck.h
								
								
								
								
							|  | @ -64,8 +64,6 @@ enum fsck_msg_type { | |||
| 	FUNC(GITATTRIBUTES_LARGE, ERROR) \ | ||||
| 	FUNC(GITATTRIBUTES_LINE_LENGTH, ERROR) \ | ||||
| 	FUNC(GITATTRIBUTES_BLOB, ERROR) \ | ||||
| 	FUNC(SYMLINK_TARGET_MISSING, ERROR) \ | ||||
| 	FUNC(SYMLINK_TARGET_BLOB, ERROR) \ | ||||
| 	/* warnings */ \ | ||||
| 	FUNC(EMPTY_NAME, WARN) \ | ||||
| 	FUNC(FULL_PATHNAME, WARN) \ | ||||
|  | @ -76,8 +74,6 @@ enum fsck_msg_type { | |||
| 	FUNC(ZERO_PADDED_FILEMODE, WARN) \ | ||||
| 	FUNC(NUL_IN_COMMIT, WARN) \ | ||||
| 	FUNC(LARGE_PATHNAME, WARN) \ | ||||
| 	FUNC(SYMLINK_TARGET_LENGTH, WARN) \ | ||||
| 	FUNC(SYMLINK_POINTS_TO_GIT_DIR, WARN) \ | ||||
| 	/* infos (reported as warnings, but ignored by default) */ \ | ||||
| 	FUNC(BAD_FILEMODE, INFO) \ | ||||
| 	FUNC(GITMODULES_PARSE, INFO) \ | ||||
|  | @ -145,8 +141,6 @@ struct fsck_options { | |||
| 	struct oidset gitmodules_done; | ||||
| 	struct oidset gitattributes_found; | ||||
| 	struct oidset gitattributes_done; | ||||
| 	struct oidset symlink_targets_found; | ||||
| 	struct oidset symlink_targets_done; | ||||
| 	kh_oid_map_t *object_names; | ||||
| }; | ||||
|  | ||||
|  | @ -156,8 +150,6 @@ struct fsck_options { | |||
| 	.gitmodules_done = OIDSET_INIT, \ | ||||
| 	.gitattributes_found = OIDSET_INIT, \ | ||||
| 	.gitattributes_done = OIDSET_INIT, \ | ||||
| 	.symlink_targets_found = OIDSET_INIT, \ | ||||
| 	.symlink_targets_done = OIDSET_INIT, \ | ||||
| 	.error_func = fsck_error_function \ | ||||
| } | ||||
| #define FSCK_OPTIONS_STRICT { \ | ||||
|  | @ -166,8 +158,6 @@ struct fsck_options { | |||
| 	.gitmodules_done = OIDSET_INIT, \ | ||||
| 	.gitattributes_found = OIDSET_INIT, \ | ||||
| 	.gitattributes_done = OIDSET_INIT, \ | ||||
| 	.symlink_targets_found = OIDSET_INIT, \ | ||||
| 	.symlink_targets_done = OIDSET_INIT, \ | ||||
| 	.error_func = fsck_error_function, \ | ||||
| } | ||||
| #define FSCK_OPTIONS_MISSING_GITMODULES { \ | ||||
|  | @ -176,8 +166,6 @@ struct fsck_options { | |||
| 	.gitmodules_done = OIDSET_INIT, \ | ||||
| 	.gitattributes_found = OIDSET_INIT, \ | ||||
| 	.gitattributes_done = OIDSET_INIT, \ | ||||
| 	.symlink_targets_found = OIDSET_INIT, \ | ||||
| 	.symlink_targets_done = OIDSET_INIT, \ | ||||
| 	.error_func = fsck_error_cb_print_missing_gitmodules, \ | ||||
| } | ||||
|  | ||||
|  |  | |||
							
								
								
									
										33
									
								
								hook.c
								
								
								
								
							
							
						
						
									
										33
									
								
								hook.c
								
								
								
								
							|  | @ -9,31 +9,6 @@ | |||
| #include "strbuf.h" | ||||
| #include "environment.h" | ||||
| #include "setup.h" | ||||
| #include "copy.h" | ||||
|  | ||||
| static int identical_to_template_hook(const char *name, const char *path) | ||||
| { | ||||
| 	const char *env = getenv("GIT_CLONE_TEMPLATE_DIR"); | ||||
| 	const char *template_dir = get_template_dir(env && *env ? env : NULL); | ||||
| 	struct strbuf template_path = STRBUF_INIT; | ||||
| 	int found_template_hook, ret; | ||||
|  | ||||
| 	strbuf_addf(&template_path, "%s/hooks/%s", template_dir, name); | ||||
| 	found_template_hook = access(template_path.buf, X_OK) >= 0; | ||||
| #ifdef STRIP_EXTENSION | ||||
| 	if (!found_template_hook) { | ||||
| 		strbuf_addstr(&template_path, STRIP_EXTENSION); | ||||
| 		found_template_hook = access(template_path.buf, X_OK) >= 0; | ||||
| 	} | ||||
| #endif | ||||
| 	if (!found_template_hook) | ||||
| 		return 0; | ||||
|  | ||||
| 	ret = do_files_match(template_path.buf, path); | ||||
|  | ||||
| 	strbuf_release(&template_path); | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| const char *find_hook(const char *name) | ||||
| { | ||||
|  | @ -70,14 +45,6 @@ const char *find_hook(const char *name) | |||
| 		} | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	if (!git_hooks_path && git_env_bool("GIT_CLONE_PROTECTION_ACTIVE", 0) && | ||||
| 	    !identical_to_template_hook(name, path.buf)) | ||||
| 		die(_("active `%s` hook found during `git clone`:\n\t%s\n" | ||||
| 		      "For security reasons, this is disallowed by default.\n" | ||||
| 		      "If this is intentional and the hook should actually " | ||||
| 		      "be run, please\nrun the command again with " | ||||
| 		      "`GIT_CLONE_PROTECTION_ACTIVE=false`"), | ||||
| 		    name, path.buf); | ||||
| 	return path.buf; | ||||
| } | ||||
|  | ||||
|  |  | |||
|  | @ -501,16 +501,6 @@ int cmd__path_utils(int argc, const char **argv) | |||
| 		return !!res; | ||||
| 	} | ||||
|  | ||||
| 	if (argc == 4 && !strcmp(argv[1], "do_files_match")) { | ||||
| 		int ret = do_files_match(argv[2], argv[3]); | ||||
|  | ||||
| 		if (ret) | ||||
| 			printf("equal\n"); | ||||
| 		else | ||||
| 			printf("different\n"); | ||||
| 		return !ret; | ||||
| 	} | ||||
|  | ||||
| 	fprintf(stderr, "%s: unknown function name: %s\n", argv[0], | ||||
| 		argv[1] ? argv[1] : "(there was none)"); | ||||
| 	return 1; | ||||
|  |  | |||
|  | @ -610,45 +610,4 @@ test_expect_success !VALGRIND,RUNTIME_PREFIX,CAN_EXEC_IN_PWD '%(prefix)/ works' | |||
| 	test_cmp expect actual | ||||
| ' | ||||
|  | ||||
| test_expect_success 'do_files_match()' ' | ||||
| 	test_seq 0 10 >0-10.txt && | ||||
| 	test_seq -1 10 >-1-10.txt && | ||||
| 	test_seq 1 10 >1-10.txt && | ||||
| 	test_seq 1 9 >1-9.txt && | ||||
| 	test_seq 0 8 >0-8.txt && | ||||
|  | ||||
| 	test-tool path-utils do_files_match 0-10.txt 0-10.txt >out && | ||||
|  | ||||
| 	assert_fails() { | ||||
| 		test_must_fail \ | ||||
| 		test-tool path-utils do_files_match "$1" "$2" >out && | ||||
| 		grep different out | ||||
| 	} && | ||||
|  | ||||
| 	assert_fails 0-8.txt 1-9.txt && | ||||
| 	assert_fails -1-10.txt 0-10.txt && | ||||
| 	assert_fails 1-10.txt 1-9.txt && | ||||
| 	assert_fails 1-10.txt .git && | ||||
| 	assert_fails does-not-exist 1-10.txt && | ||||
|  | ||||
| 	if test_have_prereq FILEMODE | ||||
| 	then | ||||
| 		cp 0-10.txt 0-10.x && | ||||
| 		chmod a+x 0-10.x && | ||||
| 		assert_fails 0-10.txt 0-10.x | ||||
| 	fi && | ||||
|  | ||||
| 	if test_have_prereq SYMLINKS | ||||
| 	then | ||||
| 		ln -sf 0-10.txt symlink && | ||||
| 		ln -s 0-10.txt another-symlink && | ||||
| 		ln -s over-the-ocean yet-another-symlink && | ||||
| 		ln -s "$PWD/0-10.txt" absolute-symlink && | ||||
| 		assert_fails 0-10.txt symlink && | ||||
| 		test-tool path-utils do_files_match symlink another-symlink && | ||||
| 		assert_fails symlink yet-another-symlink && | ||||
| 		assert_fails symlink absolute-symlink | ||||
| 	fi | ||||
| ' | ||||
|  | ||||
| test_done | ||||
|  |  | |||
|  | @ -41,4 +41,11 @@ test_expect_success 'git rev-parse --git-path hooks' ' | |||
| 	test .git/custom-hooks/abc = "$(cat actual)" | ||||
| ' | ||||
|  | ||||
| test_expect_success 'core.hooksPath=/dev/null' ' | ||||
| 	git clone -c core.hooksPath=/dev/null . no-templates && | ||||
| 	value="$(git -C no-templates config --local core.hooksPath)" && | ||||
| 	# The Bash used by Git for Windows rewrites `/dev/null` to `nul` | ||||
| 	{ test /dev/null = "$value" || test nul = "$value"; } | ||||
| ' | ||||
|  | ||||
| test_done | ||||
|  |  | |||
|  | @ -1060,41 +1060,4 @@ test_expect_success 'fsck reports problems in current worktree index without fil | |||
| 	test_cmp expect actual | ||||
| ' | ||||
|  | ||||
| test_expect_success 'fsck warning on symlink target with excessive length' ' | ||||
| 	symlink_target=$(printf "pattern %032769d" 1 | git hash-object -w --stdin) && | ||||
| 	test_when_finished "remove_object $symlink_target" && | ||||
| 	tree=$(printf "120000 blob %s\t%s\n" $symlink_target symlink | git mktree) && | ||||
| 	test_when_finished "remove_object $tree" && | ||||
| 	cat >expected <<-EOF && | ||||
| 	warning in blob $symlink_target: symlinkTargetLength: symlink target too long | ||||
| 	EOF | ||||
| 	git fsck --no-dangling >actual 2>&1 && | ||||
| 	test_cmp expected actual | ||||
| ' | ||||
|  | ||||
| test_expect_success 'fsck warning on symlink target pointing inside git dir' ' | ||||
| 	gitdir=$(printf ".git" | git hash-object -w --stdin) && | ||||
| 	ntfs_gitdir=$(printf "GIT~1" | git hash-object -w --stdin) && | ||||
| 	hfs_gitdir=$(printf ".${u200c}git" | git hash-object -w --stdin) && | ||||
| 	inside_gitdir=$(printf "nested/.git/config" | git hash-object -w --stdin) && | ||||
| 	benign_target=$(printf "legit/config" | git hash-object -w --stdin) && | ||||
| 	tree=$(printf "120000 blob %s\t%s\n" \ | ||||
| 		$benign_target benign_target \ | ||||
| 		$gitdir gitdir \ | ||||
| 		$hfs_gitdir hfs_gitdir \ | ||||
| 		$inside_gitdir inside_gitdir \ | ||||
| 		$ntfs_gitdir ntfs_gitdir | | ||||
| 		git mktree) && | ||||
| 	for o in $gitdir $ntfs_gitdir $hfs_gitdir $inside_gitdir $benign_target $tree | ||||
| 	do | ||||
| 		test_when_finished "remove_object $o" || return 1 | ||||
| 	done && | ||||
| 	printf "warning in blob %s: symlinkPointsToGitDir: symlink target points to git dir\n" \ | ||||
| 		$gitdir $hfs_gitdir $inside_gitdir $ntfs_gitdir | | ||||
| 	sort >expected && | ||||
| 	git fsck --no-dangling >actual 2>&1 && | ||||
| 	sort actual >actual.sorted && | ||||
| 	test_cmp expected actual.sorted | ||||
| ' | ||||
|  | ||||
| test_done | ||||
|  |  | |||
|  | @ -185,19 +185,4 @@ test_expect_success 'stdin to hooks' ' | |||
| 	test_cmp expect actual | ||||
| ' | ||||
|  | ||||
| test_expect_success 'clone protections' ' | ||||
| 	test_config core.hooksPath "$(pwd)/my-hooks" && | ||||
| 	mkdir -p my-hooks && | ||||
| 	write_script my-hooks/test-hook <<-\EOF && | ||||
| 	echo Hook ran $1 | ||||
| 	EOF | ||||
|  | ||||
| 	git hook run test-hook 2>err && | ||||
| 	test_grep "Hook ran" err && | ||||
| 	test_must_fail env GIT_CLONE_PROTECTION_ACTIVE=true \ | ||||
| 		git hook run test-hook 2>err && | ||||
| 	test_grep "active .core.hooksPath" err && | ||||
| 	test_grep ! "Hook ran" err | ||||
| ' | ||||
|  | ||||
| test_done | ||||
|  |  | |||
|  | @ -788,57 +788,6 @@ test_expect_success 'batch missing blob request does not inadvertently try to fe | |||
| 	git clone --filter=blob:limit=0 "file://$(pwd)/server" client | ||||
| ' | ||||
|  | ||||
| test_expect_success 'clone with init.templatedir runs hooks' ' | ||||
| 	git init tmpl/hooks && | ||||
| 	write_script tmpl/hooks/post-checkout <<-EOF && | ||||
| 	echo HOOK-RUN >&2 | ||||
| 	echo I was here >hook.run | ||||
| 	EOF | ||||
| 	git -C tmpl/hooks add . && | ||||
| 	test_tick && | ||||
| 	git -C tmpl/hooks commit -m post-checkout && | ||||
|  | ||||
| 	test_when_finished "git config --global --unset init.templateDir || :" && | ||||
| 	test_when_finished "git config --unset init.templateDir || :" && | ||||
| 	( | ||||
| 		sane_unset GIT_TEMPLATE_DIR && | ||||
| 		NO_SET_GIT_TEMPLATE_DIR=t && | ||||
| 		export NO_SET_GIT_TEMPLATE_DIR && | ||||
|  | ||||
| 		git -c core.hooksPath="$(pwd)/tmpl/hooks" \ | ||||
| 			clone tmpl/hooks hook-run-hookspath 2>err && | ||||
| 		test_grep ! "active .* hook found" err && | ||||
| 		test_path_is_file hook-run-hookspath/hook.run && | ||||
|  | ||||
| 		git -c init.templateDir="$(pwd)/tmpl" \ | ||||
| 			clone tmpl/hooks hook-run-config 2>err && | ||||
| 		test_grep ! "active .* hook found" err && | ||||
| 		test_path_is_file hook-run-config/hook.run && | ||||
|  | ||||
| 		git clone --template=tmpl tmpl/hooks hook-run-option 2>err && | ||||
| 		test_grep ! "active .* hook found" err && | ||||
| 		test_path_is_file hook-run-option/hook.run && | ||||
|  | ||||
| 		git config --global init.templateDir "$(pwd)/tmpl" && | ||||
| 		git clone tmpl/hooks hook-run-global-config 2>err && | ||||
| 		git config --global --unset init.templateDir && | ||||
| 		test_grep ! "active .* hook found" err && | ||||
| 		test_path_is_file hook-run-global-config/hook.run && | ||||
|  | ||||
| 		# clone ignores local `init.templateDir`; need to create | ||||
| 		# a new repository because we deleted `.git/` in the | ||||
| 		# `setup` test case above | ||||
| 		git init local-clone && | ||||
| 		cd local-clone && | ||||
|  | ||||
| 		git config init.templateDir "$(pwd)/../tmpl" && | ||||
| 		git clone ../tmpl/hooks hook-run-local-config 2>err && | ||||
| 		git config --unset init.templateDir && | ||||
| 		test_grep ! "active .* hook found" err && | ||||
| 		test_path_is_missing hook-run-local-config/hook.run | ||||
| 	) | ||||
| ' | ||||
|  | ||||
| . "$TEST_DIRECTORY"/lib-httpd.sh | ||||
| start_httpd | ||||
|  | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano