Мерзавец: Как удалить файл из индекса, не удаляя файлы ни из какого репозитория

Когда Вы используете

git rm --cached myfile

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

Существует ли способ просто удалить файл из управления версиями, не удаляя его ни из какой файловой системы?

Править: Разъясненный, я надеюсь.

157
задан Nick Volynkin 24 June 2015 в 07:30
поделиться

3 ответа

Я не думаю, что коммит Git может записать намерение типа «прекратить отслеживание этого файла, но не удалять его».

Реализация такого намерения потребует вмешательства извне Git в любые репозитории, которые объединяют (или перебазируют) коммит, удаляющий файл.


Сохранить копию, применить удаление, восстановить

Вероятно, самый простой способ сделать - это сказать нижестоящим пользователям, чтобы они сохранили копию файла, подтвердили удаление, а затем восстановили файл. Если они загружаются через rebase и «переносят» изменения в файл, у них будут конфликты. Чтобы разрешить такие конфликты, используйте git rm foo.conf && git rebase --continue (если конфликтующий коммит содержит изменения помимо удаленного файла) или git rebase --skip ( если конфликтующий коммит изменился только на удаленный файл).

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

Если они уже вытащили вашу фиксацию удаления, они все равно могут восстановить предыдущую версию файла с помощью git show :

git show @{1}:foo.conf >foo.conf

Или с помощью git checkout (за комментарий Уильяма Перселла; но не забудьте повторно удалить его из индекса!):

git checkout @{1} -- foo.conf && git rm --cached foo.conf

Если они предприняли другие действия после получения вашего удаления (или они выполняли операцию с перебазированием в отдельная ГОЛОВА), им может понадобиться что-то другое, кроме @ {1} . Они могут использовать git log -g , чтобы найти фиксацию непосредственно перед тем, как они вытащили ваше удаление.


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

Сохранить файл по умолчанию и активировать его вручную / автоматически

Если продолжение сохранения содержимого файла конфигурации в репозитории не является полностью неприемлемым, вы можете переименовать отслеживаемый файл из (например) foo.conf в foo.conf.default , а затем проинструктируйте своих пользователей cp foo.conf.default foo.conf после применения фиксации переименования. {{ 1}} Или, если пользователи уже используют какую-либо существующую часть репозитория (например, сценарий или другую программу, настроенную в соответствии с содержимым репозитория (например, Makefile или аналогичный)) для запуска / развертывания вашего программного обеспечения, вы можете включить механизм по умолчанию в процесс запуска / развертывания:

test -f foo.conf || test -f foo.conf.default &&
    cp foo.conf.default foo.conf

Имея такой механизм по умолчанию, пользователи должны иметь возможность извлечь фиксацию, которая переименовывает foo.conf в foo.conf .default без необходимости выполнять дополнительную работу. Кроме того, вам не придется вручную копировать файл конфигурации, если вы сделаете дополнительные l установки / репозитории в будущем.

Перезапись истории в любом случае требует ручного вмешательства…

Если недопустимо поддерживать содержимое в репозитории, вы, вероятно, захотите полностью удалить его из истории с помощью чего-то вроде git filter-branch --index-filter … . Это равносильно перезаписи истории, что потребует ручного вмешательства для каждой ветки / репозитория (см. Раздел «Восстановление из исходной базы» на странице руководства git rebase ).Специальная обработка, необходимая для вашего файла конфигурации, будет просто еще одним шагом, который необходимо выполнить при восстановлении после перезаписи:

  1. Сохраните копию файла конфигурации.
  2. Восстановить после перезаписи.
  3. Восстановите файл конфигурации.

Игнорировать это, чтобы предотвратить повторение

Какой бы метод вы ни использовали, вы, вероятно, захотите включить имя файла конфигурации в файл .gitignore в репозитории, чтобы никто не мог случайно git add foo.conf снова (это возможно, но требует -f / - force ). Если у вас более одного файла конфигурации, вы можете подумайте о «перемещении» их всех в один каталог и игнорировании всего этого (под «перемещением» я имею в виду изменение того, где программа ожидает найти свои файлы конфигурации, и заставить пользователей (или механизм запуска / развертывания) копировать / перемещать файлы в новое место; очевидно, вы не захотите git mv файл в каталог, который вы будете игнорировать).

113
ответ дан 23 November 2019 в 21:45
поделиться

Чтобы удалить файл из индекса, используйте:

git reset myfile

Это не должно повлиять на вашу локальную копию или чью-либо еще.

30
ответ дан 23 November 2019 в 21:45
поделиться

После выполнения команды git rm --cached попробуйте добавить myfile в файл .gitignore (создайте его, если он не существует). Это должно указать git игнорировать myfile .

Файл .gitignore версирован, поэтому вам нужно зафиксировать его и отправить в удаленный репозиторий.

15
ответ дан 23 November 2019 в 21:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: