git 个分支共享文件权限

File permissions are being shared across git branches

不确定为什么会这样,但问题是我在将该分支推送到远程后更改了该分支的文件权限。然后我从我们的集成分支签出一个新分支,它具有来自 "dead branch" 的权限,它是这样的:

# on feature branch
git checkout --no-track -b foo
git reset --soft "remotes/origin/dev"
git add .
git add -A
git commit --allow-empty -am "bar"
git push -u origin foo
chmod -R -w .  # remove all write permissions in current dir

# later on
git branch --no-track z "remotes/origin/dev"
git checkout z
### ughh this new branch z files are not writable, but whyyyy?

基本上我们将文件更改为不可写,并且该分支永远不会合并到任何分支 - 我们在修改文件权限之前将其推送到远程。

为什么不可写文件权限出现在其他从未与不可写文件分支合并的分支中?

Git 关心并为每个文件存储的唯一权限是 "is or is not executable" 权限。 chmod 的这种行为的 TL;DR 是 "don't do that"——为此使用单独的克隆或单独的工作树。有关更多详细信息,请继续阅读。

具体来说,在每个提交快照中,每个文件(或 blob,实际上)被标记为模式 100644(不可执行)或 100755 (可执行)。您将在 git ls-tree 输出中看到这一点,就像在任何现有提交上的 运行 一样。 所有 其他权限,包括读取或写入的能力,由您决定。在 Unix 和类 Unix 系统上,当 Git 创建一个工作树文件时,它实际上使用模式 0777 (如果文件是可执行的)或 0666 (如果不是) .您的 umask 会从这些文件中删除任何不需要的权限;典型的 umask 值为 022(删除组和其他写权限)或 002(仅删除 non-group/other 写权限),但安全子系统可能使用 077(删除所有组和其他写权限)其他权限),例如。

请注意 Git 确实能够保持 内部存储库数据 组可写,但这些不是工作树文件:这些主要影响目录其中 Git 存储松散和打包的对象、参考值等。这些由 core.sharedRepository 设置控制;参见 the git config documentation。 (请记住,在目录中创建和删除文件的能力取决于当前用户和组 ID 对目录本身的写入权限。好吧,也就是说,除非您涉及 ACL;否则它会变得非常复杂。)

当使用 git checkout 从一个提交切换到另一个提交时,Git 仅根据需要删除和替换工作树文件。这种需要在很大程度上取决于 index 内容,索引索引工作树。这解释了为什么最终保留了一些(但不是全部)文件权限。有关更多信息,请参阅 Checkout another branch when there are uncommitted changes on the current branch.