Как удалить файл из индекса в git?

356

Как удалить файл из индекса (= область размещения = кэш), не удаляя его из файловой системы?

hcs42
источник
5
Вы имеете в виду «сброс к тому, что было раньше» или «удалить, потому что я больше не хочу этот файл»?
Эндрю Айлетт
В моем случае это то же самое, потому что файл не существовал раньше ...
hcs42

Ответы:

505

Ты хочешь:

git rm --cached [file]

Если вы пропустите --cachedопцию, она также будет удалена из рабочего дерева. git rmнемного безопаснее, чем git reset, потому что вы будете предупреждены, если промежуточный контент не соответствует ни концу ветви, ни файлу на диске. (Если этого не произойдет, вы должны добавить --force.)

Джон Феминелла
источник
8
Это также прекрасно работает, если, например, вы случайно зарегистрировали некоторые промежуточные сборки или локальные файлы конфигурации, которые не попали в ваш .gitignore; используйте, git rm --cachedчтобы удалить их из репозитория, добавить соответствующие файлы или каталоги в .gitignore, подготовить и зафиксировать как обычно. Они исчезнут из репо, но останутся нетронутыми в вашем локальном дереве, и вы случайно не зарегистрируете их снова.
Ионокласт Бригам
22
Это также удаляет файл из репо (удаленного) после фиксации и нажатия.
powder366
6
Это не удаляет его из индекса, но помечает его как удаленный в индексе.
JotaBe
4
Этот ответ, скорее всего, неверен, поскольку он удаляет файл из репозитория (как уже упоминалось @ powder366), что не является ожидаемым результатом.
Отомо
1
Это решение не сработало для меня. Он пометил указанный файл как удаленный, а затем удаляет его из локального репо.
Paiego
134

Это должно отменить удаление файла <file> (без удаления или иного изменения файла):

git reset <file>
Дэвид Андерхилл
источник
6
Это удаляет последнее изменение для конкретного файла, но сохраняет его в репозитории (удаленно) после фиксации и отправки.
powder366
1
Это ответ, который я искал. Обратите внимание, что вам не нужно указывать HEAD.
Майкл Дорст
Хороший вопрос @MichaelDorst. Я обновил ответ, чтобы пропустить HEAD!
Дэвид Андерхилл
3
git reset HEAD <file> 

для удаления конкретного файла из индекса.

а также

git reset HEAD

для удаления всех проиндексированных файлов.

Абдул Гафур
источник
1

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

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

  • git gui <- использует оконный фреймворк Tk - стиль, аналогичный gitk
  • git cola <- более современный графический интерфейс

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


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

  • git rm --cached [file]
  • git reset HEAD <file>

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


Работа без индекса

Основываясь на комментариях и голосах, я понял, что многие люди используют индекс все время. Я не. Вот как:

  • Передайте всю мою рабочую копию (типичный случай): git commit -a
  • Зафиксируйте всего несколько файлов: git commit (list of files)
  • Зафиксируйте все, кроме нескольких измененных файлов: git commit -aзатем внесите изменения черезgit gui
  • Графически просмотрите все изменения в рабочей копии: git difftool --dir-diff --tool=meld
nobar
источник
@ Мартин: Я думаю, это зависит от вашего рабочего процесса. В моем подходе я никогда не использую индекс напрямую. Когда я хочу сохранить свою работу, я просто делаю коммиты git commit -a. Когда я отвечал на этот вопрос, это было потому, что я сделал (экзотический) « обратный выбор вишни », который помещает файлы в индекс для вас, но я хотел отредактировать файл перед фиксацией. Я удалил файл из индекса, пока редактировал его, чтобы diff работал так, как я привык.
Нобар
Мой случай использования был очень узким и бесполезным: создать ветку; добавить папку, заполненную файлами только для ветки; переключиться на мастера; слияния; ops, в мастер добавили неверную папку, добавили в gitignore; файлы не будут удалены из коммитов, лучшее решение - просто использовать rmсразу, но я сначала подумал, что переключение ветвей не приведет к уничтожению игнорируемой папки. но ... я использую инструмент github, основанный на графическом интерфейсе, который мне подходит, и поддерживаю управление индексами, за исключением того, что оно не поддерживает это. и что, я должен использовать 2 графических интерфейса для узкого использования? все еще не могу согласиться с ответом.
Cregox
3
Это решительно непопулярный ответ. Тем не менее, я вполне уверен, что подход, который я предлагаю, является правильным для некоторых людей (включая меня). Я использую один из этих инструментов для манипулирования индексом несколько раз в год.
Нобар
1
В настоящее время редакторы и IDE программирования, скорее всего, будут поддерживать графические манипуляции с индексами. По крайней мере, GitHub's Atom делает.
Нобар
1
Я предпочитаю cli-интерфейс, а не графический интерфейс, хотя это более опасно. Это позволит мне использовать git даже без графического интерфейса, который мне нравится (вместо того, чтобы потеряться, когда я не могу установить такие инструменты, например, на удаленном сервере). Все, что говорит, что этот ответ совершенно действителен и не заслуживает "отрицательных" голосов, +1 за предоставление хорошей альтернативы графическому интерфейсу!
SidOfc