"git status" показує змінені файли, але "git diff" не має


181

Я переглянув усі подібні запитання. Однак я двічі перевірив, і щось дивне напевно відбувається.

На одному сервері (Solaris з Git 1.8.1) я клонував сховище Git, після чого скопіював папку .git у мої існуючі живі файли. Це спрацювало чудово, я міг бігати

git status

тоді

git diff [filename]

перевірити будь-які файли, які відрізнялися.

На іншому сервері (Solaris з Git 1.7.6) я все одно точно так само

git diff [filename]

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


9
Це у вашому індексі? Якщо це так, ви можете переглянути розд git diff --cached.
jeremyharris

2
git diff --cachedпросто дає і пустий вихід.
Олівер П

git logтакож не дає результатів.
Олівер П

Припускаючи, що дійсно є помилка, ви повинні мати можливість створити мінімальний приклад. Спробуйте відтворити його та поділіться зразком.
mheinzerling

1) Змінено режим файлу? Шукайте тутcore.fileMode варіант 2) Також я зіткнувся з подібною проблемою з конфігурацією Console2 (я маю її під git), коли Console2 насправді працює. Можливо, своєрідне блокування файлів робить git до того, що файл змінився.
madhead

Відповіді:



63

Є кілька причин, чому git statusможе виявитись різниця, але git diffне може.

  • Режим (біт дозволу) файлу змінився - наприклад, з 777 на 700.

  • Стиль подачі рядків змінився з CRLF (DOS) на LF (UNIX)

Найпростіший спосіб дізнатися, що сталося, - це запустити git format-patch HEAD^і подивитися, що говорить створений патч.


11
якщо застосовуються файли дозволів на зміни: git config core.filemode false для дозволу ігнорування файлів
jruzafa

Як ви дізналися, що зміна каналу рядка з CRLF на LF - одна з ситуацій, коли статус git виявить різницю, а git diff не буде?
Алекс Спрінглінг

Співробітники, які використовують Windows, допоможуть вам з’ясувати всілякі цікаві речі про закінчення рядків. Я думаю, що можуть бути випадки, коли "git diff" показує зміну від CRLF до LF, хоча - це, мабуть, залежить від вашої конфігурації. Я деякий час не працював з Windows, тому не знаю, які зараз є дефолти.
cmccabe

59

Для мене це мало відношення до прав доступу до файлів. Хтось із Mac / Linux в моєму проекті, здається, вчинив деякі файли з недозволеними дозволами, які мій клієнт Windows git не зміг відтворити. Для мене рішенням було сказати git ігнорувати дозволи файлів:

git config core.fileMode false

Інше розуміння: Як зробити так, щоб змінити режим файлу Git ігнорувати (chmod)?


Це вирішило проблему, з якою у мене було безліч файлів, хоча я думаю, що це було з файлом, створеним / зміненим часом.
Дерек

Це вирішило це для мене. Значення fileMode видається за замовчуванням істинним у томах Mac / Linux та false у томах Windows. Я перемістив проект з Mac на Windows, і його потрібно було переключити на false.
geekinit

1
Це також допомогло, якщо ви використовуєте VSCode за допомогою контейнера Docker, який монтує ваш каталог у Windows 10. На зовнішній стороні контейнера, перевіряючи стан git, правильно показано, що ви не змінили жодних файлів. Але якщо ви перевіряєте стан git всередині контейнера, він показує, що файли змінені. Запуск вищевказаної команди всередині контейнера вирішив мою проблему.
Фредерік Оллінгер

39

У мене виникла проблема, коли сотні закінчень рядків були модифіковані якоюсь програмою і git diffперераховані всі вихідні файли як змінені. Після виправлення закінчень рядків git statusфайли все ще перераховані як змінені.

Мені вдалося виправити цю проблему, додавши всі файли до індексу, а потім скинувши індекс.

git add -A
git reset

core.filemode було встановлено на хибне.


Дякую! Працював як шарм!
Starwave

1
Я вирішив git add --renormalize ., дивіться свою відповідь нижче.
Стефано М

17

Я підозрюю, що з установкою Git або з вашим сховищем щось не так.

Спробуйте запустити:

GIT_TRACE=2 git <command>

Подивіться, чи отримаєте ви щось корисне. Якщо це не допомагає, просто використовуйте штрих і подивіться, що відбувається не так:

strace git <command>

6
@towi: Оскільки це коштувало тебе великої винагороди, мені було б цікаво побачити, що ти дізнався про причину подібних невдач.
cfi

5
У моєму випадку я додав -Fпрапор до LESSзмінної env, яка повідомляє менше виходити, якщо є менше одного екрана, повного інформації. Оскільки git використовує менше як пейджер, а у мене була невелика розбіжність, нічого не було показано. Або мені довелося додати -Xдо LESSenv, який показує вміст на екрані навіть після менших виходів, або просто видалити -F. GIT_TRACEпоказав, lessщо виконується, що нагадало мені, що я змінив LESSзмінну останнім часом. Ця ж причина у відповіді @ rcwxok, але хотіла прокоментувати, як GIT_TRACEдопомогла.
Raghu Dodda

Ця відповідь дає мені натяк на «пейджер» і приводить мене до вирішення про налаштування core.pagerв .gitconfig, який прекрасно працює для мене.
ytu

10

У мене була схожа проблема: git diffпоказала б відмінності, але git diff <filename>не стала. Виявилося, що я встановив LESSрядок, що включає -F( --quit-if-one-screen). Видалення цього прапора вирішило проблему.


1
Замість видалення -F, додавання -Xможе також спрацювати, див. Мою відповідь нижче для подібного випадку.
avivr

Дякую за це! Зводив мене з розуму.
hackel

9

Як уже зазначалося в попередній відповіді , така ситуація може виникнути через проблеми, що закінчуються рядками (CR / LF vs. LF). Я вирішив цю проблему (під Git версії 2.22.0) за допомогою цієї команди:

git add --renormalize .

Відповідно до посібника:

       --renormalize
           Apply the "clean" process freshly to all tracked files to
           forcibly add them again to the index. This is useful after
           changing core.autocrlf configuration or the text attribute in
           order to correct files added with wrong CRLF/LF line endings.
           This option implies -u.

Це нова найкраща відповідь.
PHPst

5

Коротка відповідь

Біг git add іноді допомагає.

Приклад

У статусі Git відображаються змінені файли, а git diff не показує нічого ...

> git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   package.json

no changes added to commit (use "git add" and/or "git commit -a")
> git diff
> 

... біг git add вирішує невідповідність.

> git add
> git status
On branch master
nothing to commit, working directory clean
> 

2
Мені це звучить як «боротьба із симптомами» замість «вилікування хвороби» ...;)
einjohn

@einjohn Як ви думаєте, в чому це захворювання?
Шон Люттін

1
Хвороба може бути декількома речами. Як зазначають інші, це може бути проблема дозволу або щось із закінченнями рядка. Це також можуть бути вже поетапні зміни. Однак ця остання можливість не відповідає вашому прикладу. Тим не менш, за допомогою свого рішення ви не дізнаєтесь причину (хворобу), ви просто усунете проблему (на перший погляд, несправний порожній розріз (симптоми)). Щоб було зрозуміло: я не кажу, що це погане рішення. Це може допомогти комусь, якщо він / вона просто хочуть, щоб проблема зникла. ... сподіваюся, я пролив трохи світла на свою хворобу-метафара. :)
einjohn

@einjohn Здається, це закінчення рядків більшу частину часу. Здається , statusі diffмають окремі способи обробки тих.
Шон Луттін

5

Я зіткнувся з цією проблемою. Мій випадок був схожий на LESSпитання розмістив rcwxok .

У моєму випадку я встановлюю PAGERзмінну середовища наPAGER='less -RSF' .

Однак, на відміну від попередніх відповідей, я не хотів видаляти цю -Fопцію, тому що я явно розміщував її там, сподіваючись запобігти показу різниці вless якщо він коротший, ніж екранний.

Для того, щоб отримати бажаний результат, а НЕ видаляти -F, я додав -X: PAGER='less -RSFX'. Це і вирішило цю git diffпроблему, і, крім того, запобігає появі коротких відмінностей less.


Капіталізація здається дивною. Ви маєте на увазі "менше -RSFX" замість "менший -RSFX"? Чи є варіанти правильним?
StackzOfZtuff

1
Так, дякую, це була помилка. Не впевнений, як це сталося. Тепер виправлено.
avivr

3

Я щойно побіг у подібному питанні. git diff fileнічого не показав , бо я додав файл індексу Git з деякою частиною його імені в верхньому регістрі: GeoJSONContainer.js.

Після цього я перейменував його на GeoJsonContainer.jsзміни, і зміни перестали відслідковуватися. git diff GeoJsonContainer.jsнічого не показував. Мені довелося видалити файл із індексу із силовим прапором та додати файл ще раз:

git rm -f GeoJSONContainer.js
git add GeoJSONContainer.js

2

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

Моє припущення щодо Вашого випадку використання:

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

Дійсно є два способи.

Клон репо - mv .git - git reset - твердий

Цей метод - те, що ви зробили - клонуйте існуючий сховище в порожній каталог, а потім перемістіть .gitкаталог у каталог призначення. Щоб працювати без проблем, це зазвичай вимагає того, щоб ви запустили

git reset --hard

Однак це змінить стан файлів у вашому поточному каталозі. Ви можете спробувати це на повній копії / rsync свого каталогу та вивчити, що змінюється. Принаймні після цього ви більше не бачите розбіжностей між git logта status.

Запустіть новий сховище - вкажіть на походження

Друга менш тривожна: cdдо вашого пункту призначення та запустіть нове сховище

git init

Тоді ви скажете тому новому сховищу, що він має десь ще предка:

git remote add origin original_git_repo_path

Тоді безпечно

git fetch origin master

копіювати дані без зміни локальних файлів. Зараз все повинно бути добре.

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


Здається, ви маєте на увазі, що це помилка git . Гаразд, може бути. Я все-таки припускав, що мені бракує належного розуміння git, тому що я не такий розумний, як Лінус ;-)
towi

@towi: Ні, я не маю на увазі, що це помилка git, або я не маю на увазі зворотне. Я не знайомий з внутрішніми органами git. Але, як правило, переміщуючи .gitпапки в інші робочі зони, ми потенційно порушуємо припущення про git. Якщо це призводить до хаотичної поведінки, ми не можемо звинувачувати git, ми повинні звинувачувати себе у тому, щоб грати в трюки з git. git забезпечує засоби для виправлення цього, наприклад reset --hard. Просто це не те, що ми хочемо. Саме ця причина init/remote addрекомендується шляхом, і все добре.
cfi

@towi та Oliver P: Хоча я розумію, що ви хочете вирішити ваш конкретний випадок помилок, іноді просто радимо звернутися із загальними рекомендаціями, особливо якщо вони ідеально відповідають вашому випадку використання. Також немає втрат даних. А remote addспосіб зробити все ще можна застосувати до такої заплутаної ситуації, як описана Олівером П
cfi

1
Повторне повідомлення без коментарів не допомагає покращити цю відповідь, як і сайт в цілому. Хто не сприймає голосів, залиште коментар, щоб проблему можна було вирішити.
cfi

1

Я знову натрапив на цю проблему. Але цього разу це сталося з іншої причини. Я скопіював файли в репо, щоб перезаписати попередні версії. Тепер я бачу, що файли змінені, але diff не повертає diff.

Наприклад, у мене є файл mainpage.xaml. У File Explorer я вставив новий файл mainpage.xaml над файлом у моєму поточному репо. Я зробив роботу на іншій машині і просто вставив файл сюди.
git показує модифікований

Файл показує модифікований, але коли я запускаю git diff, зміни не відображатимуться. Можливо, тому, що інформація про файл змінилася і git знає, що це насправді не той самий файл. Цікаво.

git diff не показує нічого

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


1

У мене ця проблема була описана наступним чином: Якщо я вводив текст

$ git diff

Git просто повернувся до підказки без помилок.

Якщо я набрав

$ git diff <filename>

Git просто повернувся до підказки без помилок.

Нарешті, читаючи навколо, я помітив, що git diffнасправді закликає mingw64\bin\diff.exeвиконувати роботу.

Ось угода. Я запускаю Windows і інсталював іншу утиліту Bash, і вона змінила мій шлях, щоб він більше не вказував на мій каталог mingw64 \ bin .

Тож якщо ви введете:

git diff

і він просто повертається до підказки, у вас може виникнути ця проблема.

Фактичний diff.exe, яким керує, gitзнаходиться у вашому каталозі mingw64 \ bin

Нарешті, щоб виправити це, я фактично скопіював свій mingw64\binкаталог у місце, де його шукав Git. Я спробував це, і він все ще не працював.

Потім я закрив своє вікно Git Bash і знову відкрив його, перейшов до мого того ж сховища, яке вийшло з ладу і зараз воно працює.

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