mirror of
https://github.com/git/git.git
synced 2024-11-23 09:56:28 +08:00
Merge branch 'fixes/2.45.1/2.41' into fixes/2.45.1/2.42
* fixes/2.45.1/2.41: 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 hack
This commit is contained in:
commit
73339e4dc2
3
.github/workflows/main.yml
vendored
3
.github/workflows/main.yml
vendored
@ -278,8 +278,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
|
||||
|
@ -157,18 +157,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.
|
||||
|
||||
|
@ -960,8 +960,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
int filter_submodules = 0;
|
||||
int hash_algo;
|
||||
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;
|
||||
@ -981,13 +979,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)
|
||||
@ -1135,7 +1126,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
}
|
||||
|
||||
init_db(git_dir, real_git_dir, template_dir, GIT_HASH_UNKNOWN, NULL,
|
||||
init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
|
||||
do_not_override_repo_unix_permissions, INIT_DB_QUIET);
|
||||
|
||||
if (real_git_dir) {
|
||||
@ -1479,7 +1470,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 $HOME/bin
|
||||
(
|
||||
|
13
config.c
13
config.c
@ -1558,19 +1558,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
@ -640,8 +640,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, '\\'))) {
|
||||
@ -1278,56 +1276,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;
|
||||
}
|
||||
|
||||
@ -1426,10 +1374,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) \
|
||||
@ -75,8 +73,6 @@ enum fsck_msg_type {
|
||||
FUNC(NULL_SHA1, WARN) \
|
||||
FUNC(ZERO_PADDED_FILEMODE, WARN) \
|
||||
FUNC(NUL_IN_COMMIT, 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) \
|
||||
@ -144,8 +140,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;
|
||||
};
|
||||
|
||||
@ -155,8 +149,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 { \
|
||||
@ -165,8 +157,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 { \
|
||||
@ -175,8 +165,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
|
||||
|
@ -1050,41 +1050,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 &&
|
||||
grep "Hook ran" err &&
|
||||
test_must_fail env GIT_CLONE_PROTECTION_ACTIVE=true \
|
||||
git hook run test-hook 2>err &&
|
||||
grep "active .core.hooksPath" err &&
|
||||
! grep "Hook ran" err
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -771,57 +771,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 &&
|
||||
! 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 &&
|
||||
! 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 &&
|
||||
! 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 &&
|
||||
! 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 &&
|
||||
! 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
Block a user