Skip to content

Commit eb3c027

Browse files
matheustavaresgitster
authored andcommitted
apply: don't use core.sharedRepository to create working tree files
core.sharedRepository defines which permissions Git should set when creating files in $GIT_DIR, so that the repository may be shared with other users. But (in its current form) the setting shouldn't affect how files are created in the working tree. This is not respected by apply and am (which uses apply), when creating leading directories: $ cat d.patch diff --git a/d/f b/d/f new file mode 100644 index 0000000..e69de29 Apply without the setting: $ umask 0077 $ git apply d.patch $ ls -ld d drwx------ Apply with the setting: $ umask 0077 $ git -c core.sharedRepository=0770 apply d.patch $ ls -ld d drwxrws--- Only the leading directories are affected. That's because they are created with safe_create_leading_directories(), which calls adjust_shared_perm() to set the directories' permissions based on core.sharedRepository. To fix that, let's introduce a variant of this function that ignores the setting, and use it in apply. Also add a regression test and a note in the function documentation about the use of each variant according to the destination (working tree or git dir). Signed-off-by: Matheus Tavares <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 898f807 commit eb3c027

File tree

5 files changed

+47
-6
lines changed

5 files changed

+47
-6
lines changed

apply.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4409,7 +4409,7 @@ static int create_one_file(struct apply_state *state,
44094409
return 0;
44104410

44114411
if (errno == ENOENT) {
4412-
if (safe_create_leading_directories(path))
4412+
if (safe_create_leading_directories_no_share(path))
44134413
return 0;
44144414
res = try_create_file(state, path, mode, buf, size);
44154415
if (res < 0)

cache.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,11 @@ int adjust_shared_perm(const char *path);
12551255
* safe_create_leading_directories() temporarily changes path while it
12561256
* is working but restores it before returning.
12571257
* safe_create_leading_directories_const() doesn't modify path, even
1258-
* temporarily.
1258+
* temporarily. Both these variants adjust the permissions of the
1259+
* created directories to honor core.sharedRepository, so they are best
1260+
* suited for files inside the git dir. For working tree files, use
1261+
* safe_create_leading_directories_no_share() instead, as it ignores
1262+
* the core.sharedRepository setting.
12591263
*/
12601264
enum scld_error {
12611265
SCLD_OK = 0,
@@ -1266,6 +1270,7 @@ enum scld_error {
12661270
};
12671271
enum scld_error safe_create_leading_directories(char *path);
12681272
enum scld_error safe_create_leading_directories_const(const char *path);
1273+
enum scld_error safe_create_leading_directories_no_share(char *path);
12691274

12701275
/*
12711276
* Callback function for raceproof_create_file(). This function is

sha1-file.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ int mkdir_in_gitdir(const char *path)
291291
return adjust_shared_perm(path);
292292
}
293293

294-
enum scld_error safe_create_leading_directories(char *path)
294+
static enum scld_error safe_create_leading_directories_1(char *path, int share)
295295
{
296296
char *next_component = path + offset_1st_component(path);
297297
enum scld_error ret = SCLD_OK;
@@ -337,14 +337,24 @@ enum scld_error safe_create_leading_directories(char *path)
337337
ret = SCLD_VANISHED;
338338
else
339339
ret = SCLD_FAILED;
340-
} else if (adjust_shared_perm(path)) {
340+
} else if (share && adjust_shared_perm(path)) {
341341
ret = SCLD_PERMS;
342342
}
343343
*slash = slash_character;
344344
}
345345
return ret;
346346
}
347347

348+
enum scld_error safe_create_leading_directories(char *path)
349+
{
350+
return safe_create_leading_directories_1(path, 1);
351+
}
352+
353+
enum scld_error safe_create_leading_directories_no_share(char *path)
354+
{
355+
return safe_create_leading_directories_1(path, 0);
356+
}
357+
348358
enum scld_error safe_create_leading_directories_const(const char *path)
349359
{
350360
int save_errno;

t/t4129-apply-samemode.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,30 @@ test_expect_success FILEMODE 'bogus mode is rejected' '
7373
test_i18ngrep "invalid mode" err
7474
'
7575

76+
test_expect_success POSIXPERM 'do not use core.sharedRepository for working tree files' '
77+
git reset --hard &&
78+
test_config core.sharedRepository 0666 &&
79+
(
80+
# Remove a default ACL if possible.
81+
(setfacl -k newdir 2>/dev/null || true) &&
82+
umask 0077 &&
83+
84+
# Test both files (f1) and leading dirs (d)
85+
mkdir d &&
86+
touch f1 d/f2 &&
87+
git add f1 d/f2 &&
88+
git diff --staged >patch-f1-and-f2.txt &&
89+
90+
rm -rf d f1 &&
91+
git apply patch-f1-and-f2.txt &&
92+
93+
echo "-rw-------" >f1_mode.expected &&
94+
echo "drwx------" >d_mode.expected &&
95+
test_modebits f1 >f1_mode.actual &&
96+
test_modebits d >d_mode.actual &&
97+
test_cmp f1_mode.expected f1_mode.actual &&
98+
test_cmp d_mode.expected d_mode.actual
99+
)
100+
'
101+
76102
test_done

t/test-lib-functions.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,9 @@ test_chmod () {
367367
git update-index --add "--chmod=$@"
368368
}
369369

370-
# Get the modebits from a file.
370+
# Get the modebits from a file or directory.
371371
test_modebits () {
372-
ls -l "$1" | sed -e 's|^\(..........\).*|\1|'
372+
ls -ld "$1" | sed -e 's|^\(..........\).*|\1|'
373373
}
374374

375375
# Unset a configuration variable, but don't fail if it doesn't exist.

0 commit comments

Comments
 (0)