Статус Git показує файли як змінені, хоча вміст однаковий


194

Я отримав перевірку git від когось іншого і намагаюся внести нестандартні зміни в локальний сховище. Однак багато (якщо не кожен) файл видається зміненим, навіть якщо вміст абсолютно однаковий.

Я вже встановив core.fileModeна false, а також встановив core.autocrlffalse, без успіху.

Варто зазначити, що репортаж Git, який я отримав, був від когось, хто використовує Windows, тоді як я використовую Linux.

Що я можу зробити, щоб здійснити фактичні зміни?

EDIT: вихід 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 безумовно вказують, що файли різні, але я не маю поняття, що це викликає, і як це виправити.

Версія голови:

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.filemodeвідключили або встановили значення, чи відрізняється trueвихід?
Марк Лонгейр

Інший важливий біт інформації, який би допоміг, - це результатgit --version
Марк Лонгейр,

2
@AronRotteveel: Це просто: перший файл має CRLF рядки-кінці (вікна), другий LF (Unix)
sehe

3
git 2.8 (березень 2016 року) вводить git ls-files --eol, щоб швидко зрозуміти, чи є участь eol. Дивіться мою відповідь нижче
VonC

Людина у Windows може запустити git config --global core.autocrlf true для вирішення цієї проблеми.
Іньока

Відповіді:


62

Оновлення: Відповідно до коментаря до цього питання, проблема вирішена:

Це легко: перший файл має рядки CRLF (windows), другий 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

може бути використаний для перевірки того, що файли насправді різні. Використання зовнішньої різниці також може працювати

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

Дивна річ у тому, що md5sums для обох файлів різні, але я не можу знайти будь-яку різницю пробілів. (Я припускаю, що це так, але я просто не бачу цього). Будь-яка допомога буде вітатися.
Арон Ротвевель

Просто десь завантажте приклад (gist.github.com було б доречним для цього). Я припускаю, що це є з новим рядком в останньому рядку, байтом-порядковим знаком або неканонічним кодуванням UTF8 взагалі. Ви завжди можете також переглянути xxdабо bdiffробити двійкові
відмінності

дякую за пораду. xddбуло для мене новим. Чудовий інструмент! Я оновив свою приклад прикладом.
Арон Ротвевель

1
@AronRotteveel: Це просто: перший файл має рядки CRLF (windows), другий - LF (Unix). Редагуватиfile Util покаже вам , що ( file a bбуде відповідати що - щось на зразок a: ASCII text, with CRLF line terminators b: ASCII text)
sehe

чи не повинні вони насправді відображатися як ^ M у VIM? (Я цього не бачу). Очевидно, я вам вірю, але мені дуже цікаво, як ви насправді це помітили :)
Арон Роттевель

134

Я вирішив цю проблему за допомогою наступних положень

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
Блискуча. Дякую за це
Rupi

6
Треба бути обережними, оскільки ви втратите будь-які інші зміни, якщо ви їх зробите.
Мохі Елдійн

У мене виникла ця проблема після копіювання та вставки моєї папки репо з Windows до Ubuntu. Місцевих змін не було, але чомусь Git подумав, що кожен файл змінився. Це рішення вирішило цю проблему.
Лінек

88

Ви змінили режим файлів? Я зробив це на своїй машині, і локальна машина Dev отримала 777 для всіх файлів, тоді як у репо було 755, який показав кожен файл як змінений. Я зробив, git diffі він показав, що старий і новий режим різні. Якщо це проблема, то Ви можете легко проігнорувати їх на git config core.filemode false
ура


2
Використовуючи Windows 10 lxss (тобто Ubuntu Bash) з репо в файловій системі Windows з git в Linux, я подумав, що це проблема, що закінчується рядком. Навіть не вважав, що може бути різним і спосіб, яким відрізняються режими файлів.
Метт Л

Це спрацювало для мене, коли я змінив локальний O / S з Ubuntu на Windows. Ура
Марк Бакнелл,

@MattL та itsandy я зазвичай розробляю на Win 10 разом з Git Bash, але сьогодні я на Mac і бачу, що git вважає, що .gitignoreфайли змінилися, коли їх не було. На цьому Mac, git config core.filemodeвідповідає з true. Я змінив це false, але це не допомогло.
Райан

43

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

git add -uv 

щоб додати зміни.
він додав 3 файли (не всі), які я фактично змінив. і після цього статус git показує лише 3 модифіковані файли. після git фіксувати все в порядку зі статусом git


2
Спасибі, це було те, що мені було потрібно. Я використовував пропозицію @ sehe порівняти md5sum, щоб перевірити, чи файли однакові (у моєму випадку вони були). Після цього за допомогою прапора -u правильно відфільтрували ці файли без фактичних відмінностей від файлів із змінами.
STW

Дякую, це було корисно. У мене була ця проблема після того, як я працював npm iу корені свого проекту. Так чи інакше, багато файлів отримували інші закінчення рядків, що створювало цю проблему.
Сервер Халілов

це те, чого я очікував ... зміни, які були зроблені, залишилися, і спокій
Deepak,


24

У моєму випадку файли з'являлися як змінені після зміни дозволів на файли .

Щоб змінити дозвіл на 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) .
(Об’єднав Хуніо С Хамано - gitster- у комітеті 05f1539 , 03 лютого 2016 р.)

ls-files: додати еольну діагностику

Працюючи в середовищі між платформами, користувач може захотіти перевірити, чи зберігаються текстові файли в нормалізованому сховищі та чи .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'), і який атрибут діє, для кожного показаного шляху .


Хоча це і показує проблему, вона її не виправляє.
Greeso

7

Ось як я вирішив проблему в Linux, коли я клонував проект, створений у Windows:

для Linux, щоб все працювало належним чином, ви повинні мати це налаштування: core.autocrlf = input

ось як його встановити: git config - вхідний core.autocrlf

Потім знову клонуйте проект з github.


Це працювало для мене у сценарії, коли я використовую Visual Studio у Windows, але я виконую комміти та додаткові перевірки в WSL у командному рядку. У командному рядку кожен файл відображався як змінений, але у Visual Studio змінилося лише кілька файлів. Я додав autoclrf = вхід у свій .gitconfig файл і це миттєво виправив. Дякую!
Big Data Брайан

5

У FAQ про Git є відповідь, яка може бути актуальною, хоча я ніколи раніше не стикався з цим:

Чому git diff іноді перераховує файл, який не має змін?

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

Що git statusдля вас показує?


git statusпросто показує величезний список файлів у модифікованому розділі.
Aron Rotteveel

@Aron: виходячи з цієї підказки, я б сказав: 85% каже, що конверсія
lineend

4
Ого. Нагадування про те, наскільки нерозбірливі деякі офіційні документи git.
Марс

2

Після копіювання мого локального сховища та робочої копії в іншу папку (до речі, у Windows) у мене було чотири файли, які відображалися як змінені, і спробував кожну пропозицію, вказану в інших відповідях. Зрештою, для мене це було виправлено - видалення локальної гілки та завантаження її знову з пульта. У моєму випадку я гадаю, що це мало щось стосується скопіювання локального сховища, а не клонування.


2

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

Виявляється, я це зрозумів, бо думав, що я повинен просто оновити Git до останньої версії, яку я і зробив, але запущений git --versionвернув старий номер версії. Після наступного пошуку, чому я знайшов корінь каталогу cygwin bin в моєму середовищі, який містив виконуваний git, працює під номером старої версії. Піди розберися.

Це також було важко знайти, оскільки в мене встановлений TortoiseGit. Мої інструменти командного рядка використовуватимуть версію cygwin завдяки спадам шляху, а TortoiseGit був налаштований на використання версії Windows, зробивши її ще більш заплутаною.

Сподіваюся, це комусь допомагає.


1
Хороший улов. +1. Ось чому я завжди встановити мій шлях сам, як і в stackoverflow.com/a/44351065/6309
VonC

Я часто дозволяю інсталятору встановити PATH, але потім перевіряю його вручну, що я тут зробив. Моя попередня установка мала git 2.4.x (x86), а я встановив git 2.13.x (x64). Ви можете уявити мою плутанину, коли я видалив посилання на шлях x86 і все-таки отримав 2,4 !! Ось тоді я побачив каталог сміттєвих кіл у Cygwin, і це здавалося наступним логічним місцем для пошуку. Тож налаштування FWIW або навіть візуально перевірка вашого PATH може не вирішити це, якщо каталог бін Cygwin буде вперше вказаний!
dudewad

1

Мені, здається, є лише підозрілий запис у вашому конфігурації core.ignorecase. Ви можете спробувати скасувати це за допомогою:

  git config --unset core.ignorecase

... і подивіться, git statusчи git diffвідрізняється результат від або .



0

Для мене це було тому, що обидва VM Linux були відображені в одній домашній файловій системі. Один VM працював git-1.7.1, а інший - git-2.14

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

Як тільки 'git status' запустився на VM, що працює з g-2.14, тоді обидва VM почнуть повідомляти про сховище як про чисте. "git status" має побічні ефекти. Це не незмінна операція. І git-1.7.1 не розуміє світ так само, як це робить git-2 +.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.