如果"以管理员身份运行",由于Windows VirtualStore导致的问题,git status仅会更正

时间:2014-07-11 19:25:20

标签: git windows-8.1 uac console2

我有一个我写的Excel Addin的git存储库,所以路径是" C:\ Program Files \ Microsoft Office 15 \ root \ office15 \ Library \ BTRTools" (那个' Library'路径是Excel加载项所需的安装父级,以便它们正常工作,因此我无法对其进行更改)。我在Win7和Win8.1中都启用了UAC。在Win7中一切正常,但在Win8.1中,我得到的状态基本上都是“一切都改变了”。 (但即使是一些较为奇怪的文件首先被提及,然后再删除'然后再次以相同的状态提及'未跟踪'。存储库真的很干净,尽管如此git status说,但我不能拉或重置 - 硬或任何东西。

如果我跑步' Console2' (我从中发出git bash命令的应用程序)使用'以管理员身份运行'选项,一切正常,状态是干净的(没有列出任何变化)。我可以正确地执行拉动和任何其他命令。

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

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

提前致谢。

更新

我发现在特定条件下我在Win7中有相同的行为。我编写了一个脚本,通过创建和运行c# 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目录中的format-list。唯一的区别是Win8拥有“应用程序包授权”和#39;基本上所有文件夹和Win7都没有。不确定是否暗示任何事情。

更新:已解决

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

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也正常运行。我要进行更大规模的战斗,以便我继续前进。我不太明白这一点,但作为旁注,这里是我尝试的一些步骤

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

如果有人对“正确”有任何意见。处理这个问题的方法,我全心全意。

2 个答案:

答案 0 :(得分:0)

我的猜测是Git试图在没有访问权限的地方编写文件。

Windows然后尝试通过在其他地方重新编写写入来保持错误的Git。检查你的

  

%APPDATA%\本地\ VirtualStore

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

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

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

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

Bonus Chatter

来自Understanding and Configuring User Account Control in Windows Vista

  

用户帐户控制:虚拟化每个用户位置的文件和注册表写入错误

     

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

     

配置选项:

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

默认值:已启用

     

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

答案 1 :(得分:0)

5年后,您可能希望通过Git 2.23(2019年第三季度)解决此问题(带有VirtualStore且带有不需要的UAC的Git命令)

请参见commit fe90397Cesar Eduardo Barros (cesarb)(2019年6月27日)。
(由Junio C Hamano -- gitster --commit 9b9b24b中合并,2019年7月11日)

  

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

     

在Windows> = Vista上,没有带有   requestedExecutionLevel可能导致多种混乱的行为。

     

第一个也是最明显的行为是“用户帐户控制”(也称为“ UAC”)功能的“安装程序检测”,Windows有时会决定(通过查看文件名,甚至查看其中的字节序列)可执行文件),即可执行文件是安装程序,应提升运行(导致出现知名的弹出对话框)。
  在Git的上下文中,诸如“ git patch-id”或“ git update-index”之类的子命令易受此行为的影响。

     

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

     

除了是不良行为之外,文件虚拟化还会导致Git的运行速度显着降低(例如,参见msysgit issue 320

     

Windows> = Vista的第三种有害行为是它与   调用GetWindowsVersionEx()时的Windows版本。

     

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

     
      
  • 要么在所有可执行文件中嵌入应用程序清单(实际上是符合特定架构的XML文档),
  •   
  • 或者您将一个外部清单(文件名后跟.manifest的外部清单)添加到所有可执行文件中。
  •   
     

由于Git的内置文件是硬链接(或复制的),因此嵌入清单更加简单和强大。

     

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

     

无论如何,最好对此清单明确,这样编译器工具链中的更改就不会令我们感到惊讶(就像mingw-w64一次错误地破坏GetWindowsVersionEx()时所做的那样)。

     

参考文献: