git status only correct if “Run As Administrator”, problems due to Windows VirtualStore

▼魔方 西西 提交于 2019-12-07 00:15:21

My guess is that Git has attempted to write files where it does not have access.

Windows then tries to keep the buggy Git going by re-directing the write someplace else. Check your

%AppData%\Local\VirtualStore

folder for redirected writes. For example:

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

My guess is you will find files there.

A correctly written Windows application would include an embedded option that asks Windows to not redirect failed writes. But i'm guessing Git is not a correctly written Windows application.

Bonus Chatter

From Understanding and Configuring User Account Control in Windows Vista

User Account Control: Virtualize file and registry write failures to per-user locations

This setting defines virtualization settings for 32-bit applications. Virtualization does not apply to 64-bit applications.

Configuration options:

  • Enabled - If a 32-bit application with no manifest file attempts to write to a protected location like the Program Files directory, virtualization will redirect those operations to a locations in the file system and registry that all users can access. This setting enables standard users to run pre Windows Vista applications that have historically required the user running the program to be an administrator.
  • Disabled - If a 32-bit application with no manifest file attempts to write to a protected location like the Program Files directory, the write will fail and the application will silently fail to run.

Default value: Enabled

Recommendation: Keep this setting enabled in environments where software must be run that is not fully compliant with UAC. Any 32-bit non-administrative application without an application manifest file or an application database entry is not UAC compliant. Many enterprises must run pre Windows Vista software, and therefore, should keep this setting configured to Enabled.

5 years later, you might hope the issue (Git commands with unwanted UAC with VirtualStore) has been fixed, with Git 2.23 (Q3 2019)

See commit fe90397 (27 Jun 2019) by Cesar Eduardo Barros (cesarb).
(Merged by Junio C Hamano -- gitster -- in commit 9b9b24b, 11 Jul 2019)

mingw: embed a manifest to trick UAC into Doing The Right Thing

On Windows >= Vista, not having an application manifest with a requestedExecutionLevel can cause several kinds of confusing behavior.

The first and more obvious behavior is "Installer Detection" of the "User Account Control" (also known as "UAC") feature, where Windows sometimes decides (by looking at things like the file name and even sequences of bytes within the executable) that an executable is an installer and should run elevated (causing the well-known popup dialog to appear).
In Git's context, subcommands such as "git patch-id" or "git update-index" fall prey to this behavior.

The second and more confusing behavior is "File Virtualization".
It means that when files are written without having write permission, it does not fail (as expected), but they are instead redirected to somewhere else.
When the files are read, the original contents are returned, though, not the ones that were just written somewhere else.
Even more confusing, not all write accesses are redirected; Trying to write to write-protected .exe files, for example, will fail instead of redirecting.

In addition to being unwanted behavior, File Virtualization causes dramatic slowdowns in Git (see for instance msysgit issue 320)

A third unwanted behavior of Windows >= Vista is that it lies about the Windows version when calling GetWindowsVersionEx().

There are two ways to prevent these unwanted behaviors:

  • Either you embed an application manifest (which really is an XML document conforming to a specific schema) within all your executables,
  • or you add an external manifest (a file with the same name followed by .manifest) to all your executables.

Since Git's builtins are hardlinked (or copied), it is simpler and more robust to embed a manifest.

Recent enough MSVC compilers already embed a working internal manifest, and building with mingw-w64 (which is the case in Git for Windows' SDK) does it, too, but for MinGW you have to do so by hand.

In any case, it is better to be explicit about this manifest, that way changes in the compiler toolchain won't surprise us (as mingw-w64 once did when it broke GetWindowsVersionEx() by mistake).

References:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!