Две версии одной и той же строки в "git diff" - PullRequest
0 голосов
/ 22 ноября 2018

Я столкнулся со странным поведением после переключения веток.Я выполнил git checkout master, и у меня сразу был один файл, помеченный как измененный.Я побежал git reset --hard, чтобы избавиться от этого, но безрезультатно.git diff дал мне вывод, подобный этому:

diff --git a/Project/MYClass.cs b/Project/MYClass.cs
index 4f8405e..cb8ca4c 100644
--- a/Project/MYClass.cs
+++ b/Project/MYClass.cs
@@ -170,7 +170,7 @@ namespace Project
-            Logger.Warn(message);
+            Logger.Info(message);

Но когда я вручную изменяю его обратно, я получаю:

diff --git a/Project/MyClass.cs b/Project/MyClass.cs
index cb8ca4c..4f8405e 100644
--- a/Project/MyClass.cs
+++ b/Project/MyClass.cs
@@ -170,7 +170,7 @@ namespace Project
-            Logger.Info(message);
+            Logger.Warn(message);

Так что git не может решить, какой это был.Чтобы было смешнее, если я изменил его на что-то совершенно другое, я получаю:

diff --git a/Project/MYClass.cs b/Project/MYClass.cs
index 4f8405e..cb8ca4c 100644
--- a/Project/MYClass.cs
+++ b/Project/MYClass.cs
@@ -170,7 +170,7 @@ namespace Project
-            Logger.Warn(message);
+            Logger.Error(message);
diff --git a/Project/MyClass.cs b/Project/MyClass.cs
index cb8ca4c..4f8405e 100644
--- a/Project/MyClass.cs
+++ b/Project/MyClass.cs
@@ -170,7 +170,7 @@ namespace Project
-            Logger.Info(message);
+            Logger.Error(message);

Когда я бегу git ls-tree -r master | Select-String "myclass.cs", я получаю это:

100644 blob 4f8405e28faa09981a3f76775b1693db31b0bdad    Project/MYClass.cs
100644 blob cb8ca4c60f10f959422ecc2cbdb91d0e693ea380    Project/MyClass.cs

Я вижу и понимаю что-товыключен, но я понятия не имею, как это произошло.

Я знаю, как исправить это жестоко, убрать мой локальный и извлечь все из удаленного, но я хочу знать, что вызывает это, и как исправитьэто правильно.

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Торек!Почему ты крадешь мой ответ?: -P

Как объясняет Торек (гораздо более подробно, чем я), проблема в том, что у вас есть два разных файла для git .... но когда git использует Windows FS API, они оба бьюттот же файл на ФС ..... и это объясняет всю проблему.Как вы это решаете?Если вы не против решения проблемы, двигайтесь вперед, сохраните нужный файл с нужным вам содержимым, а другой удалите с помощью git rm и подтвердите.Если вы хотите исправить это в прошлое, то посмотрите, где появился второй файл, исправьте эту ревизию, удалив ее, и перезапишите историю поверх нее.

0 голосов
/ 23 ноября 2018

Git считает, что у вас есть два разных файла в каталоге / папке Project:

  • MYClass.cs (прописные буквы M, прописные буквы Y, прописные буквы C, строчные буквы lass.cs)
  • MyClass.cs (прописные буквы M, строчные буквы y, прописные буквы C, строчные буквы lass.cs)

Git открывает каждое имя файла отдельно, записываетсодержимое этого файла и закрывает его.

Поскольку вы работаете в Windows, которая отказывается создавать два разных файла, имена которых отличаются только в case , ваша ОС перезаписывает один из двух файлов с другим, оставляя только один из двух корпусов на месте.Ваша ОС не позволит Git иметь два файла в рабочем дереве.Git может (и имеет) оба файла в index , потому что индекс Git на самом деле является файлом данных, а не каталогом / папкой.Поскольку Git делает свои коммиты из индекса, Git может делать новые коммиты, которые по-прежнему содержат два разных файла, имена которых отличаются только регистром.

Вы должны обновить свой индекс, чтобы он содержал только one такое имя, иначе вы обречены на Windows (и MacOS), чтобы навсегда бороться с этой проблемой.Самый простой способ - это исправить в системе Linux или Unix, где индекс и рабочее дерево остаются синхронизированными, поскольку ОС может создавать и создает два разных файла, имена которых отличаются только в случае.

Hardможно использовать git rm --cached: дать ему имя, которое вы действительно хотите удалить.Git удалит этот файл из индекса, не затрагивая рабочего дерева вообще.Теперь, когда индекс имеет правильный регистр, вы можете исправить регистр в рабочем дереве, чтобы он соответствовал, однако это делается в Windows - в других системах обычная хитрость:

mv NameWithCASEISSUE x   # change the whole name a lot, using a safe name
mv x NameWithCaseIssue   # change it back, using the correct case this time

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

Действительно неудачный случай (если я могу использовать это слово :-)) возникает, когда вы действительно делаете хотите оба имени файла, отличающиеся только регистром, индексом и последующими коммитами.Нет хороших инструментов для борьбы с этим.Теоретически возможно построить такие инструменты вокруг команд git update-index и git checkout-index, но в настоящее время они не существуют.

...