Любое решение, которое вы можете применить, будет переписано в истории. Это означает, что это отрицательно повлияет на кого-либо еще с копией вашего репозитория, и если они предпримут неправильные действия при попытке восстановления, это может отменить ваше исправление.
Поэтому наличие такой ситуации в общедоступном репо является довольно прискорбной ситуацией, хотя, если вам случится узнать, что ее клонировали не так много людей (или, может быть, никто), на практике это не так уж плохо. Главное, сообщить о том, что вы делаете, таким образом, чтобы все пользователи репо могли быть в курсе.
(Обычно я бы сказал, что вам нужно согласие / координация для любого, у кого есть копия репо; здесь, если вы видите в качестве репо, что вы позволяете другим клонировать, я полагаю, вы могли бы сказать лишь меру координация хороша, но если вы не ограничиваете толчки происхождением, существует вероятность того, что кто-то сделает «неправильное исправление» и повторно введет плохой коммит, что бы мы ни говорили, «правильно».)
В любом случае, знайте об этом, но с этим ничего не поделаешь. Вы должны переписать историю, и вопрос в том, как.
Вы можете просто удалить все коммиты, которые были сделаны с момента добавления папки node_modules
, но, конечно, тогда вы потеряете все другие изменения из этих коммитов. Самый простой способ избавиться от node_modules
без потери другой истории (и без сторонних инструментов) будет git filter-branch
.
Конечно, вы хотите убедиться, что у вас есть все ссылки локально. Поскольку ваш репо, вероятно, является подлинным оригиналом, который вы скопировали на github, все должно быть в порядке. Но при необходимости вы можете получить или даже сделать клон --mirror
источника, чтобы начать все сначала. Тогда
git filter-branch --index-filter 'git rm --cached --ignore-unmatch -r node_modules' -- --all
Если у вас есть коммиты, которые ничего не меняют за пределами node_modules
и вы хотите отменить эти коммиты, вы можете добавить опцию --prune-empty
перед разделителем --
.
(В репо с большой историей (много коммитов) это может быть медленным, в этом случае вы можете рассмотреть сторонний инструмент, такой как BFG Repo Cleaner, который является более специализированным инструментом для удаления больших / нежелательных файлы из истории (в отличие от filter-branch
, который является гораздо более универсальным инструментом).
После того, как вы запустите это и проверите, что ваша история выглядит нормально, вы захотите провести некоторую очистку локального репо. Возможно, проще всего использовать его для создания нового клона.
cd ..
git clone file://localhost/path/to/old/repo newrepo
Если вы хотите очистить исходный локальный репозиторий, вам нужно удалить набор «резервных ссылок», созданных filter-branch
(под refs/original
), и, вероятно, стереть эти флаги, а затем использовать gc
чтобы фактически выбросить ненужные объекты.
Что касается репо на github, опять же может оказаться, что удалить его и воссоздать его будет проще всего - особенно если у вас много переписанных веток. Кроме того, вы можете принудительно нажать (git push -f
) на каждую переписанную ветвь и обратиться к документации по github за информацией о серверной стороне gc