Состояние Git показывает файлы как измененные, даже если их содержимое одинаково

195

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

Я уже установил core.fileModeна ложь, а также core.autocrlfна ложь, но безуспешно.

Стоит отметить, что репозиторий Git, который я получил, был от кого-то, использующего Windows, в то время как я использую Linux.

Что я могу сделать, чтобы зафиксировать реальные изменения?

РЕДАКТИРОВАТЬ: вывод git config -l:

user.name=Aron Rotteveel
user.email=<removed>
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=auto
color.ui=true
color.pager=true
color.branch.current=yellow reverse
color.branch.local=yellow
color.branch.remote=green
color.diff.meta=yellow bold
color.diff.frag=magenta bold
color.diff.old=red bold
color.diff.new=green bold
color.status.added=yellow
color.status.changed=green
color.status.untracked=cyan
core.pager=less -FRSX
core.whitespace=fix,-indent-with-non-tab,trailing-space,cr-at-eol
alias.co=checkout
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
core.autocrlf=false
remote.origin.url=<removed>
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*

Обновление: добавлены случайные файлы примеров. Эти файлы просто текстовые, поэтому их проще всего включать.

Оригинальные файлы находятся здесь: https://gist.github.com/c3c5302430935155ef3d . Hexdumps однозначно указывают, что файлы разные, но я понятия не имею, что вызывает это и как это исправить.

Версия HEAD:

0000000: 4854 4d4c 2e53 6166 654f 626a 6563 740d  HTML.SafeObject.
0000010: 0a54 5950 453a 2062 6f6f 6c0d 0a56 4552  .TYPE: bool..VER
0000020: 5349 4f4e 3a20 332e 312e 310d 0a44 4546  SION: 3.1.1..DEF
0000030: 4155 4c54 3a20 6661 6c73 650d 0a2d 2d44  AULT: false..--D
0000040: 4553 4352 4950 5449 4f4e 2d2d 0d0a 3c70  ESCRIPTION--..<p
0000050: 3e0d 0a20 2020 2057 6865 7468 6572 206f  >..    Whether o
0000060: 7220 6e6f 7420 746f 2070 6572 6d69 7420  r not to permit 
0000070: 6f62 6a65 6374 2074 6167 7320 696e 2064  object tags in d
0000080: 6f63 756d 656e 7473 2c20 7769 7468 2061  ocuments, with a
0000090: 206e 756d 6265 7220 6f66 2065 7874 7261   number of extra
00000a0: 0d0a 2020 2020 7365 6375 7269 7479 2066  ..    security f
00000b0: 6561 7475 7265 7320 6164 6465 6420 746f  eatures added to
00000c0: 2070 7265 7665 6e74 2073 6372 6970 7420   prevent script 
00000d0: 6578 6563 7574 696f 6e2e 2054 6869 7320  execution. This 
00000e0: 6973 2073 696d 696c 6172 2074 6f0d 0a20  is similar to.. 
00000f0: 2020 2077 6861 7420 7765 6273 6974 6573     what websites
0000100: 206c 696b 6520 4d79 5370 6163 6520 646f   like MySpace do
0000110: 2074 6f20 6f62 6a65 6374 2074 6167 732e   to object tags.
0000120: 2020 596f 7520 7368 6f75 6c64 2061 6c73    You should als
0000130: 6f20 656e 6162 6c65 0d0a 2020 2020 254f  o enable..    %O
0000140: 7574 7075 742e 466c 6173 6843 6f6d 7061  utput.FlashCompa
0000150: 7420 696e 206f 7264 6572 2074 6f20 6765  t in order to ge
0000160: 6e65 7261 7465 2049 6e74 6572 6e65 7420  nerate Internet 
0000170: 4578 706c 6f72 6572 0d0a 2020 2020 636f  Explorer..    co
0000180: 6d70 6174 6962 696c 6974 7920 636f 6465  mpatibility code
0000190: 2066 6f72 2079 6f75 7220 6f62 6a65 6374   for your object
00001a0: 2074 6167 732e 0d0a 3c2f 703e 0d0a 2d2d   tags...</p>..--
00001b0: 2320 7669 6d3a 2065 7420 7377 3d34 2073  # vim: et sw=4 s
00001c0: 7473 3d34 0d0a                           ts=4..

Скопированная версия:

0000000: 4854 4d4c 2e53 6166 654f 626a 6563 740a  HTML.SafeObject.
0000010: 5459 5045 3a20 626f 6f6c 0a56 4552 5349  TYPE: bool.VERSI
0000020: 4f4e 3a20 332e 312e 310a 4445 4641 554c  ON: 3.1.1.DEFAUL
0000030: 543a 2066 616c 7365 0a2d 2d44 4553 4352  T: false.--DESCR
0000040: 4950 5449 4f4e 2d2d 0a3c 703e 0a20 2020  IPTION--.<p>.   
0000050: 2057 6865 7468 6572 206f 7220 6e6f 7420   Whether or not 
0000060: 746f 2070 6572 6d69 7420 6f62 6a65 6374  to permit object
0000070: 2074 6167 7320 696e 2064 6f63 756d 656e   tags in documen
0000080: 7473 2c20 7769 7468 2061 206e 756d 6265  ts, with a numbe
0000090: 7220 6f66 2065 7874 7261 0a20 2020 2073  r of extra.    s
00000a0: 6563 7572 6974 7920 6665 6174 7572 6573  ecurity features
00000b0: 2061 6464 6564 2074 6f20 7072 6576 656e   added to preven
00000c0: 7420 7363 7269 7074 2065 7865 6375 7469  t script executi
00000d0: 6f6e 2e20 5468 6973 2069 7320 7369 6d69  on. This is simi
00000e0: 6c61 7220 746f 0a20 2020 2077 6861 7420  lar to.    what 
00000f0: 7765 6273 6974 6573 206c 696b 6520 4d79  websites like My
0000100: 5370 6163 6520 646f 2074 6f20 6f62 6a65  Space do to obje
0000110: 6374 2074 6167 732e 2020 596f 7520 7368  ct tags.  You sh
0000120: 6f75 6c64 2061 6c73 6f20 656e 6162 6c65  ould also enable
0000130: 0a20 2020 2025 4f75 7470 7574 2e46 6c61  .    %Output.Fla
0000140: 7368 436f 6d70 6174 2069 6e20 6f72 6465  shCompat in orde
0000150: 7220 746f 2067 656e 6572 6174 6520 496e  r to generate In
0000160: 7465 726e 6574 2045 7870 6c6f 7265 720a  ternet Explorer.
0000170: 2020 2020 636f 6d70 6174 6962 696c 6974      compatibilit
0000180: 7920 636f 6465 2066 6f72 2079 6f75 7220  y code for your 
0000190: 6f62 6a65 6374 2074 6167 732e 0a3c 2f70  object tags..</p
00001a0: 3e0a 2d2d 2320 7669 6d3a 2065 7420 7377  >.--# vim: et sw
00001b0: 3d34 2073 7473 3d34 0a                   =4 sts=4.
Арон Роттвил
источник
1
Если у вас установлено значение core.filemodeunset или установлено значение true, отличается ли выход?
Марк Лонгэйр
Другая важная информация, которая могла бы помочь, - это выводgit --version
Марк Лонгэйр,
2
@AronRotteveel: Это просто: первый файл имеет CRLF-концы строк (windows), второй LF (Unix)
сех
3
вводит git 2.8 (март 2016) git ls-files --eol, чтобы быстро увидеть, участвует ли eol. Смотрите мой ответ ниже
VonC
Человек в Windows может запустить git config --global core.autocrlf true, чтобы решить эту проблему.
Инёка

Ответы:

62

Обновление: согласно комментарию на этот вопрос, проблема была решена:

Это легко: первый файл имеет CRLF-концы строк (окна), второй LF (Unix). fileUtil (доступен в мерзавца \ USR \ Bin) покажет вам , что ( file a bбудет отвечать что - то вроде a: ASCII text, with CRLF line terminators b: ASCII text)

Оригинальный ответ ниже:


Разница, которую вы показываете, не показывает ни одной другой линии. Можете выложить .git / config (или лучше git config -l).

Возможно, некоторые пробельные символы игнорируются

Вы должны попытаться отключить core.whitespace=fix,-indent-with-non-tab,trailing-space,cr-at-eol;

также

git show HEAD:myfile|md5sum
md5sum myfile

может быть использован для проверки того, что файлы на самом деле разные. Использование внешнего diff может также работать

git show HEAD:myfile > /tmp/myfile.HEAD

diff -u myfile /tmp/myfile.HEAD

# or if you prefer an interactive tool like e.g.:
vim -d myfile /tmp/myfile.HEAD
sehe
источник
Странно то, что md5sums для обоих файлов разные , но я не могу найти ЛЮБУЮ пробельные разницу. (Я предполагаю, что это так, но я просто не вижу этого). Любая помощь приветствуется.
Арон Роттвил
Просто загрузите пример куда-нибудь (для этого подойдет gist.github.com). Я предполагаю, что это с новой строкой в ​​последней строке, меткой порядка байтов или неканоническими кодировками UTF8 в целом. Вы всегда можете посмотреть xxdили bdiffсделать бинарные
различия
Спасибо за чаевые. xddбыл новым для меня. Отличный инструмент! Я обновил свой пост с примером.
Арон Роттвил
1
@AronRotteveel: Это просто: первый файл имеет CRLF-концы строк (окна), второй LF (Unix). Редактироватьfile Util покажет вам , что ( file a bбудет отвечать что - то вроде a: ASCII text, with CRLF line terminators b: ASCII text)
sehe
разве те не должны отображаться как ^ M в VIM? (Я этого не вижу). Очевидно, я вам верю, но мне действительно интересно, как вы на самом деле это заметили :)
Арон Роттвил
135

Я решил эту проблему, используя следующие stpes

1) Удалите каждый файл из индекса Git.

git rm --cached -r .

2) Перепишите индекс Git, чтобы подобрать все новые окончания строки.

git reset --hard

Обратите внимание, что шаг 2 может удалить ваши локальные изменения. Решение было частью шагов, описанных на сайте git https://help.github.com/articles/dealing-with-line-endings/

Яцек Шибиш
источник
В моем случае я сделал несколько заметок к некоторым файлам, а затем скопировал репозиторий без папки .git на новый компьютер. Когда я понял, что мне не хватает пакета .git, было слишком поздно возвращаться и возвращать его. Итак, я: 1. Извлек новую копию всего репо 2. Заменил ванильные файлы файлами с моими изменениями 3. Запустил первый шаг в посте ОП: git rm --cached -r .4. Это подготовило мои изменения (и любые другие файлы, которые были заменены ) так что я их ставил. В этот момент мой репо вернулся к нормальному состоянию.
Коди
2
Brilliant. Спасибо за это.
rupi
6
Нужно быть осторожным, так как вы потеряете любые другие изменения, если вы это сделаете.
Мохи Элдин
У меня была эта проблема после копирования и вставки моей папки репозитория из Windows в Ubuntu. Локальных изменений не было, но по какой-то причине git думал, что каждый отдельный файл изменился. Это решение решило эту проблему.
Linek
88

Вы изменили режим файлов? Я сделал это на своей машине, и на локальной машине разработчика было дано 777 для всех файлов, в то время как в репо было 755, в котором каждый файл был изменен. Я сделал, git diffи он показал, что старый режим и новый режим отличаются. Если это проблема, то вы можете легко проигнорировать их git config core.filemode false
Cheers

itsandy
источник
2
Используя Windows 10 lxss (то есть Ubuntu Bash) с репозиторием в файловой системе Windows с git в Linux, я думал, что это проблема с окончанием строки. Даже не подумал, что это может быть из-за того, что режимы файлов тоже разные.
Мэтт Л
Это сработало для меня, когда я сменил локальную операционную систему с Ubuntu на Windows. Приветствия
Марк Бакнелл
@MattL и его, я обычно разрабатываю на Win 10 с Git Bash, но сегодня я на Mac и вижу, что git думает, что .gitignoreфайлы изменились, когда их нет. На этом Mac git config core.filemodeотвечает true. Я изменил это на false, но это не помогло.
Райан
43

У меня такая же проблема. после win-> lin copy у меня все файлы изменены.
я использовал fromdos, чтобы исправить окончания строк,
а затем

git add -uv 

добавить изменения.
он добавил 3 файла (не все), которые я на самом деле изменил. и после этого git status показывает только 3 измененных файла. после git commit все в порядке со статусом git

Demo_S
источник
2
Спасибо, это было то, что мне было нужно. Я использовал предложение @ sehe о сравнении md5sum для проверки идентичности файлов (в моем случае они были). После этого с помощью флага -u правильно отфильтровывались эти файлы без каких-либо реальных отличий от тех, которые были изменены.
STW
Спасибо, это было полезно. У меня была эта проблема после выполнения npm iв корне моего проекта. Каким-то образом многие файлы получали разные окончания строк, что создавало эту проблему.
Сервер Халилов
это то, что я ожидал ... изменения, которые сделали, остаются, и отдых
Дипак
28

Мне удалось исправить проблемы на компьютере с Windows, изменив core.autocrlf с false на core.autocrlf = input

git config core.autocrlf input

как это предлагается в https://stackoverflow.com/a/1112313/52277

Майкл Фрейдгейм
источник
25

В моем случае файлы были изменены после изменения прав доступа к файлам. .

Чтобы git игнорировал изменения разрешений, сделайте следующее:

# For the current repository
git config core.filemode false   

# Globally
git config --global core.filemode false
Сакис
источник
1
Ваш ответ сэкономил мне много времени. Спасибо!
Pavel_K
После этого я рекомендую сохранить / поместить необходимые изменения, сбросить / проверить файлы, для которых были изменены разрешения, а затем снова включить их core.filemode. :)
XtraSimplicity
У меня была эта проблема после копирования файлов с одного ноутбука на другой. Ваше исправление сохранило это. Спасибо!
Сэм
23

Тем не менее, много (если не каждый) файл выглядит измененным, даже если его содержимое точно такое же.

С git 2.8 (март 2016 г.) вы сможете быстро проверить, связаны ли эти изменения с eol.

См. Коммит a7630bd (16 января 2016 г.) от Torsten Bögershausen ( tboegi) .
(Слиты Junio C Hamano - gitster- в фиксации 05f1539 , 03 фев 2016 г.)

ls-files: добавить диагностику eol

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

Позвольте Git показывать окончания строк в индексе и в рабочем дереве и эффективные атрибуты text / eol.

Конец строки (" eolinfo") показан так:

"-text"        binary (or with bare CR) file
"none"         text file without any EOL
"lf"           text file with LF
"crlf"         text file with CRLF
"mixed"        text file with mixed line endings.

Действующий атрибут text / eol является одним из следующих:

"", "-text", "text", "text=auto", "text eol=lf", "text eol=crlf"

git ls-files --eol дает вывод, как это:

i/none   w/none   attr/text=auto      t/t5100/empty
i/-text  w/-text  attr/-text          t/test-binary-2.png
i/lf     w/lf     attr/text eol=lf    t/t5100/rfc2047-info-0007
i/lf     w/crlf   attr/text eol=crlf  doit.bat
i/mixed  w/mixed  attr/               locale/XX.po

показать, какое соглашение eol используется в данных в индексе (' i') и в рабочем дереве (' w'), и какой атрибут действует для каждого отображаемого пути .

VonC
источник
Хотя это показывает проблему, это не решает ее.
Greeso
7

Вот как я исправил проблему в Linux, пока клонировал проект, созданный в Windows:

в Linux, чтобы все работало правильно, вы должны иметь эту настройку: core.autocrlf = input

вот как это установить: git config --global core.autocrlf input

Затем снова клонируйте проект из github.

искатель правды
источник
Это сработало для меня в сценарии, где я использую Visual Studio в Windows, но я делаю коммиты и дополнительные проверки в WSL в командной строке. В командной строке каждый файл отображался как измененный, но в Visual Studio изменилось только несколько файлов. Я добавил autoclrf = input в мой файл .gitconfig, и он мгновенно это исправил. Спасибо!
Большие данные Брайан
5

В Git FAQ есть ответ, который может быть уместным, хотя я никогда не сталкивался с этим раньше:

Почему git diff иногда отображает файл без изменений?

git diff и другие операции git оптимизированы, поэтому он даже не смотрит на файлы, чье состояние (размер, время модификации и т. д.) на диске и в индексе git отличаются. Это делает git diff чрезвычайно быстрым для небольших изменений. Если файл был каким-либо образом затронут, git diff должен посмотреть на содержимое и сравнить его, что является гораздо более медленной операцией, даже если на самом деле изменений нет. git diff перечисляет файлы как напоминание о том, что они не используются оптимально. Запуск git status не только покажет статус, но также обновит индекс статусом для неизмененных файлов диска, делая последующие операции, не только diff, намного быстрее. Типичный случай, при котором многие файлы перечисляются в diff, - это запуск команд массового редактирования, таких как perl -pi -e '...'.

Что значит git status показывает для вас?

Марк Лонгэйр
источник
git statusпросто показывает огромный список файлов в измененном разделе.
Арон Роттвил
@Aron: основываясь на этой подсказке, я бы сказал: 85% говорят, что конвертация в
линию
4
Вот это да. Напоминание о том, насколько неразборчивы некоторые официальные документы git.
Марс
2

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

Нейт Кук
источник
2

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

Оказывается, я понял это, потому что я думал, что я должен просто обновить Git до последней версии, что я сделал, но работает git --version вернул старый номер версии. После последовавшей охоты за причинами я обнаружил корень каталога cygwin bin в моем пути к среде, который содержал исполняемый файл git, работающий под старым номером версии. Пойди разберись.

Это также было трудно найти, потому что у меня установлен TortoiseGit. Мои инструменты командной строки использовали версию cygwin из-за аварийных путей, а TortoiseGit был настроен на использование версии windows, что делало его еще более запутанным.

Надеюсь, это кому-нибудь поможет.

dudewad
источник
1
Хороший улов. +1. Вот почему я всегда устанавливаю свой PATH самостоятельно, как в stackoverflow.com/a/44351065/6309
VonC
Я часто позволяю установщику устанавливать PATH, но потом проверяю его вручную, что я и сделал здесь. В моей предыдущей установке был git 2.4.x (x86), и я установил git 2.13.x (x64). Вы можете представить мое замешательство, когда я удалил ссылку на путь x86 и все еще получил 2.4 !! Именно тогда я увидел каталог bin Cygwin, и это казалось следующим логичным местом для поиска. Поэтому настройка FWIW или даже визуальная проверка вашей PATH могут не решить эту проблему, если каталог бина Cygwin указан первым!
dudewad
1

Мне кажется, единственная подозрительная запись в вашем конфиге core.ignorecase. Вы можете попробовать сбросить это с:

  git config --unset core.ignorecase

... и посмотреть, если выход из git statusили git diffотличается.

Марк Лонгэйр
источник
1

Я просто установил filemode = false в .git / config, и это сработало для меня.

filemode = false
Фелипе Санта
источник
0

Для меня это было потому, что две виртуальные машины Linux были сопоставлены с одной и той же домашней файловой системой. Одна виртуальная машина работала с git-1.7.1, а другая - с git-2.14

Виртуальная машина, на которой запущен git-1.7.1, всегда отображала 4 измененных файла (даже при том, что содержимое и окончания строк были идентичными).

После запуска «git status» на виртуальной машине с g-2.14 обе виртуальные машины начнут сообщать о хранилище как о чистом. «git status» имеет побочные эффекты. Это не неизменная операция. И git-1.7.1 не понимает мир так же, как git-2 +.

Уильям
источник