Как убрать коммиты от слова совсем?

Рейтинг: 1Ответов: 2Опубликовано: 22.07.2023

Вот такая ситуация. Примерная история коммитов с комментариями.

  1. Нормальный коммит, запушен на github
  2. Нормальный коммит
  3. Коммит, в который случайно попал новый файл на 200 мегабайт
  4. Очередной коммит.
  5. Коммит, в котором замечена неприятность, файл удален через git rm
  6. Еще один коммит

Но теперь если пушить все это на github, то получается неприятность: большой файл там не принимается, и хотя его вроде бы и нет в коммите 5 и далее, но он есть в коммитах 3 и 4, и хотя он не нужен в принципе, пуш его все равно пытается залить.

Как корректно поступить в такой ситуации? Конечно, как вариант - откат к коммиту 2, и добавление все наново руками, что было в коммитах 3 и 4. Но не кажется хорошим решением. А как поступить лучше всего?

Вот что делаю, по шагам.

Создал тестовый репозиторий на github. Создал у себя репозиторий из одного файла version с цифрой 0 внутри.

  1. Выполнил Commit 0.

Запустил прописанные на github

git remote add origin https://github.com/mikhajlo/Test.git
git branch -M main
git push -u origin main
  1. Меняю цифру в version на 1, делаю Commit 1 (git commit -a и git push).

  2. Добавляю большой файл, меняю цифру в version на 2, делаю Commit 2 (git add large.rar и git commit -a).

  3. Меняю цифру в version на 3, делаю Commit 3 (git commit -a).

  4. Удаляю большой файл (git rm -f large.rar), меняю цифру в version на 4, делаю Commit 4 (git commit -a).

  5. Меняю цифру в version на 5, делаю Commit 5 (git commit -a).

При попытке запушить получаю ошибку большого файла.

git log говорит

commit aecd9dd79cd79607b7440b013c72f3e02c7acbe6 (HEAD -> main)

    Commit 5

commit 874eb211adc6706f0626ff66db4d1092cdc3b72c

    Commit 4

commit a5c5801888b877962dfa6d6be18443723ea280a3

    Commit 3

commit 1813bf5e873ae3a7fc0ccb2f96cc7b0547f7b759

    Commit 2

commit c776ffc36977b52f8e497e90f03c9591b98c6ac3 (origin/main)

    Commit 1

commit 0fa879ac87277db8def7a43ea10323627f9ceb46

    Commit 0

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

P.S. Просьба не гнать читать учебники — Pro Git от Scott Chacon & Ben Straub прочел. Очень уж запутанно и непонятно... Если можете предложить что-то понятное (реально понятное, а не как в этой книжке...) и на русском (чтоб не мучиться сначала с переводом, потом с пониманием) - буду признателен.

P.P.S. Более непонятной системы с более непонятной идеологией и документацией не встречал, разве что Linux...

Ответы

▲ 2Принят

Переделываете историю, избавляясь от коммитов, относящихся к проблемным файлам

git rebase --onto <последний нормальный коммит> <коммит, в который случайно попал новый файл> <oчередной коммит>

Затем устанавливаете ветку на новый oчередной коммит и пушите. Коммит 1813bf5e873ae3a7fc0ccb2f96cc7b0547f7b759 будет выпилен полностью.

git checkout c776ffc36977b52f8e497e90f03c9591b98c6ac3 
git rebase --onto c776ffc36977b52f8e497e90f03c9591b98c6ac3 1813bf5e873ae3a7fc0ccb2f96cc7b0547f7b759 874eb211adc6706f0626ff66db4d1092cdc3b72c
(возможно тут попросит разрулить правку version 2 / 3)
git branch -f main
git push origin main

Если <Коммит, в который случайно попал новый файл> нужно сохранить без этого файла, то cначала переключаетесь на этот коммит, удаляете файл и делаете изменения git commit --amend, а потом перенос уже с этим отредактированным коммитом. Модифицированный коммит 1813bf5e873ae3a7fc0ccb2f96cc7b0547f7b759 останется, но без большого файла.

git checkout 1813bf5e873ae3a7fc0ccb2f96cc7b0547f7b759
git rm large.rar
git commit --amend
(Закрываете редактор комментария коммита без правок. Получаете новый коммит 2-alt.)
git rebase --onto 2-alt-id 1813bf5e873ae3a7fc0ccb2f96cc7b0547f7b759 874eb211adc6706f0626ff66db4d1092cdc3b72c
git branch -f main
git push origin main
▲ 4

Более простой (ну, как посмотреть) вариант:

git rebase -i origin/main

Эта команда сформирует файл со списком коммитов и откроет его в текстовом редакторе по умолчанию (осторожно, это может оказаться vi если вы его не настраивали).

Дальше надо найти строчку с 5м коммитом, изменить в ней команду pick на fixup и переставить её сразу после третьего. После чего файл нужно сохранить и выйти из редактора.


Еще более простой вариант доступен если вы ещё не успели сделать 5й коммит. В таком случае его можно сделать используя ключ --fixup, после чего применить rebase в режиме autosquash:

git commit --fixup 1813bf5e873ae3a7fc0ccb2f96cc7b0547f7b759
git rebase -i --autosquash origin/main

В таком случае git rebase вам откроет список комитов упорядоченных сразу как надо, вам останется только убедиться что всё правильно и выйти из текстового редактора.


PS Не игнорируйте существование GUI. Нормальные инструменты позволяют сделать всё что я написал выше без заучивания команд и копания в манах. Нормальным GUI под винду если что является Git Extensions, под линукс вроде бы тоже что-то было.