Git обнаруживает измененные файлы, которые на самом деле идентичны по байтам

У меня проблема с git (через черепаховый git), который показывает некоторые файлы моего проекта как измененные, но на самом деле они не изменены. Я перепроверил это, сделав новый клон репозитория, и, не касаясь его, я уже обнаружил «модифицированные» файлы во вновь созданной рабочей копии. Это раздражает, потому что некоторые операции заблокированы (потому что это переопределит мои «измененные» файлы), но я не могу их отменить, удаление + возврат тоже не работает. Фиксация «изменений» работает, но это не идеальное решение.

Я на Windows, использую TortoiseGit 1.8.16.0 и Git 2.6.4. Использование git status напрямую также показывает, что одни и те же файлы «модифицированы».

Кажется, это происходит только в каталоге моего проекта, который раньше был подмодулем, но теперь я использую поддерево git. Итак, в какой-то момент я полностью удалил подмодуль (или так я думаю) и создал поддерево.

У кого-нибудь была такая же проблема? Как исправить раз и навсегда? (даже после внесения «изменений» через некоторое время, иногда через несколько недель, у меня будут другие файлы, а иногда и те же файлы, которые начнут показывать ту же странную проблему).

Вот результат сравнения одного из этих файлов: git diff app.config

diff --git a/Ozytis.Common/Web/app.config b/Ozytis.Common/Web/app.config
index 3686aab..f559fe7 100644
--- a/Ozytis.Common/Web/app.config
+++ b/Ozytis.Common/Web/app.config
@@ -1,25 +1,25 @@
-<U+FEFF><?xml version="1.0" encoding="utf-8"?>
-<configuration>
-  <configSections>
-    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
-    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=ne
utral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
-  </configSections>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-  <entityFramework>
-    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
-      <parameters>
-        <parameter value="v11.0" />
-      </parameters>
-    </defaultConnectionFactory>
-    <providers>
-      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
-    </providers>
-  </entityFramework>
+<U+FEFF><?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <configSections>
+    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
+    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=ne
utral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+  </configSections>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+  <entityFramework>
+    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
+      <parameters>
+        <parameter value="v11.0" />
+      </parameters>
+    </defaultConnectionFactory>
+    <providers>
+      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
+    </providers>
+  </entityFramework>
 </configuration>
\ No newline at end of file

Для этого файла diff показывает, что все строки изменены. Однако я проверил с помощью шестнадцатеричного редактора предыдущую и текущую версии файла, переводы строк одинаковы, фактически каждый байт одинаков.

Кроме того, некоторые файлы показывают, что отличаются всего несколько строк (но опять же, это не так). Даже если весь файл имеет последовательные переводы строк.


person youen    schedule 17.12.2015    source источник
comment
Были ли изменены права доступа к файлам?   -  person Claudio    schedule 17.12.2015
comment
Что показывает git diff?   -  person choroba    schedule 17.12.2015
comment
@choroba git diff app.config diff --git a/Ozytis.Common/Web/app.config b/Ozytis.Common/Web/app.config index 3686aab..f559fe7 100644 --- a/Ozytis.Common/Web/app.config +++ b/Ozytis.Common/Web/app.config @@ -1,25 +1,25 @@ -<U+FEFF><?xml version="1.0" encoding="utf-8"?> -<configuration> - <configSections> [snip] - </entityFramework> +<U+FEFF><?xml version="1.0" encoding="utf-8"?> +<configuration> + <configSections> [snip] + </entityFramework> </configuration> \ No newline at end of file PS: нет возможности оставить перевод строки в комментариях?   -  person youen    schedule 17.12.2015
comment
Вы не можете оставить LF в комментарии, но вы можете добавить git diff вывод к содержанию вопроса   -  person Zdeslav Vojkovic    schedule 17.12.2015
comment
Я думаю, git diff --ignore-space-at-eol объяснит проблему, ‹CR›‹LF› против ‹LF›   -  person user3159253    schedule 17.12.2015
comment
@user3159253 user3159253 ваша команда не дает результата. Не знаю, что об этом думать. Я проверил свои файлы с помощью шестнадцатеричного редактора: они имеют точно такие же переводы строк в предыдущей/следующей версии (0x0d 0x0a). Кроме того, я не трогал некоторые файлы в течение нескольких месяцев, почему они внезапно появляются измененными? А почему после свежего клона?   -  person youen    schedule 17.12.2015
comment
@Claudio Я только что клонировал репозиторий, не менял права доступа к файлам или что-то в этом роде. Я вообще не менял права доступа к файлам за всю жизнь проекта, насколько я помню (кстати, я на Windows)   -  person youen    schedule 17.12.2015
comment
@youen, если вы следуете этому ответу , файл исчезает из git status? Если это так, я предполагаю, что это либо ошибка с вашим шестнадцатеричным редактором, либо с вашей установкой git.   -  person houtanb    schedule 17.12.2015
comment
@youen, это действительно проблема с окончанием строки. Ознакомьтесь с этим документом, а затем попробуйте различные варианты настройки core.autocrlf. Вам также может потребоваться принудительно исправить проблему с окончанием строки в новом коммите.   -  person user3159253    schedule 17.12.2015


Ответы (1)


Кажется, это действительно проблема с окончанием строки (спасибо user3159253 и HBHB за их комментарии по этому поводу).

Похоже на ошибку git, потому что почему он сообщает, что файлы разные, но в то же время, когда вы получаете их на свой компьютер, он меняет окончания строк, так что вы не видите, в чем разница? Я считаю, что он не должен показывать различия в конце строки (не с git status и не с git diff), если он все равно настроен на их изменение.

Кроме того, я уже пытался изменить core.autocrlf, прежде чем задавать свой вопрос, но оказалось, что мой проект содержит .gitattributes, и это было настоящей проблемой. Файл начинается с * text, а затем несколько форматов файлов изменяются на двоичные, и это имеет приоритет над core.autocrlf. Поскольку все работают над Windows для этого проекта, я изменил его на * binary (см. обновление ниже), по крайней мере, теперь все ясно. Это заставило git обнаружить еще несколько файлов как измененных (опять же, git не согласен с этим?), но на этот раз я действительно вижу различия в конце строк. Я совершил их, и я надеюсь, что это конец истории.

ОБНОВЛЕНИЕ:

Использование * binary в .gitattributes также не работает, потому что теперь git не может объединять текстовые файлы, так как считает их двоичными. Правильная версия (если вы хотите запретить git изменять окончания строк, но при этом правильно объединять текстовые файлы) — * -text:

Сброс текстового атрибута в пути указывает Git не предпринимать никаких попыток преобразования конца строки при возврате или извлечении.

http://git-scm.com/docs/gitattributes

Это решение может быть не идеальным, потому что после обновления вашей рабочей копии все ваши файлы будут иметь окончания строк в стиле unix (потому что я полагаю, что это было сохранено git). Поэтому вам нужно преобразовать все ваши файлы обратно в окончание строк Windows (помогает dos2unix) и сделать большая фиксация, которая будет проблемой для будущего слияния (если таковое будет).

person youen    schedule 17.12.2015