Git не видит изменений в файле

Обновлено: 21.11.2024

При работе в Git или других системах управления версиями понятие "сохранение" представляет собой процесс с более тонкими нюансами, чем сохранение в текстовом процессоре или других традиционных приложениях для редактирования файлов. Традиционное программное выражение «сохранение» является синонимом термина Git «фиксация». Коммит — это Git-эквивалент «сохранения». Традиционное сохранение следует рассматривать как операцию файловой системы, которая используется для перезаписи существующего файла или записи нового файла. Кроме того, фиксация в Git — это операция, которая воздействует на набор файлов и каталогов.

Сохранение изменений в Git и SVN — это тоже другой процесс. SVN Commits или «check-in» — это операции, которые делают удаленную отправку на централизованный сервер. Это означает, что для фиксации SVN требуется доступ в Интернет, чтобы полностью «сохранить» изменения проекта. Коммиты Git можно захватить и создать локально, а затем при необходимости отправить на удаленный сервер с помощью основной команды git push -u origin. Разница между этими двумя методами является фундаментальным отличием архитектурных проектов. Git — это модель распределенного приложения, тогда как SVN — это централизованная модель. Распределенные приложения, как правило, более надежны, поскольку у них нет единой точки отказа, как у централизованного сервера.

В Git есть дополнительный механизм сохранения, который называется "заначка". Тайник — это временная область хранения изменений, которые не готовы к фиксации. Тайник работает с рабочим каталогом, первым из трех деревьев, и имеет широкие возможности использования. Чтобы узнать больше, посетите страницу git stash.

Репозиторий Git можно настроить так, чтобы он игнорировал определенные файлы или каталоги. Это предотвратит сохранение Git изменений в любом игнорируемом содержимом. Git имеет несколько методов настройки, которые управляют списком игнорирования. Настройка игнорирования Git более подробно обсуждается на странице игнорирования Git.

добавьте git

Команда git add добавляет изменение рабочего каталога в промежуточную область. Он сообщает Git, что вы хотите включить обновления определенного файла в следующую фиксацию. Однако на самом деле git add не оказывает существенного влияния на репозиторий — изменения фактически не записываются до тех пор, пока вы не запустите git commit .

В сочетании с этими командами вам также потребуется git status для просмотра состояния рабочего каталога и промежуточной области.

Как это работает

Команды git add и git commit составляют основной рабочий процесс Git. Это две команды, которые должен понимать каждый пользователь Git, независимо от модели совместной работы его команды. Они служат для записи версий проекта в историю репозитория.

Разработка проекта основывается на базовом шаблоне редактирования/этапа/фиксации. Сначала вы редактируете свои файлы в рабочем каталоге. Когда вы будете готовы сохранить копию текущего состояния проекта, вы вносите изменения с помощью git add . После того, как вы довольны подготовленным снимком, вы фиксируете его в истории проекта с помощью git commit . Команда git reset используется для отмены фиксации или промежуточного снимка.

В дополнение к git add и git commit третья команда git push необходима для полного совместного рабочего процесса Git. git push используется для отправки зафиксированных изменений в удаленные репозитории для совместной работы. Это позволяет другим членам команды получить доступ к набору сохраненных изменений.

Команду git add не следует путать с svn add , которая добавляет файл в репозиторий. Вместо этого git add работает на более абстрактном уровне изменений. Это означает, что git add нужно вызывать каждый раз, когда вы изменяете файл, тогда как svn add нужно вызывать только один раз для каждого файла. Это может показаться излишним, но такой рабочий процесс значительно упрощает организацию проекта.

Промежуточная зона

Основная функция команды git add — перенести отложенные изменения в рабочем каталоге в промежуточную область git. Промежуточная область — одна из самых уникальных функций Git, и может потребоваться некоторое время, чтобы разобраться с ней, если вы работаете с SVN (или даже с Mercurial). Это помогает думать об этом как о буфере между рабочим каталогом и историей проекта. Промежуточная область считается одним из «трех деревьев» Git, наряду с рабочим каталогом и историей коммитов.

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

Общие параметры

Подготовить все изменения в файле> для следующей фиксации.

Подготовить все изменения в каталоге> для следующего коммита.

Начните интерактивный промежуточный сеанс, который позволит вам выбрать части файла для добавления к следующей фиксации. Это представит вам часть изменений и запросит команду. Используйте y, чтобы подготовить фрагмент, n, чтобы игнорировать фрагмент, s, чтобы разделить его на более мелкие фрагменты, e, чтобы отредактировать фрагмент вручную, и q, чтобы выйти.

Примеры

Когда вы начинаете новый проект, git add выполняет ту же функцию, что и svn import . Чтобы создать начальную фиксацию текущего каталога, используйте следующие две команды:

После того, как вы запустите свой проект, вы можете добавить новые файлы, указав путь к git add :

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

Обзор

В обзоре git add — это первая команда в цепочке операций, которая указывает Git «сохранить» моментальный снимок текущего состояния проекта в истории коммитов. При самостоятельном использовании git add будет продвигать ожидающие изменения из рабочего каталога в промежуточную область. Команда git status используется для проверки текущего состояния репозитория и может использоваться для подтверждения продвижения git add. Команда git reset используется для отмены git add . Затем команда git commit используется для фиксации моментального снимка промежуточного каталога в истории фиксации репозиториев.

Я пытаюсь отправить свои файлы на github с помощью bash. Они уже там, и я загружаю более новую версию с новыми строками и кодом и т. д. Но когда я пытаюсь выполнить git add, а затем git status, он говорит:

На мастере ветки

нечего коммитить, рабочий каталог чист

И файл, который я использую, был только что изменен.

Если git diff (или git status ) ничего не показывает, это объясняет, почему нечего добавить. Итак, вопрос на самом деле: «Почему git не распознает, что мой файл был изменен?»

30 ответов 30

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

Вы можете указать git прекратить игнорировать изменения в файле с помощью:

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

На практике я обнаружил, что удаление кэшированного файла и его сброс заработали:

Команда git rm --cached означает только удаление файла из индекса, а reset указывает git перезагрузить индекс git из последней фиксации.

Этот ответ был единственным, который помог решить мою проблему. Не уверен, что это связано с Windows (у меня никогда не было таких проблем в прошлом, ни в OSX, ни в Linux). Так что спасибо @ThorSummoner. Кстати, я попробовал git add -f файл, который был в этом состоянии «предполагать неизменным», и это не сработало — пришлось либо git update-index, либо git rm --cached с последующим сбросом git, чтобы заставить его работать. < /p>

Кроме того, если вы действительно не уверены в текущем состоянии своего репозитория, сделайте следующее: git rm --cached -r . а затем git reset . .

Проверьте файл .gitignore. Вы можете обнаружить, что файл, или расширение файла, или путь к файлу, с которым вы пытаетесь работать, соответствует записи в .gitignore , что объясняет, почему этот файл игнорируется (и не распознается как измененный файл).

Это оказалось для меня, когда у меня была аналогичная проблема.

Я использовал gitignore.io для создания своего .gitignore и нашел строку с lib/ , что заставляет git игнорировать эту папку. С этим проблем нет — по крайней мере, если эта папка не является основной папкой вашего проекта, как это случилось со мной.

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

Звучит безумно, но иногда вы находитесь не в том репозитории, хотя вам так кажется. Например, вы могли переместить родительский каталог, но забыли переключить репозитории в текстовом редакторе. Или наоборот: вы находитесь в правильном репозитории в текстовом редакторе, но в неправильном репо в командной строке. В первой ситуации вы вносите изменения в правильный файл, но это не та папка, которая открыта в вашей командной строке, так что на самом деле это не тот файл. Во второй ситуации вы на самом деле отредактировали нужный файл, но ваша командная строка git не распознает изменение, потому что вы находитесь не в правильном каталоге в командной строке.

Как уже обсуждалось, файлы, вероятно, были помечены как "предположим-без изменений", что в основном говорит git, что вы не будете изменять файлы, поэтому ему не нужно отслеживать изменения с ними. Однако это может повлиять на несколько файлов, и если это большое рабочее пространство, вы можете не захотеть проверять их все по одному. В этом случае вы можете попробовать: git update-index --really-refresh

согласно документам:

По сути, это заставит git отслеживать изменения всех файлов независимо от флагов "предполагать, что они не изменились".

Для меня статус git говорит, что файлы не изменены, но git add . добавляет два файла, а git update-index --really-refresh говорит, что этим двум нужны обновления, но, похоже, ничего не делает. Есть идеи?

Ну, у нас недостаточно данных, чтобы ответить на этот вопрос, поэтому я дам вам несколько предположений:

1) вы спрятали свои изменения, для исправления введите: git stash pop

2) у вас были изменения, и вы их зафиксировали, вы должны увидеть свою фиксацию в журнале git

3) у вас были изменения, сделанные git reset --hard или другие, ваши изменения могут быть там в reflog, введите git reflog --all с последующей проверкой или выбором вишни ref, если вы когда-нибудь найдете это.

4) вы проверяли одно и то же хранилище несколько раз и ошиблись.

1) тайник не найден 2) у меня есть изменения, которые я зафиксировал, могу ли я зафиксировать их снова? 3) я этого не делал 4) я в правильном репозитории

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

Произошла забавная вещь. Git-плагин Eclipse Kepler автоматически помечал все папки моего проекта как игнорируемые в папке .gitignore.

Когда я должен был зафиксировать в меню "Команда", все они снова становились игнорируемыми. Насколько я могу судить, это произошло потому, что я установил их как производные в родительском проекте. Снятие пометки с них как dervied исправило это. Я никогда не видел этого раньше на Indigo. Надеюсь, это кому-нибудь поможет.

У меня была неправильная конфигурация подмодуля git. Я пошел в корень репозитория и выполнил эти команды для каталогов, в которых ранее были папки .git:

Затем каталоги появились в статусе git.

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

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

В Windows git status использует, среди прочего, отметку времени файла и изменения размера файла, чтобы определить, изменился ли файл. Таким образом, поскольку отметка времени не была обновлена, у нее был только размер файла. К сожалению, рассматриваемый файл был файлом простой версии, содержимое которого изменилось с 7.1.2 на 7.2.0. Другими словами, размер файла также не изменился. Другие файлы, которые также были изменены WinMerge, и у которых не были обновлены временные метки, но они имели другой размер после того, как изменение было обнаружено статусом git, просто отлично.

TL;DR; Вы вообще находитесь в правильном репозитории?

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

На самом деле на моей машине было два отдельных репозитория git repo1 и repo2, настроенных в одном и том же корневом каталоге с именем source . Эти два репозитория, по сути, являются репозиториями двух продуктов, над которыми я постоянно работаю в своей компании. Теперь дело в том, что стандартная структура каталогов исходного кода всех продуктов в моей компании одинакова.

Поэтому, не осознавая, я изменил точно такой же именованный файл в repo2, который я должен был изменить в repo1. Итак, я просто продолжал запускать команду git status на repo1, и она продолжала выдавать одно и то же сообщение

На мастере ветки

нечего коммитить, рабочий каталог чист

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

Я использую Git последние пару недель. Проект простой, и ветки нет. С сегодняшнего дня, когда я делаю изменения в отслеживаемом файле, эти изменения не отображаются в команде git diff. Я не могу добавить и зафиксировать этот файл, так как в нем нет изменений.

Когда я смотрю на Git Status, отслеживаемый файл там тоже недоступен. Что мне делать?

Вот как выглядит мой файл конфигурации.

Редактировать: Спасибо за помощь и потраченное время на решение моей проблемы. Последнее предложение от /u/yes_or_gnome решило проблему

Если это ничего не дало. Затем mv .git/index .git/index.bak (предполагается, что каталог .git находится в текущем каталоге. Если не исправить путь.) Затем git reset и git status.

Проект простой, ветки нет.

К вашему сведению, филиал всегда есть. Если вы не укажете его вручную, он будет просто мастером.

Да, я запутался в терминологии. Есть идеи по поводу моей проблемы?

Сначала попробуйте git status -uall --ignored . Каков результат? Он указан как «Неотслеживаемый», «Неустановленный», «Добавленный»?

Если файл "Не помещен" или "Добавлен", проблем нет.

Затем попробуйте git ls-files | грэп . Выход? Указан ли файл в списке?

Где шаблон имени файла будет соответствовать части фактического имени файла. Так, например, у меня есть файл с именемtests/unit/topology.py, я мог бы использовать topo для шаблона, который уменьшил бы сотни файлов до нескольких; на самом деле, 7 в моем случае.

Если файл НЕ указан в списке ls-files , значит, он каким-то образом или кем-то был закэширован git rm --cached. Вам придется добавить его обратно.

Если он указан в ls-файлах и не отслеживается в статусе, значит, он где-то игнорируется.

Есть как минимум три места, куда вы можете заглянуть. Во-первых, .gitignore может находиться в любом каталоге вашего репозитория; find $GIT_DIR -name '\.gitignore', чтобы найти их все. Во-вторых, $GIT_DIR/info/exclude — это исключения вашего локального репо, которые никому не передаются. В-третьих, вы глобальный файл игнорирования, который применяется ко всем локальным репозиториям. Проверьте git config core.excludesFile, в противном случае это либо $XDG_CONFIG_HOME/git/ignore, либо $HOME/git/ignore; зависит от того, установлен ли XDG_CONFIG_HOME.

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

Сначала давайте удостоверимся, что мы все еще находимся в правильном каталоге. Вы должны быть в каталоге планет.

Если вы все еще находитесь на лунах, вернитесь к планетам

Давайте создадим файл с именем mars.txt, содержащий некоторые примечания о материалах на Марсе. Мы будем использовать nano для редактирования файла; вы можете использовать любой редактор, который вам нравится. В частности, это не обязательно должен быть core.editor, который вы установили глобально ранее. Но помните, команда bash для создания или редактирования нового файла будет зависеть от выбранного вами редактора (это может быть не nano ). Чтобы освежить в памяти текстовые редакторы, ознакомьтесь с разделом «Какой редактор?» в уроке Оболочка Unix.

Введите приведенный ниже текст в файл mars.txt:

mars.txt теперь содержит одну строку, которую мы можем увидеть, запустив:

Если мы снова проверим статус нашего проекта, Git сообщит нам, что заметил новый файл:

Сообщение «неотслеживаемые файлы» означает, что в каталоге есть файл, который Git не отслеживает. Мы можем указать Git отслеживать файл с помощью git add :

а затем убедитесь, что все произошло правильно:

Теперь Git знает, что он должен отслеживать mars.txt, но еще не зафиксировал эти изменения как фиксацию. Чтобы это сделать, нам нужно запустить еще одну команду:

Когда мы запускаем git commit , Git берет все, что мы сказали ему сохранить с помощью git add, и постоянно сохраняет копию в специальном каталоге .git. Эта постоянная копия называется фиксацией (или ревизией), а ее краткий идентификатор — f22b25e. Ваш коммит может иметь другой идентификатор.

Мы используем флаг -m (для «сообщения»), чтобы записать короткий описательный и конкретный комментарий, который поможет нам позже вспомнить, что мы сделали и почему. Если мы просто запустим git commit без параметра -m, Git запустит nano (или любой другой редактор, который мы настроили как core.editor ), чтобы мы могли написать более длинное сообщение.

Хорошие сообщения о коммите начинаются с краткого описания ( . Если вы хотите углубиться в детали, добавьте пустую строку между строкой сводки и вашими дополнительными примечаниями. Используйте это дополнительное место, чтобы объяснить, почему вы внесли изменения и/или как они повлияли на будет.

Если мы сейчас запустим git status:

это говорит нам, что все обновлено. Если мы хотим узнать, что мы сделали в последнее время, мы можем попросить Git показать нам историю проекта с помощью git log:

Журнал git перечисляет все коммиты, сделанные в репозиторий, в обратном хронологическом порядке. Список для каждого коммита включает полный идентификатор коммита (который начинается с тех же символов, что и короткий идентификатор, напечатанный командой git commit ранее), автора коммита, когда он был создан, и сообщение журнала, которое Git дал, когда коммит был создан.

Где мои изменения?

Если мы запустим ls в этот момент, мы по-прежнему увидим только один файл с именем mars.txt. Это связано с тем, что Git сохраняет информацию об истории файлов в специальном каталоге .git, упомянутом ранее, чтобы наша файловая система не загромождалась (и чтобы мы не могли случайно отредактировать или удалить старую версию).

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

Когда мы сейчас запускаем git status, он сообщает нам, что файл, о котором он уже знает, был изменен:

Последняя строка — это ключевая фраза: «в фиксацию не добавлено никаких изменений». Мы изменили этот файл, но не сказали Git, что хотим сохранить эти изменения (что мы делаем с помощью git add ), и не сохранили их (что мы делаем с помощью git commit ). Итак, давайте сделаем это сейчас. Рекомендуется всегда просматривать наши изменения перед их сохранением. Мы делаем это с помощью git diff. Это показывает нам разницу между текущим состоянием файла и самой последней сохраненной версией:

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

  1. Первая строка сообщает нам, что Git производит вывод, аналогичный команде Unix diff, сравнивающей старую и новую версии файла.
  2. Вторая строка сообщает, какие именно версии файла сравнивает Git; df0654a и 315bf3a — это уникальные этикетки, созданные компьютером для этих версий.
  3. Третья и четвертая строки снова показывают имя изменяемого файла.
  4. Остальные строки наиболее интересны, они показывают нам фактические различия и линии, на которых они встречаются. В частности, маркер + в первом столбце показывает, где мы добавили строку.

После проверки нашего изменения пришло время его зафиксировать:

Ой! Git не зафиксирует, потому что мы не использовали сначала git add. Давайте это исправим:

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

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

Промежуточная зона

Если вы думаете о Git как о создании моментальных снимков изменений за время существования проекта, git add указывает, что будет помещено в моментальный снимок (помещая вещи в промежуточную область), а затем git commit затем < em>фактически берет снимок и делает постоянную запись о нем (как фиксация). Если у вас ничего не подготовлено, когда вы вводите git commit , Git предложит вам использовать git commit -a или git commit --all , что похоже на сбор всех для картинки! Тем не менее, почти всегда лучше явно добавлять что-то в область подготовки, потому что вы можете зафиксировать изменения, которые вы забыли сделать. (Возвращаясь к моментальным снимкам, вы можете получить дополнительную информацию из-за незавершенного макияжа, идущего по сцене для моментального снимка, потому что вы использовали -a !) Попробуйте настроить все вручную, или вы можете обнаружить, что ищете «git undo commit» больше, чем вы бы лайк!

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

Читайте также: