我无法将父目录添加到Git中的*safe.directory*

180

在将Git更新到v2.35.2.windows.1后,我遇到了以下错误:

致命错误:不安全的仓库('F:/GitHub/my-project'被他人所有)
要为此目录添加例外,请执行以下命令:

git config --global --add safe.directory F:/GitHub/my-project

我尝试将我的项目的父目录添加到.gitconfig中,但它没有起作用。

[safe]
    directory = F:/GitHub/
    directory = F:/Private/
  • 这个问题有没有变通的方法?
  • “'x' is owned by someone else”实际上是什么意思?

我不想将我正在工作的每个项目都添加到.gitconfig文件中。


2
在我的情况下,我是唯一在我的笔记本电脑上工作的人。然而,由于我克隆到根目录而不是我的主目录(请不要因此评判我),所以我收到了这个错误,因为我使用sudo在根目录下构建的目录属于root用户而不是我自己。 - Saeed Neamati
2
还要注意驱动器的大小写必须匹配,否则这个方法将无法工作。 - leppie
@DrLightman:你可以降级你的git版本,所有的事情都能正常工作。你可以在安全和简单生活之间做出选择(但请注意:现在安全问题已知,所以你应该定期检查系统中是否有人滥用它)。 - Giacomo Catenazzi
相关(更偏向于Linux):*致命错误:不安全的仓库('/home/repon'由他人拥有)* - Peter Mortensen
2
顺便提一下,如果您正在使用fat32或exfat磁盘,那么这是一个问题。而且是一个非常愚蠢的问题。 - Matthew Whited
显示剩余2条评论
24个回答

161
从Git v2.35.3版本开始,可以禁用安全目录检查,这将结束所有“不安全的仓库”错误(这也适用于2.30-34的最新补丁版本)。
可通过运行以下命令完成: git config --global --add safe.directory '*'1 它将在您的全局.gitconfig文件中添加以下设置:
[safe]
    directory = *

在禁用此功能之前,请确保您理解此安全措施以及为什么需要它。如果您的存储库存储在共享驱动器上,则不应该这样做
然而,如果您始终是计算机的唯一用户,并且您的存储库存储在本地,则理论上禁用此检查不应增加任何风险。
还要注意,您目前无法将其与文件路径组合使用,因为该命令不会将通配符*解释为运算符,它只会将"*"参数视为“禁用安全存储库检查/将所有存储库视为安全”。

1 - 如果在Windows中出现特定终端程序的故障,请尝试使用双引号将通配符括起来(通过此GitHub问题):
git config --global --add safe.directory "*"


2
我似乎无法让它工作。如果我指定一个特定的目录,它可以工作。你确定通配符设置有效吗? - nonrectangular
8
@nonrectangular 如果你使用的是Windows系统,建议在通配符“*”周围使用双引号而不是单引号。 - zcoop98
4
感谢@HalBurgiss指出,我没有意识到通配符仅适用于git v2.35.1及更高版本。Ubuntu 20.04预装的是v2.25.1。Ubuntu对旧版git(包括v2.25.1)应用了安全补丁,因此会产生此新错误,但没有修补此通配符解决方案的支持。请参阅M.S. Arun的解决方案,在Ubuntu 20.04上使用PPA获取最新的git版本。 - nonrectangular
5
谢谢,发现得不错。可惜!通配符会很有用。 - asherber
13
是的,他们修复了一个安全问题,但修复得如此糟糕以至于必须禁用安全修复才能完成工作。太棒了。 - Eric
显示剩余9条评论

99

回答

这似乎与此漏洞公告相关: https://github.blog/2022-04-12-git-security-vulnerability-announced/

我认为与您的电子邮件关系不大,而更多地与您文件系统上目录的所有者有关。 您当前登录的用户是否也是该文件夹的所有者? 父文件夹呢? 另外,您是否在存储库目录内调用git? 更新时间只有几个小时,所以我想事情仍然在变化中。

目前,如git的消息所示,请执行

git config --global --add safe.directory F:/GitHub/my-project

现在确保你正在F:/GitHub/my-project内部调用git

编辑:如我们在下面的评论中发现,包含 .git 文件夹(git 仓库)的父目录的所有者是问题所在。
重新克隆项目是一种平台独立的方法,可以确保你是该目录的所有者。

旁注

我在 Linux 上使用 flutter 时遇到了同样的问题,在我的 distro 中安装在 /opt/flutter 中。我没有作为 root 工作,因此我遇到了同样的问题。 运行 git config --global --add safe.directory /opt/flutter 确实为我解决了这个问题。

长篇编辑:澄清

经过一晚上的睡眠后再次查看关于漏洞的帖子,我觉得需要进行一些澄清。其余的答案保持不变。
让我们来看一下以下简单的目录结构。

/home/
├─ tommy/
│  ├─ .git/
│  ├─ rental_space/
│  │  ├─ mary/
│  │  │  ├─ projects/
│  │  │  │  ├─ phone_app/
│  │  │  │  │  ├─ .git/
│  │  ├─ anthony/
在此情况下,用户tommy拥有自己在/home下的目录,但(由于某种原因)将空间租给其他用户,这里是maryanthony。如果mary错误地在她的目录中但在phone_app项目之外执行git,那么旧版的git会向上遍历目录树以搜索.git存储库。 它找到的第一个是来自/home/tommy/.git的存储库。 这是一个安全风险,因为另一个用户,就是可以扮演tommy的任何人,都可以影响mary对git的执行,并可能引起麻烦。从Git v2.35.2及更高版本开始,当进入的目录属于mary以外的用户时,遍历将立即停止。假设mary/home/tommy/rental_space/mary/projects中执行了git,然后git将在projects中检查,但找不到.git。它将向上一级目录检查mary,但仍然找不到.git。然后它将再次向上移动,但rental_space属于tommy而不是mary。新的Git版本将在此处停止并打印我们在问题中看到的消息。将目录/home/tommy/rental_space添加到safe.directory变量中可以让git继续进行,但正如所解释的那样,这是一种安全风险。

我在此使用了类似Linux的目录结构,但在Windows上也是如此。


是的,当前用户是项目及其父目录的所有者。而且,是的,我正在存储库目录内调用git,但仍然存在错误。感谢您的答案,我想我会逐个添加目录,直到修复问题。 - Shleemypants
2
似乎对于子模块,现在需要正确拥有子模块文件夹和.git文件。即,将父项目添加为安全目录将包括子模块,但仅当它们的文件所有权与当前用户(或可能是父级.git文件夹)匹配时。 - webaware
2
@webaware 目前无法对您的回答进行评论(.....),但我认为您只是进行了一些小的澄清。我会稍微修改我的回答! - derpda
2
您说得对,user.*设置是无关紧要的。安全问题在于,在Windows共享驱动器上(以及可能包括某些Linux系统在内的任何多用户系统),可能会有人被欺骗运行木马软件。Git尝试使用操作系统的文件和目录所有权概念来解决这个安全问题。 - torek
2
在Windows上信任文件夹还存在其他问题。GitHub Desktop的最新Beta版本解决了这个问题。Git也无法检查NTFS文件夹的所有者是否是用户可能属于的安全组。 - Spencer
显示剩余9条评论

20

正如@derpda提到的那样,这与一个已经修复的Git安全漏洞有关。

至少在Linux上,您可以通过确保Git存储库的父文件夹归您所有来解决该问题。如果您能适当设置文件夹的所有权,则没有必要添加safe.directory配置设置。

如果您需要不同的所有权(例如作为不同用户运行的服务),则将您的文件夹添加到多值safe.directory配置设置中:

git config --global --add safe.directory /path/to/project

7
希望这对我有用... 我的文件夹在我的WSL上,显然是与我的Windows系统不同的用户... - Dave Thompson

19

我在Windows升级到版本2.35.2.windows.1后发现了同样的问题。

通过获取包含.git文件夹和其中所有文件的文件夹的所有权,我成功解决了这个问题。

以下是命令(假设您已经在存储库文件夹中):

takeown.exe /f . /r

注意:如果你在工作文件夹内有多个仓库文件夹,你可能需要递归地拥有工作文件夹及其子文件夹的所有权。这需要更长的执行时间,但你只需要执行一次。
cmd.exe下,命令看起来像这样:
takeown.exe /f C:\Users\%USERNAME%\Work /r

或者像这样在 powershell.exe 或 pwsh.exe 下:

takeown.exe /f $HOME\Work /r

7
我不建议递归地获取所有权。你只需要拥有父文件夹 .git.git 自身的所有权即可。 例如,当您的项目包含用作Docker卷的文件夹时,使用您的建议变得很重要。这些文件夹内部的权限通常是故意不同的,并且对Git的问题没有任何影响。 - derpda
@derpda,我基本上同意你的观点,但是只有当你从repo的根目录执行所有Git命令时,你的评论才是完全正确的。如果你从子目录执行命令,则需要将整个路径直到.git的父级所属于当前用户。 - Palec
2
@Palec 你说得没错,但是在我给出的 Docker 卷的例子中,更改目录的所有权是一个不好的解决方案 - 只需使用 cd 更改目录,这样您就可以安全地执行 git - derpda
“takeown” 也会破坏多重启动。Git 需要进行适当的 ACL 检查。是的,这些东西在 Linux 上几乎没有人使用,因为它们是有问题的。但它们在 Windows 上可以正常工作,而且一直以来都可以。 - Eric

8

针对(主要)Visual Studio 2022用户:

以下是我的设置:

  • Git版本为2.36.0.windows.1
  • 我从我的NAS中挂载了一个SMB网络共享,路径为\\MyNas\User,映射到X:\
  • 将远程分支克隆到了X:\目录下。
  • 我的NAS和PC不在同一个中。
  • 我的IDE:最新版本的Visual Studio 2022 Enterprise 17.2.0 Preview 4.0

目前的问题:

由于我的NAS和PC不在同一个域中,我无法将我的PC用户设置为NAS目录的所有者。

当在Visual Studio中打开存储库时,控制台会显示以下错误:

Opening Repository:
X:\Repo
Git failed with a fatal error.
fatal: unsafe repository ('//MyNas/User/Repo' is owned by someone else)
To add an exception for this directory, call:

    git config --global --add safe.directory '%(prefix)///MyNas/User/Repo'

经过长时间测试:

问题出在 Visual Studio 的便携式 Git 安装版本,版本号为 2.35.2。即使取消了“Git for Windows”组件的勾选,Visual Studio 仍然使用其自身的 Git 安装而非全局的 Git 安装。

解决方案:

  1. Add the repository directory as a safe directory with the recommended command:

    git config --global --add safe.directory '%(prefix)///MyNAS/User/Repo'
    
    # Or just trust any directory (not really recommended)
    git config --global --add safe.directory *
    
  2. Update the Git-Version which Visual Studio uses. (I just took the files from the global Git installation located in C:\Program Files\Git\mingw64\bin and pasted them to C:\Program Files\Microsoft Visual Studio\2022\Preview\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Git\mingw64\bin)

也许一个复制/粘贴文件的替代方式是让Visual Studio使用全局安装的Git,就像在这个Stack Overflow问题中所描述的那样:配置Visual Studio使用系统安装的Git.exe
注意:我没有测试过这个替代方案,因为我已经覆盖了我的Visual Studio安装目录中的Git文件。

关键要点:
  • 最新的Git版本(2.36.0)支持安全/可信任的目录。
  • 确保你的IDE使用的是最新版本的Git。

3
是的。只需指出 %(prefix) 是字面上的 %(prefix),而不是某些变量替换。 - Spencer

8

如果您正在使用挂载 NTFS 文件系统(可能是与 Windows 共享的数据驱动器),则可以在 /etc/fstab 中附加 defaults,uid=1000,gid=1000 来编辑您的挂载选项。这是默认设置;您无法在 NTFS 中永久更改 .git 的所有者。这些选项将使所有内容都归当前用户所有(而不是属于 root)。


谢谢,非常好用 :D 我正在使用带有Windows分区的Bitlocker,现在所有者可以访问.git文件了。 - silexcorp

6
我在Windows电脑上有一个本地存储库,映射到网络文件夹:

n:\folder

这指向

\windows-server\folder\working-folder

当我试图执行操作时

n:\folder> git status

出现了这个已知错误:

fatal: unsafe repository ('//windows-server/folder/working-folder' is owned by someone else) To add an exception for this directory, call:

    git config --global --add safe.directory '%(prefix)///windows-server/folder/working-folder'

在我的情况下,无法更改文件权限。因此我尝试了

git config --global --add safe.directory '%(prefix)///windows-server/folder/working-folder'

但是这并没有起作用。我不得不删除 ''!

解决方案:

git config --global --add safe.directory %(prefix)///windows-server/folder/working-folder

点赞了,谢谢 - 注意通配符似乎不再起作用。 - bigbadmouse
只有 * 而不是 "*" 对我有效。谢谢! - Roberto

6
在安卓的Termux中,您需要添加实际的git仓库,而不是父目录。
git config --global --add safe.directory /storage/emulated/0/src/go2null-dotfiles

您也可以禁用检查。

git config --global --add safe.directory '*'

6

针对Ubuntu 20.xx用户的解决方案 - 2022更新:

使用此PPA更新Git可以提供最新稳定的上游Git版本,解决了这个问题。

sudo add-apt-repository ppa:git-core/ppa

sudo apt update

sudo apt install git

Ref: https://git-scm.com/download/linux


这里有Ubuntu 20.04 (Focal Fossa)Ubuntu 20.10 (Groovy Gorilla)。你测试的是哪个版本,包括次要版本号? - Peter Mortensen
根据 https://launchpad.net/~git-core/+archive/ubuntu/ppa 的说法,我的 20.04 版本可以正常工作,两者都应该可以正常工作。 - Raymond

6

我也遇到过这个问题,因为我重新安装了Windows系统,而某些仓库文件夹的所有者是旧用户。所以Git不允许你直接使用这些文件夹。

你可以通过 "属性" → "安全" → "高级" → "所有者" 来检查。如果当前所有者类似于 "S-1-blah-blah",那么你就遇到了和我一样的问题。

如果你确定你是这些文件夹的真正所有者,你可以使用 takeown 命令:

cd F:/GitHub/
takeown /f *

/r开关在我的情况下似乎不是必需的。


我已经通过将 BUILTIN\Administrators 设置为所有者来解决这个问题多年了,但现在由于 Git 在 Windows 上使用 Linux 语义并且他们在谈论性能的同时采取了一些捷径而使我倒退了十年,而他们只需要正确地检查存储库根目录就可以了。 - Eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接