Skip to content

Commit 9d6788f

Browse files
committed
Sync with 2.40.3
* maint-2.40: Git 2.40.3 Git 2.39.5 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
2 parents 0f15832 + 4bf5d57 commit 9d6788f

File tree

15 files changed

+39
-250
lines changed

15 files changed

+39
-250
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,7 @@ jobs:
264264
cc: clang
265265
pool: macos-13
266266
- jobname: osx-gcc
267-
cc: gcc
268-
cc_package: gcc-13
267+
cc: gcc-13
269268
pool: macos-13
270269
- jobname: linux-gcc-default
271270
cc: gcc

Documentation/RelNotes/2.39.5.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Git 2.39.5 Release Notes
2+
========================
3+
4+
Relative to Git 2.39.5, this release has fixes for regressions that
5+
were introduced in 2.39.4, most notably the error message shown when
6+
cloning Git LFS-enabled repositories. It also contains a fix for the
7+
`osx-gcc` CI job.
8+
9+
Fixes since Git 2.39.4
10+
----------------------
11+
12+
* The clone protections introduced in v2.39.4 broke Git LFS-enabled
13+
clones and have therefore been dropped.
14+
15+
* The `core.hooksPath` setting is allowed in repository-local
16+
configs again; The benefits of making it protected were
17+
outweighed by the cost.
18+
19+
* Fix a memory leak.
20+
21+
* CI fix.

Documentation/RelNotes/2.40.3.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Git v2.40.3 Release Notes
2+
=========================
3+
4+
This release merges up the regression bug fixes in v2.39.5,
5+
most notably the bug where cloning Git LFS-enabled repositories
6+
failed; see the release notes for that version for details.

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2743,7 +2743,7 @@ exec-cmd.sp exec-cmd.s exec-cmd.o: EXTRA_CPPFLAGS = \
27432743
'-DFALLBACK_RUNTIME_PREFIX="$(prefix_SQ)"'
27442744

27452745
builtin/init-db.sp builtin/init-db.s builtin/init-db.o: GIT-PREFIX
2746-
builtin/init-db.sp builtin/init-db.s builtin/init-db.o: EXTRA_CPPFLAGS = \
2746+
setup.sp setup.s setup.o: EXTRA_CPPFLAGS = \
27472747
-DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"'
27482748

27492749
config.sp config.s config.o: GIT-PREFIX

builtin/clone.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -959,8 +959,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
959959
int submodule_progress;
960960
int filter_submodules = 0;
961961
int hash_algo;
962-
const char *template_dir;
963-
char *template_dir_dup = NULL;
964962

965963
struct transport_ls_refs_options transport_ls_refs_options =
966964
TRANSPORT_LS_REFS_OPTIONS_INIT;
@@ -980,13 +978,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
980978
usage_msg_opt(_("You must specify a repository to clone."),
981979
builtin_clone_usage, builtin_clone_options);
982980

983-
xsetenv("GIT_CLONE_PROTECTION_ACTIVE", "true", 0 /* allow user override */);
984-
template_dir = get_template_dir(option_template);
985-
if (*template_dir && !is_absolute_path(template_dir))
986-
template_dir = template_dir_dup =
987-
absolute_pathdup(template_dir);
988-
xsetenv("GIT_CLONE_TEMPLATE_DIR", template_dir, 1);
989-
990981
if (option_depth || option_since || option_not.nr)
991982
deepen = 1;
992983
if (option_single_branch == -1)
@@ -1134,7 +1125,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
11341125
}
11351126
}
11361127

1137-
init_db(git_dir, real_git_dir, template_dir, GIT_HASH_UNKNOWN, NULL,
1128+
init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
11381129
INIT_DB_QUIET);
11391130

11401131
if (real_git_dir) {
@@ -1478,7 +1469,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
14781469
free(dir);
14791470
free(path);
14801471
free(repo_to_free);
1481-
free(template_dir_dup);
1472+
UNLEAK(repo);
14821473
junk_mode = JUNK_LEAVE_ALL;
14831474

14841475
transport_ls_refs_options_release(&transport_ls_refs_options);

ci/install-dependencies.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ macos-*)
3434
export HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1
3535
# Uncomment this if you want to run perf tests:
3636
# brew install gnu-time
37-
test -z "$BREW_INSTALL_PACKAGES" ||
38-
brew install $BREW_INSTALL_PACKAGES
3937
brew link --force gettext
4038
mkdir -p $HOME/bin
4139
(

config.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,19 +1596,8 @@ static int git_default_core_config(const char *var, const char *value, void *cb)
15961596
if (!strcmp(var, "core.attributesfile"))
15971597
return git_config_pathname(&git_attributes_file, var, value);
15981598

1599-
if (!strcmp(var, "core.hookspath")) {
1600-
if (current_config_scope() == CONFIG_SCOPE_LOCAL &&
1601-
git_env_bool("GIT_CLONE_PROTECTION_ACTIVE", 0))
1602-
die(_("active `core.hooksPath` found in the local "
1603-
"repository config:\n\t%s\nFor security "
1604-
"reasons, this is disallowed by default.\nIf "
1605-
"this is intentional and the hook should "
1606-
"actually be run, please\nrun the command "
1607-
"again with "
1608-
"`GIT_CLONE_PROTECTION_ACTIVE=false`"),
1609-
value);
1599+
if (!strcmp(var, "core.hookspath"))
16101600
return git_config_pathname(&git_hooks_path, var, value);
1611-
}
16121601

16131602
if (!strcmp(var, "core.bare")) {
16141603
is_bare_repository_cfg = git_config_bool(var, value);

copy.c

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -71,61 +71,3 @@ int copy_file_with_time(const char *dst, const char *src, int mode)
7171
return copy_times(dst, src);
7272
return status;
7373
}
74-
75-
static int do_symlinks_match(const char *path1, const char *path2)
76-
{
77-
struct strbuf buf1 = STRBUF_INIT, buf2 = STRBUF_INIT;
78-
int ret = 0;
79-
80-
if (!strbuf_readlink(&buf1, path1, 0) &&
81-
!strbuf_readlink(&buf2, path2, 0))
82-
ret = !strcmp(buf1.buf, buf2.buf);
83-
84-
strbuf_release(&buf1);
85-
strbuf_release(&buf2);
86-
return ret;
87-
}
88-
89-
int do_files_match(const char *path1, const char *path2)
90-
{
91-
struct stat st1, st2;
92-
int fd1 = -1, fd2 = -1, ret = 1;
93-
char buf1[8192], buf2[8192];
94-
95-
if ((fd1 = open_nofollow(path1, O_RDONLY)) < 0 ||
96-
fstat(fd1, &st1) || !S_ISREG(st1.st_mode)) {
97-
if (fd1 < 0 && errno == ELOOP)
98-
/* maybe this is a symbolic link? */
99-
return do_symlinks_match(path1, path2);
100-
ret = 0;
101-
} else if ((fd2 = open_nofollow(path2, O_RDONLY)) < 0 ||
102-
fstat(fd2, &st2) || !S_ISREG(st2.st_mode)) {
103-
ret = 0;
104-
}
105-
106-
if (ret)
107-
/* to match, neither must be executable, or both */
108-
ret = !(st1.st_mode & 0111) == !(st2.st_mode & 0111);
109-
110-
if (ret)
111-
ret = st1.st_size == st2.st_size;
112-
113-
while (ret) {
114-
ssize_t len1 = read_in_full(fd1, buf1, sizeof(buf1));
115-
ssize_t len2 = read_in_full(fd2, buf2, sizeof(buf2));
116-
117-
if (len1 < 0 || len2 < 0 || len1 != len2)
118-
ret = 0; /* read error or different file size */
119-
else if (!len1) /* len2 is also 0; hit EOF on both */
120-
break; /* ret is still true */
121-
else
122-
ret = !memcmp(buf1, buf2, len1);
123-
}
124-
125-
if (fd1 >= 0)
126-
close(fd1);
127-
if (fd2 >= 0)
128-
close(fd2);
129-
130-
return ret;
131-
}

copy.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,4 @@ int copy_fd(int ifd, int ofd);
77
int copy_file(const char *dst, const char *src, int mode);
88
int copy_file_with_time(const char *dst, const char *src, int mode);
99

10-
/*
11-
* Compare the file mode and contents of two given files.
12-
*
13-
* If both files are actually symbolic links, the function returns 1 if the link
14-
* targets are identical or 0 if they are not.
15-
*
16-
* If any of the two files cannot be accessed or in case of read failures, this
17-
* function returns 0.
18-
*
19-
* If the file modes and contents are identical, the function returns 1,
20-
* otherwise it returns 0.
21-
*/
22-
int do_files_match(const char *path1, const char *path2);
23-
2410
#endif /* COPY_H */

hook.c

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,6 @@
88
#include "strbuf.h"
99
#include "environment.h"
1010
#include "setup.h"
11-
#include "copy.h"
12-
13-
static int identical_to_template_hook(const char *name, const char *path)
14-
{
15-
const char *env = getenv("GIT_CLONE_TEMPLATE_DIR");
16-
const char *template_dir = get_template_dir(env && *env ? env : NULL);
17-
struct strbuf template_path = STRBUF_INIT;
18-
int found_template_hook, ret;
19-
20-
strbuf_addf(&template_path, "%s/hooks/%s", template_dir, name);
21-
found_template_hook = access(template_path.buf, X_OK) >= 0;
22-
#ifdef STRIP_EXTENSION
23-
if (!found_template_hook) {
24-
strbuf_addstr(&template_path, STRIP_EXTENSION);
25-
found_template_hook = access(template_path.buf, X_OK) >= 0;
26-
}
27-
#endif
28-
if (!found_template_hook)
29-
return 0;
30-
31-
ret = do_files_match(template_path.buf, path);
32-
33-
strbuf_release(&template_path);
34-
return ret;
35-
}
3611

3712
const char *find_hook(const char *name)
3813
{
@@ -69,14 +44,6 @@ const char *find_hook(const char *name)
6944
}
7045
return NULL;
7146
}
72-
if (!git_hooks_path && git_env_bool("GIT_CLONE_PROTECTION_ACTIVE", 0) &&
73-
!identical_to_template_hook(name, path.buf))
74-
die(_("active `%s` hook found during `git clone`:\n\t%s\n"
75-
"For security reasons, this is disallowed by default.\n"
76-
"If this is intentional and the hook should actually "
77-
"be run, please\nrun the command again with "
78-
"`GIT_CLONE_PROTECTION_ACTIVE=false`"),
79-
name, path.buf);
8047
return path.buf;
8148
}
8249

t/helper/test-path-utils.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -501,16 +501,6 @@ int cmd__path_utils(int argc, const char **argv)
501501
return !!res;
502502
}
503503

504-
if (argc == 4 && !strcmp(argv[1], "do_files_match")) {
505-
int ret = do_files_match(argv[2], argv[3]);
506-
507-
if (ret)
508-
printf("equal\n");
509-
else
510-
printf("different\n");
511-
return !ret;
512-
}
513-
514504
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
515505
argv[1] ? argv[1] : "(there was none)");
516506
return 1;

t/t0060-path-utils.sh

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -610,45 +610,4 @@ test_expect_success !VALGRIND,RUNTIME_PREFIX,CAN_EXEC_IN_PWD '%(prefix)/ works'
610610
test_cmp expect actual
611611
'
612612

613-
test_expect_success 'do_files_match()' '
614-
test_seq 0 10 >0-10.txt &&
615-
test_seq -1 10 >-1-10.txt &&
616-
test_seq 1 10 >1-10.txt &&
617-
test_seq 1 9 >1-9.txt &&
618-
test_seq 0 8 >0-8.txt &&
619-
620-
test-tool path-utils do_files_match 0-10.txt 0-10.txt >out &&
621-
622-
assert_fails() {
623-
test_must_fail \
624-
test-tool path-utils do_files_match "$1" "$2" >out &&
625-
grep different out
626-
} &&
627-
628-
assert_fails 0-8.txt 1-9.txt &&
629-
assert_fails -1-10.txt 0-10.txt &&
630-
assert_fails 1-10.txt 1-9.txt &&
631-
assert_fails 1-10.txt .git &&
632-
assert_fails does-not-exist 1-10.txt &&
633-
634-
if test_have_prereq FILEMODE
635-
then
636-
cp 0-10.txt 0-10.x &&
637-
chmod a+x 0-10.x &&
638-
assert_fails 0-10.txt 0-10.x
639-
fi &&
640-
641-
if test_have_prereq SYMLINKS
642-
then
643-
ln -sf 0-10.txt symlink &&
644-
ln -s 0-10.txt another-symlink &&
645-
ln -s over-the-ocean yet-another-symlink &&
646-
ln -s "$PWD/0-10.txt" absolute-symlink &&
647-
assert_fails 0-10.txt symlink &&
648-
test-tool path-utils do_files_match symlink another-symlink &&
649-
assert_fails symlink yet-another-symlink &&
650-
assert_fails symlink absolute-symlink
651-
fi
652-
'
653-
654613
test_done

t/t1350-config-hooks-path.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,11 @@ test_expect_success 'git rev-parse --git-path hooks' '
4141
test .git/custom-hooks/abc = "$(cat actual)"
4242
'
4343

44+
test_expect_success 'core.hooksPath=/dev/null' '
45+
git clone -c core.hooksPath=/dev/null . no-templates &&
46+
value="$(git -C no-templates config --local core.hooksPath)" &&
47+
# The Bash used by Git for Windows rewrites `/dev/null` to `nul`
48+
{ test /dev/null = "$value" || test nul = "$value"; }
49+
'
50+
4451
test_done

t/t1800-hook.sh

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -195,19 +195,4 @@ test_expect_success 'stdin to hooks' '
195195
test_cmp expect actual
196196
'
197197

198-
test_expect_success 'clone protections' '
199-
test_config core.hooksPath "$(pwd)/my-hooks" &&
200-
mkdir -p my-hooks &&
201-
write_script my-hooks/test-hook <<-\EOF &&
202-
echo Hook ran $1
203-
EOF
204-
205-
git hook run test-hook 2>err &&
206-
grep "Hook ran" err &&
207-
test_must_fail env GIT_CLONE_PROTECTION_ACTIVE=true \
208-
git hook run test-hook 2>err &&
209-
grep "active .core.hooksPath" err &&
210-
! grep "Hook ran" err
211-
'
212-
213198
test_done

t/t5601-clone.sh

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -771,57 +771,6 @@ test_expect_success 'batch missing blob request does not inadvertently try to fe
771771
git clone --filter=blob:limit=0 "file://$(pwd)/server" client
772772
'
773773

774-
test_expect_success 'clone with init.templatedir runs hooks' '
775-
git init tmpl/hooks &&
776-
write_script tmpl/hooks/post-checkout <<-EOF &&
777-
echo HOOK-RUN >&2
778-
echo I was here >hook.run
779-
EOF
780-
git -C tmpl/hooks add . &&
781-
test_tick &&
782-
git -C tmpl/hooks commit -m post-checkout &&
783-
784-
test_when_finished "git config --global --unset init.templateDir || :" &&
785-
test_when_finished "git config --unset init.templateDir || :" &&
786-
(
787-
sane_unset GIT_TEMPLATE_DIR &&
788-
NO_SET_GIT_TEMPLATE_DIR=t &&
789-
export NO_SET_GIT_TEMPLATE_DIR &&
790-
791-
git -c core.hooksPath="$(pwd)/tmpl/hooks" \
792-
clone tmpl/hooks hook-run-hookspath 2>err &&
793-
! grep "active .* hook found" err &&
794-
test_path_is_file hook-run-hookspath/hook.run &&
795-
796-
git -c init.templateDir="$(pwd)/tmpl" \
797-
clone tmpl/hooks hook-run-config 2>err &&
798-
! grep "active .* hook found" err &&
799-
test_path_is_file hook-run-config/hook.run &&
800-
801-
git clone --template=tmpl tmpl/hooks hook-run-option 2>err &&
802-
! grep "active .* hook found" err &&
803-
test_path_is_file hook-run-option/hook.run &&
804-
805-
git config --global init.templateDir "$(pwd)/tmpl" &&
806-
git clone tmpl/hooks hook-run-global-config 2>err &&
807-
git config --global --unset init.templateDir &&
808-
! grep "active .* hook found" err &&
809-
test_path_is_file hook-run-global-config/hook.run &&
810-
811-
# clone ignores local `init.templateDir`; need to create
812-
# a new repository because we deleted `.git/` in the
813-
# `setup` test case above
814-
git init local-clone &&
815-
cd local-clone &&
816-
817-
git config init.templateDir "$(pwd)/../tmpl" &&
818-
git clone ../tmpl/hooks hook-run-local-config 2>err &&
819-
git config --unset init.templateDir &&
820-
! grep "active .* hook found" err &&
821-
test_path_is_missing hook-run-local-config/hook.run
822-
)
823-
'
824-
825774
. "$TEST_DIRECTORY"/lib-httpd.sh
826775
start_httpd
827776

0 commit comments

Comments
 (0)