Удалить файл из репозитория Git, не удаляя его из локальной файловой системы

2392

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

git rm mylogfile.log

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

Как удалить этот файл из репо без удаления локальной копии файла?

  • 3
    Стоит отметить, что ответ с наибольшим количеством голосов опасен для некоторых. Если вы используете удаленное хранилище, чем когда вы нажимаете локально, тогда извлекайте в другое место те файлы, которые вы удалили из git, БУДЕТ УДАЛЕНО . Это упоминается в одном из ответов, но не комментируется.
Теги:
delete-file
repository
remote-server
git-rm

9 ответов

3436
Лучший ответ

Для одного файла:

git rm --cached mylogfile.log

Для одного каталога:

git rm --cached -r mydirectory
  • 125
    Легко пропустить, потому что это не так очевидно, как svn rm --keep-local .
  • 93
    Но как мне сохранить файлы на удаленных серверах? Это сохраняет мой локальный, но если я нажму и потяну с другого сервера, файл будет удален. Я также добавил .gitignore для файла, но он все еще удален
Показать ещё 5 комментариев
253

Чтобы удалить всю папку из репо (например, файлы Resharper), выполните следующие действия:

git rm -r --cached folderName

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

  • 12
    Просто добавленная заметка для будущих посетителей: не используйте графический интерфейс для «синхронизации» фиксации обратно в репо. Это вернет файлы обратно в ваш локальный репозиторий. Вы должны сделать Git Push repo branch чтобы фактически удалить файлы с пульта.
163

Вы также можете удалить файлы из репозитория на основе .gitignore, не удаляя их из локальной файловой системы:

git rm --cached `git ls-files -i -X .gitignore`

Или, альтернативно, на Windows Powershell:

git rm --cached $(git ls-files -i -X .gitignore)
  • 7
    Не работает на Windows. git ls-files -i -X .gitignore работает, но я не знаю, как отправить файлы в 'git rm'. Ты знаешь как это сделать?
  • 16
    Работает на Windows, если вы используете Git Bash вместо cmd-консоли
Показать ещё 3 комментария
65

Кроме того, если вы отправили конфиденциальные данные (например, файл, содержащий пароли), вы должны полностью удалить его из истории репозитория. Здесь объясняется, как это сделать: http://help.github.com/remove-sensitive-data/

  • 9
    Этот ответ должен включать необходимые команды для выполнения этой задачи вместо ссылки на другой веб-сайт.
  • 0
    Я также хотел бы отметить, что я нашел, что использовать инструмент git bfg repo cleaner проще и быстрее.
61

В соответствии с моим ответом здесь: https://stackoverflow.com/questions/6313126/how-to-remove-a-directory-from-git-repository

Чтобы удалить папку/каталог или файл только из репозитория git, а не из локальной, попробуйте 3 простых шага.


Шаги по удалению каталога

git rm -r --cached File-or-FolderName
git commit -m "Removed folder from repository"
git push origin master

Шаги, чтобы игнорировать эту папку в следующих коммандах

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

.gitignore файл будет выглядеть следующим образом

/FolderName

Изображение 7480

57

Более общее решение:

  • Изменить .gitignore файл.

    ECHO mylogfile.log >> .gitignore

  • Удалите все элементы из индекса.

    git rm -r -f --cached .

  • Восстановить индекс.

    git add .

  • Сделать новую фиксацию

    git commit -m "Removed mylogfile.log"

  • 1
    Будет ли это на самом деле удалить файл?
  • 5
    Из GitHub? NO. Если вы уже нажали на github, он не удалит его с сайта. Но это обновит ваш локальный репозиторий git.
Показать ещё 5 комментариев
18

Git позволяет игнорировать эти файлы, предполагая, что они не изменились. Эта выполняется командой git update-index --assume-unchanged path/to/file.txt. После маркировки файла как такового git будет полностью игнорировать любые изменения в этом файле; они не появятся, когда запуская git статус или git diff, и они никогда не будут зафиксированы.

(Из https://help.github.com/articles/ignoring-files)

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

Примечание. Это не отвечает на вопрос напрямую, но основывается на последующих вопросах в комментариях к другим ответам.

  • 2
    Хм, я делаю это, но вижу, что файл может быть перезаписан, если кто-то еще внесет изменения в репо.
5

Выше ответы не помогли мне. Я использовал фильтр-ветвь, чтобы удалить все зафиксированные файлы.

удалите файл из репозитория git с помощью

git filter-branch --tree-filter 'rm  file'

удалите папку из репозитория git с помощью

git filter-branch --tree-filter 'rm -rf directory'

Это удаляет каталог или файл из всех коммитов

вы можете указать фиксацию, используя:

git filter-branch --tree-filter 'rm -rf directory' HEAD

Или диапазон

git filter-branch --tree-filter 'rm -rf vendor/gems' t49dse..HEAD

Чтобы направить все на удаленный, вы можете сделать:

git push origin master --force
  • 2
    Это в сочетании с git rm -r --cached NAME - это хитрость, позволяющая удалить его из локального репозитория git и предотвратить его влияние на любого, кто получит позже (удалив историю файла или каталога из git.)
  • 1
    Это переписывает историю git, и вам нужно будет нажать --force после этого, это немного выходит за рамки вопроса, который я думаю. В общедоступном репо вы не можете просто изменить линию истории, так как у всех, кто уже клонировал репо, возникнут проблемы при извлечении.
4

Если вы хотите просто удалить файл и не удалить его из локального и удаленного репо, используйте команду thhis:

git update-index --assume-unchanged  file_name_with_path

Ещё вопросы

Сообщество Overcoder
Наверх
Меню