Skip to content

Commit 565113c

Browse files
committed
Sync with 2.41.2
* maint-2.41: Git 2.41.2 Git 2.40.3 Git 2.39.5 send-email: avoid creating more than one Term::ReadLine object send-email: drop FakeTerm hack 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 babb4e5 + 0d21b34 commit 565113c

File tree

15 files changed

+49
-249
lines changed

15 files changed

+49
-249
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,7 @@ jobs:
278278
cc: clang
279279
pool: macos-13
280280
- jobname: osx-gcc
281-
cc: gcc
282-
cc_package: gcc-13
281+
cc: gcc-13
283282
pool: macos-13
284283
- jobname: linux-gcc-default
285284
cc: gcc

Documentation/RelNotes/2.39.5.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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+
* Some 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.
22+
23+
* Adjust to newer Term::ReadLine to prevent it from breaking
24+
the interactive prompt code in send-email.
25+
(merge c016726c2d jk/send-email-with-new-readline later to maint).

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.

Documentation/RelNotes/2.41.2.txt

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

builtin/clone.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -960,8 +960,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
960960
int filter_submodules = 0;
961961
int hash_algo;
962962
const int do_not_override_repo_unix_permissions = -1;
963-
const char *template_dir;
964-
char *template_dir_dup = NULL;
965963

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

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

1138-
init_db(git_dir, real_git_dir, template_dir, GIT_HASH_UNKNOWN, NULL,
1129+
init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
11391130
do_not_override_repo_unix_permissions, INIT_DB_QUIET);
11401131

11411132
if (real_git_dir) {
@@ -1479,7 +1470,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
14791470
free(dir);
14801471
free(path);
14811472
free(repo_to_free);
1482-
free(template_dir_dup);
1473+
UNLEAK(repo);
14831474
junk_mode = JUNK_LEAVE_ALL;
14841475

14851476
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
@@ -1558,19 +1558,8 @@ static int git_default_core_config(const char *var, const char *value,
15581558
if (!strcmp(var, "core.attributesfile"))
15591559
return git_config_pathname(&git_attributes_file, var, value);
15601560

1561-
if (!strcmp(var, "core.hookspath")) {
1562-
if (ctx->kvi && ctx->kvi->scope == CONFIG_SCOPE_LOCAL &&
1563-
git_env_bool("GIT_CLONE_PROTECTION_ACTIVE", 0))
1564-
die(_("active `core.hooksPath` found in the local "
1565-
"repository config:\n\t%s\nFor security "
1566-
"reasons, this is disallowed by default.\nIf "
1567-
"this is intentional and the hook should "
1568-
"actually be run, please\nrun the command "
1569-
"again with "
1570-
"`GIT_CLONE_PROTECTION_ACTIVE=false`"),
1571-
value);
1561+
if (!strcmp(var, "core.hookspath"))
15721562
return git_config_pathname(&git_hooks_path, var, value);
1573-
}
15741563

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

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
@@ -9,31 +9,6 @@
99
#include "strbuf.h"
1010
#include "environment.h"
1111
#include "setup.h"
12-
#include "copy.h"
13-
14-
static int identical_to_template_hook(const char *name, const char *path)
15-
{
16-
const char *env = getenv("GIT_CLONE_TEMPLATE_DIR");
17-
const char *template_dir = get_template_dir(env && *env ? env : NULL);
18-
struct strbuf template_path = STRBUF_INIT;
19-
int found_template_hook, ret;
20-
21-
strbuf_addf(&template_path, "%s/hooks/%s", template_dir, name);
22-
found_template_hook = access(template_path.buf, X_OK) >= 0;
23-
#ifdef STRIP_EXTENSION
24-
if (!found_template_hook) {
25-
strbuf_addstr(&template_path, STRIP_EXTENSION);
26-
found_template_hook = access(template_path.buf, X_OK) >= 0;
27-
}
28-
#endif
29-
if (!found_template_hook)
30-
return 0;
31-
32-
ret = do_files_match(template_path.buf, path);
33-
34-
strbuf_release(&template_path);
35-
return ret;
36-
}
3712

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

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
@@ -185,19 +185,4 @@ test_expect_success 'stdin to hooks' '
185185
test_cmp expect actual
186186
'
187187

188-
test_expect_success 'clone protections' '
189-
test_config core.hooksPath "$(pwd)/my-hooks" &&
190-
mkdir -p my-hooks &&
191-
write_script my-hooks/test-hook <<-\EOF &&
192-
echo Hook ran $1
193-
EOF
194-
195-
git hook run test-hook 2>err &&
196-
grep "Hook ran" err &&
197-
test_must_fail env GIT_CLONE_PROTECTION_ACTIVE=true \
198-
git hook run test-hook 2>err &&
199-
grep "active .core.hooksPath" err &&
200-
! grep "Hook ran" err
201-
'
202-
203188
test_done

0 commit comments

Comments
 (0)