2

我有一个我写的 Excel 插件的 git 存储库,所以路径是“C:\Program Files\Microsoft Office 15\root\office15\Library\BTRTools”(该“库”路径是 Excel add-让他们正常工作,所以我不能改变它)。我在 Win7 和 Win8.1 中都打开了 UAC。在 Win7 中一切正常,但是在 Win8.1 中,我的状态基本上是“一切都改变了”(但甚至一些奇怪的文件首先被提到为“已删除”,然后再次以与“未跟踪”相同的状态被提及。存储库真的'干净',尽管 git status 说什么,但我不能拉或做 reset --hard 或任何东西。

如果我使用“以管理员身份运行”选项运行“Console2”(我从中发出 git bash 命令的应用程序),则一切正常且状态干净(未列出任何更改)。我可以正确地执行拉动和任何其他命令。

在 Win7 和 Win8.1 中,我已为我的用户手动授予对 BTRTools 文件夹的完全访问权限(即使我已经是两者的管理员组的一部分)并验证 Console2 确实在 Win8.1 中以我的本地用户身份运行.

以前有没有人遇到过这个问题,并且对如何让 Console2/git 在 Win8.1 中正常工作有任何想法,而无需在“以管理员身份运行”模式下始终运行(得到提示)Console2?

提前致谢。

更新

我发现在特定条件下我在 Win7 中得到了相同的行为。我编写了一个脚本,通过创建和运行 ac# Process/ProcessStartInfo来批处理多个 git 命令,它显示的行为与 Win8.1 Console2 相同。在 Win7 控制台与 Win7 脚本(即 git status)中直接调用完全相同的命令会显示两个不同的结果。

该脚本(用 LINQPad 编写)以我当前的用户身份运行,但我假设当它创建并启动Process/ProcessInfo时,它以某种方式在不同的用户下运行。通过提供我的凭据,我能够在我的脚本中更正这个问题

p.UserName = Environment.UserName;
p.Password = new System.Security.SecureString();
foreach( var c in password.ToCharArray() )
{
    p.Password.AppendChar( c );
}

注意:我验证了 Win7 和 Win8.1 中“我的”用户的安全组/设置似乎相同(属于 Admin 组)。

更新:获取 ACL 输出

我跑了 Get-ACL | 两台机器上 /BTRTools 目录上的格式列表。唯一的区别是 Win8 基本上对所有文件夹都有“应用程序包授权”,而 Win7 没有。不确定这是否暗示了任何事情。

更新:已解决

感谢@ian-boyd 为我指明了正确的方向。在 Console2/Git 工作正常的 Win7 机器上,我发现我有以下文件:

C:\Users\terry.aney\AppData\Local\VirtualStore\Program Files\Microsoft Office 15\root\office15\Library\BTRTools.git\index

我不确定它是什么时候创建的。如果我删除它,我在 Win7 上的 Console2/Git 开始“失败”,就像 Win8 所呈现的行为一样。我在 Win7 上恢复它,并将其复制到 Win8,现在 Console2/Win8 也正常运行。我有更大的战斗要打,所以我要继续前进。我不太明白这一点,但作为旁注,这是我尝试过的一些步骤

  • 根据此页面为用户组设置对 \Git 安装目录的完整文件/目录访问权限
  • 在 #1 中关闭每个用户位置的虚拟化文件和注册表写入失败。
  • 为用户组设置对 \Library 目录的完整文件/目录访问权限。

如果有人对处理此问题的“正确”方法有任何意见,我会全力以赴。

4

2 回答 2

0

我的猜测是 Git 试图在它无权访问的地方写入文件。

然后,Windows 尝试通过将写入重定向到其他地方来保持错误的 Git 继续运行。检查你的

%AppData%\Local\VirtualStore

用于重定向写入的文件夹。例如:

C:\Users\Ian\AppData\Local\VirtualStore\Program Files\Microsoft Office 15\root\office 15\Library

我猜你会在那里找到文件。

正确编写的 Windows 应用程序将包含一个嵌入式选项,该选项要求 Windows重定向失败的写入。但我猜 Git 不是一个正确编写的 Windows 应用程序。

奖金喋喋不休

了解和配置 Windows Vista 中的用户帐户控制

用户帐户控制:将文件和注册表写入失败虚拟化到每个用户的位置

此设置定义 32 位应用程序的虚拟化设置。虚拟化不适用于 64 位应用程序。

配置选项:

  • 已启用 - 如果没有清单文件的 32 位应用程序尝试写入受保护的位置(如 Program Files 目录),虚拟化会将这些操作重定向到文件系统和注册表中所有用户都可以访问的位置。此设置使标准用户能够运行以前要求运行程序的用户是管理员的 Windows Vista 以前的应用程序。
  • 已禁用 - 如果没有清单文件的 32 位应用程序尝试写入受保护的位置(如 Program Files 目录),则写入将失败,并且应用程序将静默运行失败。

默认值:启用

建议:在必须运行不完全符合 UAC 的软件的环境中保持启用此设置。任何没有应用程序清单文件或应用程序数据库条目的 32 位非管理应用程序都不符合 UAC。许多企业必须运行 Windows Vista 之前的软件,因此,应将此设置配置为Enabled

于 2014-07-31T21:09:17.010 回答
0

5 年后,您可能希望在 Git 2.23(2019 年第三季度)中解决了这个问题(带有不需要的 UAC 和 VirtualStore 的 Git 命令)

请参阅Cesar Eduardo Barros ( ) 的提交 fe90397(2019 年 6 月 27 日(由Junio C Hamano 合并——提交 9b9b24b中,2019 年 7 月 11 日)cesarb
gitster

mingw:嵌入清单以欺骗 UAC 做正确的事情

在 Windows >= Vista 上,没有带有 a 的应用程序清单 requestedExecutionLevel会导致多种令人困惑的行为。

第一个也是更明显的行为是“用户帐户控制”(也称为“UAC”)功能的“安装程序检测”,Windows 有时会决定(通过查看可执行文件中的文件名甚至字节序列等内容)可执行文件是安装程序并且应该运行提升(导致出现众所周知的弹出对话框)。
在 Git 的上下文中,诸如“ git patch-id”或“ git update-index”之类的子命令会成为这种行为的牺牲品。

第二个也是更令人困惑的行为是“文件虚拟化”。
这意味着当没有写权限的情况下写入文件时,它不会失败(如预期的那样),而是将它们重定向到其他地方。
但是,当读取文件时,会返回原始内容,而不是刚刚写入其他地方的内容。
更令人困惑的是,并非所有的写访问都被重定向;例如,尝试写入受写保护的.exe文件将失败,而不是重定向。

除了不受欢迎的行为之外,文件虚拟化还会导致 Git 显着变慢(参见例如msysgit issue 320

Windows >= Vista 的第三个不良行为是它在调用GetWindowsVersionEx().

有两种方法可以防止这些不良行为:

  • 您可以在所有可执行文件中嵌入应用程序清单(实际上是符合特定模式的 XML 文档),
  • 或者您将外部清单(具有相同名称的文件,后跟.manifest)添加到所有可执行文件。

由于 Git 的内置是硬链接(或复制)的,因此嵌入清单更简单、更健壮。

最近足够多的 MSVC 编译器已经嵌入了一个有效的内部清单,并且使用 mingw-w64 构建(Windows SDK 的 Git 就是这种情况)也可以做到这一点,但对于 MinGW,您必须手动完成。

在任何情况下,最好明确说明这个清单,这样编译器工具链中的更改就不会让我们感到惊讶(就像 mingw-w64 曾经在GetWindowsVersionEx()错误中断时所做的那样)。

参考:

于 2019-07-17T21:41:50.700 回答