мерзавец удалить старые коммиты - PullRequest
0 голосов
/ 08 мая 2018

Я сделал глупую ошибку и случайно зафиксировал папку node_modules в моем локальном git и затем отправил ее в github. Это огромная папка, и любой другой, кто скачивает мой репозиторий, также будет загружать эту папку в старых коммитах. Я безуспешно пытаюсь удалить коммиты с rebase --onto и rebase -i. Вот так выглядит мой git log.

$ git log --oneline
44549c5f (HEAD -> alex/matUI, origin/alex/matUI) fighting with gitignore
a5a5a79c changed ui to material   ##<---- remove me!
dbec4ab3 converting to material ui      ##<---- remove me!
cd4352f6 (origin/master, origin/HEAD, master) Merge pull request #1 from notsmart/addFullstack
a058bf1e moved files to new repo
80c82607 Added README.md

Как бы вы удалили эти коммиты?

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

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

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

(Обычно я бы сказал, что вам нужно согласие / координация для любого, у кого есть копия репо; здесь, если вы видите в качестве репо, что вы позволяете другим клонировать, я полагаю, вы могли бы сказать лишь меру координация хороша, но если вы не ограничиваете толчки происхождением, существует вероятность того, что кто-то сделает «неправильное исправление» и повторно введет плохой коммит, что бы мы ни говорили, «правильно».)

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

Вы можете просто удалить все коммиты, которые были сделаны с момента добавления папки 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

0 голосов
/ 08 мая 2018

Вы должны сделать две вещи:

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

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

Во-первых:

git rebase -i HEAD ~ 4

Теперь у вас есть открытый редактор со строками, похожими на те, что вы написали. Удалите строки с коммитами, которые вам не нужны. Сохраните и выйдите из редактора.

Проверьте git log, правильно ли это.

Тогда:

git push -f

Пояснение:

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

Затем вы удалили строки фиксации и сохранили. Git попытался создать новую цепочку коммитов, чтобы применить желаемые изменения. Фактически были созданы новые коммиты (часть коммита - ссылка на предыдущий), поэтому есть новые хеши для коммитов, которые были изменены (потому что технически они новые). Вы увидите, что origin / alex / matUI больше не находится в вашей HEAD (в git log).

Наконец ты толкнул с силой. Это перезаписало origin / alex / matUI с вашим текущим alex / matUI. Это на самом деле перезаписывает любую ветку, на которую указывает ваш HEAD, и связана с веткой по источнику (ваш alex / matUI связан с origin / alex / matUI, это не волшебство, это явная связь, которую вы либо создали вручную, либо создали при вытягивании / клонировании). Обычно push является консервативным, допускает только добавления после кончиков ваших веток. -f проходит через это. Используйте силу Люка :) 1039 *

...