Состояние git корректно только в том случае, если "Запуск от имени администратора", проблемы из-за Windows VirtualStore

У меня есть git-репозиторий для надстройки Excel, которую я написал, поэтому путь "C:\Program Files\Microsoft Office 15\root\office15\Library\BTRTools" (этот путь "Library" является обязательным родительским элементом для установки надстройки Excel). чтобы они работали должным образом, поэтому я не могу это изменить). У меня UAC включен как в Win7, так и в Win8.1. В Win7 все работает нормально, однако в Win8.1 я получаю статус "все изменилось" (но даже некоторые более странные файлы сначала упоминаются как "удаленные", а затем снова упоминаются в том же состоянии, что и "неотслеживаемые"). Репозиторий действительно 'clean', несмотря на то, что говорит git status, но я не могу вытащить или сделать сброс - жесткий или что-то еще.

Если я запускаю "Console2" (приложение, из которого я запускаю команды git bash), используя опцию "Запуск от имени администратора", все работает нормально и состояние чистое (без изменений). И я могу сделать тягу и любую другую команду правильно.

Как в Win7, так и в Win8.1 я вручную предоставил права полного доступа к папке BTRTools для моего пользователя (хотя я уже являюсь частью группы администраторов в обоих) и убедился, что Console2 действительно работает как мой локальный пользователь в Win8.1,

Кто-нибудь сталкивался с этой проблемой раньше и есть какие-либо идеи о том, как заставить Console2/git работать должным образом в Win8.1, не прибегая к постоянному запуску (при получении запроса) Console2 в режиме "Запуск от имени администратора"?

Заранее спасибо.

Обновить

Я обнаружил, что у меня такое же поведение в Win7 при определенных условиях. Я написал скрипт для пакетной обработки нескольких команд git, создав и запустив aC# Process / ProcessStartInfo, и он отображал то же поведение, что и консоль Win8.1. Вызов точно таких же команд непосредственно в консоли Win7 против сценария Win7 (т. Е. Состояния git) показал два разных результата.

Скрипт (который был написан на 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 выглядят одинаково (часть группы администраторов).

Обновление: выход Get-ACL

Я управлял Get-ACL | format-list в каталоге /BTRTools на обеих машинах. Единственным отличием было то, что Win8 имел "Application Package Authority" для практически всех папок, а Win7 - нет. Не уверен, что это намекает на что-либо.

Обновление: решено

Спасибо @ ian-boyd за то, что указал мне правильное направление. На моей машине с Win7, где Console2/Git работают нормально, я обнаружил, что у меня есть следующий файл:

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

Я не уверен, когда это было создано. Если я удалил его, мой Console2/Git на Win7 начал "терпеть неудачу" так же, как поведение Win8. Я восстановил его на Win7 и скопировал на Win8, и теперь Console2/Win8 также работает правильно. У меня больше сражений, поэтому я иду дальше. Я не очень понимаю это, но, как примечание, здесь были некоторые шаги, которые я пытался

  • Настройка полного доступа к файлам / каталогам в \Git каталог установки для группы пользователей на этой странице
  • Отключение виртуализации ошибок записи файлов и реестра в местоположения для каждого пользователя на одной странице в #1.
  • Настройка полного доступа к файлу / каталогу в \Library directory для группы Users.

Если у кого-то есть мнение о "правильном" способе справиться с этим, я весь в ушах.

1 ответ

Решение

Я предполагаю, что 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, и поэтому для этого параметра следует включить значение " Включено".

5 лет спустя вы можете надеяться, что проблема (команды Git с нежелательным UAC с VirtualStore) была исправлена ​​с помощью Git 2.23 (3 квартал 2019 г.)

См. Коммит fe90397 (27 июня 2019 г.) Сезара Эдуардо Барроса (cesarb).
(Слияние Junio ​​C Hamano -gitster- в коммите 9b9b24b, 11 июля 2019 г.)

mingw: встроить манифест, чтобы обмануть UAC в Doing The Right Thing

В Windows >= Vista при отсутствии манифеста приложения с requestedExecutionLevel может вызвать несколько видов сбивающего с толку поведения.

Первым и более очевидным поведением является "Обнаружение установщика" функции "Контроль учетных записей пользователей" (также известной как "UAC"), когда Windows иногда принимает решение (глядя на такие вещи, как имя файла и даже последовательности байтов в исполняемом файле) что исполняемый файл является установщиком и должен запускаться с повышенными привилегиями (вызывая появление хорошо известного всплывающего диалогового окна).
В контексте Git такие подкоманды, как "git patch-id" или "git update-index"стать жертвой такого поведения.

Второе и более запутанное поведение - "виртуализация файлов".
Это означает, что когда файлы записываются без разрешения на запись, это не дает сбоя (как и ожидалось), но вместо этого они перенаправляются в другое место.
При чтении файлов возвращается исходное содержимое, а не то, что было записано где-то еще.
Еще больше сбивает с толку то, что не все операции записи перенаправляются; Пытаюсь писать в защищенный от записи.exe файлы, например, не будут перенаправлены.

Помимо нежелательного поведения, виртуализация файлов вызывает резкое замедление работы Git (см., Например, ошибку msysgit 320).

Третье нежелательное поведение Windows >= Vista заключается в том, что при вызове он говорит о версии Windows. GetWindowsVersionEx().

Есть два способа предотвратить такое нежелательное поведение:

  • Либо вы встраиваете манифест приложения (который на самом деле представляет собой XML-документ, соответствующий определенной схеме) во все свои исполняемые файлы,
  • или вы добавляете внешний манифест (файл с тем же именем, за которым следует .manifest) ко всем вашим исполняемым файлам.

Поскольку встроенные функции Git жестко связаны (или скопированы), проще и надежнее встроить манифест.

Достаточно недавно компиляторы MSVC уже встраивают рабочий внутренний манифест, и сборка с использованием mingw-w64 (как в случае с Git для Windows SDK) тоже делает это, но для MinGW вы должны делать это вручную.

В любом случае, лучше указать этот манифест явно, чтобы изменения в инструментальной цепочке компилятора нас не удивили (как однажды сделал mingw-w64, когда он сломался. GetWindowsVersionEx() по ошибке).

Ссылки:

Другие вопросы по тегам