Message ID | 20240805060010.GA120016@coredump.intra.peff.net (mailing list archive) |
---|---|
State | Accepted |
Commit | e95d515141648e4067dbda8af8516e1c718c8f65 |
Headers | show |
Series | apply: canonicalize modes read from patches | expand |
Jeff King <peff@peff.net> writes:
> +test_expect_success POSIXPERM 'patch mode for deleted file is canonicalized' '
This test seems to fail under "--stress" and I need to borrow a
brain better clued than mine. It appears to be fooled by mtime that
is not updated immediately and failing match_stat check, but since
the index file is written on the other side of the second resolution
boundary, racy-git double-checking code does not trigger, or
something like that.
Here is how it fails:
expecting success of 4129.13 'patch mode for deleted file is canonicalized':
test_when_finished "git reset --hard" &&
echo content >non-canon &&
git add non-canon &&
chmod 666 non-canon &&
cat >patch <<-\EOF &&
diff --git a/non-canon b/non-canon
deleted file mode 100660
--- a/non-canon
+++ /dev/null
@@ -1 +0,0 @@
-content
EOF
git apply --index patch 2>err &&
test_must_be_empty err &&
git ls-files -- non-canon >staged &&
test_must_be_empty staged &&
test_path_is_missing non-canon
++ test_when_finished 'git reset --hard'
++ test 0 = 0
++ test_cleanup='{ git reset --hard
} && (exit "$eval_ret"); eval_ret=$?; :'
++ echo content
++ git add non-canon
++ chmod 666 non-canon
++ cat
++ git apply --index patch
error: last command exited with $?=1
not ok 13 - patch mode for deleted file is canonicalized
#
# test_when_finished "git reset --hard" &&
# echo content >non-canon &&
# git add non-canon &&
# chmod 666 non-canon &&
#
# cat >patch <<-\EOF &&
# diff --git a/non-canon b/non-canon
# deleted file mode 100660
# --- a/non-canon
# +++ /dev/null
# @@ -1 +0,0 @@
# -content
# EOF
# git apply --index patch 2>err &&
# test_must_be_empty err &&
# git ls-files -- non-canon >staged &&
# test_must_be_empty staged &&
# test_path_is_missing non-canon
#
1..13
$ echo $?
1
$ git -C trash\ directory.t4129-apply-samemode.stress-failed/.git ls-files --debug non-canon
non-canon
ctime: 1723701364:980719772
mtime: 1723701364:980719772
dev: 65024 ino: 1980747
uid: 110493 gid: 89939
size: 8 flags: 0
: git t/master; stat trash\ directory.t4129-apply-samemode.stress-failed/non-canon
File: trash directory.t4129-apply-samemode.stress-failed/non-canon
Size: 8 Blocks: 8 IO Block: 4096 regular file
Device: 254,0 Inode: 1980747 Links: 1
Access: (0666/-rw-rw-rw-) Uid: (110493/ jch) Gid: (89939/primarygroup)
Access: 2024-08-15 06:54:43.808293635 -0700
Modify: 2024-08-14 22:56:04.980719772 -0700
Change: 2024-08-14 22:56:05.020719706 -0700
Birth: 2024-08-14 22:56:04.980719772 -0700
$ stat trash\ directory.t4129-apply-samemode.stress-failed/.git/index
File: trash directory.t4129-apply-samemode.stress-failed/.git/index
Size: 432 Blocks: 8 IO Block: 4096 regular file
Device: 254,0 Inode: 1980724 Links: 1
Access: (0600/-rw-------) Uid: (110493/ jch) Gid: (89939/primarygroup)
Access: 2024-08-14 22:56:05.044719667 -0700
Modify: 2024-08-14 22:56:05.008719726 -0700
Change: 2024-08-14 22:56:05.016719713 -0700
Birth: 2024-08-14 22:56:04.996719746 -0700
diff --git a/apply.c b/apply.c index 0f2f5dabe3..6e1060a952 100644 --- a/apply.c +++ b/apply.c @@ -995,6 +995,7 @@ static int parse_mode_line(const char *line, int linenr, unsigned int *mode) *mode = strtoul(line, &end, 8); if (end == line || !isspace(*end)) return error(_("invalid mode on line %d: %s"), linenr, line); + *mode = canon_mode(*mode); return 0; } diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh index 4eb8444029..d9a1084b5e 100755 --- a/t/t4129-apply-samemode.sh +++ b/t/t4129-apply-samemode.sh @@ -130,4 +130,66 @@ test_expect_success 'git apply respects core.fileMode' ' test_grep ! "has type 100644, expected 100755" err ' +test_expect_success POSIXPERM 'patch mode for new file is canonicalized' ' + cat >patch <<-\EOF && + diff --git a/non-canon b/non-canon + new file mode 100660 + --- /dev/null + +++ b/non-canon + +content + EOF + test_when_finished "git reset --hard" && + ( + umask 0 && + git apply --index patch 2>err + ) && + test_must_be_empty err && + git ls-files -s -- non-canon >staged && + test_grep "^100644" staged && + ls -l non-canon >worktree && + test_grep "^-rw-rw-rw" worktree +' + +test_expect_success POSIXPERM 'patch mode for deleted file is canonicalized' ' + test_when_finished "git reset --hard" && + echo content >non-canon && + git add non-canon && + chmod 666 non-canon && + + cat >patch <<-\EOF && + diff --git a/non-canon b/non-canon + deleted file mode 100660 + --- a/non-canon + +++ /dev/null + @@ -1 +0,0 @@ + -content + EOF + git apply --index patch 2>err && + test_must_be_empty err && + git ls-files -- non-canon >staged && + test_must_be_empty staged && + test_path_is_missing non-canon +' + +test_expect_success POSIXPERM 'patch mode for mode change is canonicalized' ' + test_when_finished "git reset --hard" && + echo content >non-canon && + git add non-canon && + + cat >patch <<-\EOF && + diff --git a/non-canon b/non-canon + old mode 100660 + new mode 100770 + EOF + ( + umask 0 && + git apply --index patch 2>err + ) && + test_must_be_empty err && + git ls-files -s -- non-canon >staged && + test_grep "^100755" staged && + ls -l non-canon >worktree && + test_grep "^-rwxrwxrwx" worktree +' + test_done