Git莫名其妙地更改了单个文件的权限

Posted

技术标签:

【中文标题】Git莫名其妙地更改了单个文件的权限【英文标题】:Git changes the permissions on a single file unexplainably 【发布时间】:2013-05-19 03:20:44 【问题描述】:

我是唯一参与这个 git 项目的人。每次我在本地 Ubuntu 存储库中编辑文件,然后推送到 Bitbucket 并拉取到我的生产存储库时,git 都会将编辑后的文件更改为 -rwxrwxr-x 775。Apache 不喜欢这样。

本地系统:Ubuntu Linux 上的 git 版本 1.8.1.2

生产系统:CentOS/Red Hat Linux 上的 git 版本 1.7.12

当我将权限固定为 755 时,然后做

git diff

git diff -p

什么都不显示。

在我的本地存储库中,权限为 755,文件均归 haws 所有。 在我的生产仓库中,所有其他权限都保持在 755,所有文件包括 contact.php 都归我的用户名所有。

在本地和生产存储库中,我按如下方式更改了 core.filemode 以试图阻止这种行为,

core.filemode = false

我在合作项目中遇到过类似的谜团,所以我真的很想了解发生了什么。

    如何查看 git 更改此文件权限的原因? 如何让 git 停止更改它?

我也尝试在这里找到解决方案:Prevent Git from changing permissions on pull 无济于事。

我的最终解决方案(感谢 VonC 的指导):

    感谢 VonC 的出色解释,我勇敢地发现每次登录服务器时,我的 umask 都会回到 0002。所以我创建了一个用户启动脚本(.bashrc 或在我的情况下为 .bash_profile ) 在我的 Linux 主机上设置

    umask 0022

或使用符号表示法(为了一点附加值)

umask u=a,g-w,o-w 

umask u=a,go-w 

(允许用户的所有权限,不允许组和其他人的写权限)

这解决了我的问题。

    我之前已将 git config core.sharedRepository 设置为 true,但这不是我的问题,问题解决后我删除了该设置。

【问题讨论】:

查看 2009 年 10 月 16 日的评论 ***.com/questions/1580596/… 也可能与您将文件添加到工作树的方式有关(git add . vs git commit -a) 将 core.filemode 设置为 false 可能不是一个糟糕的解决方法。也许这也不是一个糟糕的标准工作流程实践。不过,我想知道为什么 git 没有“像宣传的那样工作”。我忽略了什么? 我建议提及您的操作系统和 git 版本以获得更好和更清晰的答案。这里有关于 windows 和非 windows 系统的区别。 谢谢。按照你的建议做。 另见问题***.com/questions/10657513/…了解更多信息。 【参考方案1】:

如“Wrong file permission when using git pull in a hook”中所述

Git 不存储权限,除了可执行位。 因此,在结帐时,会使用默认权限创建文件,这取决于您的 umask

在你的情况下:umask 0022 应该在你拉动时设置。 (这就是我在你看到的答案中提到的“Prevent Git from changing permissions on pull”)

这假设您在目标 repo 中有如下配置:

git config core.sharedRepository true

“How do I share a Git repository with multiple users on a machine?”中提到了另一种解决方案,您需要确保拉入一个像这样初始化的存储库:

git init --shared=0022

OP Tom Haws 在 cmets 中添加:

您知道为什么即使在该存储库的配置中没有 sharedRepository 条目的情况下,我的客户端生产服务器上的 git 也能够在不更改文件权限的情况下进行拉取?

可能是因为 umask 已经默认设置为0022,也就是说,默认情况下,git shell 继承了系统的umask。 更改umask 需要将core.sharedRepository 设置为true 以将其考虑在内,而不是考虑父进程的umask。 或者因为 repo 是使用 --shared=0022 创建的。

要了解如何设置umask(系统范围或用户范围),请参阅“How to set system wide umask?”

要在 git 命令(将继承其值)之前检查 umask,只需键入:

umask

【讨论】:

1.我将 umask 设置为 0022。我怎么知道 git 在拉取时没有改变它? 2.我添加了 git config core.sharedRepository true。这解决了我的问题。我会读到这个。谢谢。我正在接受您的回答,并希望您能在此问题上多陪我一会儿,以帮助我了解正在发生的事情。我仍然感到困惑的原因是我不明白 sharedRepository 在这种情况下如何应用。是因为“haws”在我的本地服务器上拥有文件,而“jcontru”在生产服务器上拥有它们吗? 我还是不明白。为什么这在我的客户项目中不是问题,其中三个开发人员都使用本地 Ubuntu 存储库推送和拉取,而我的 umask 有 0022,生产服务器上的 git config 只说 [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true @TomHaws 的想法是,如果 core.sharedRepository 设置为 true,那么 git 在拉取时会尊重 umask。 git 不会更改 umask(但如果 core.sharedRepository 设置为 false 或根本没有设置,它可以忽略它)。 你知道为什么我的客户端生产服务器上的 git 能够在没有文件权限更改的情况下进行拉取,即使该存储库的配置中没有 sharedRepository 条目?

以上是关于Git莫名其妙地更改了单个文件的权限的主要内容,如果未能解决你的问题,请参考以下文章

git status 未显示权限更改 [重复]

防止git pull更改文件权限和所有权

当多人推/拉时 Git 权限正在改变

使用git签出文件时如何找出导致文件权限更改的原因?

text 还原本地git存储库中的文件权限更改

企业生产环境用户权限集中管理项目方案