7.6. Rewriting History

Это типа конспект, который я веду для себя, чтобы получше разобраться и запомнить. Вероятно, вам лучше сразу читать оригинал: 7.6 Rewriting History.

Короткий вывод от прочтения. Рибэйз оказывается в сто раз проще сделать через терминал, чем через UI приложения, хоть SourceTree, хоть SublimeMerge, которые только усложняют и запутывают процесс.

Аменд

Изменение последнего коммита (Changing the Last Commit)

Пожалуй, самая популярная фича, чтобы поменять камент последнего коммита:

Если хотим поменять содержимое, а камент оставить преждним и не открывать текстовый редактор, то:

Рибэйз

Изменение сообщений нескольких коммитов (Changing Multiple Commit Messages)

Запускает интерактивный режим и позволяет ручками менять сообщение каждого из затронутых коммитов:

HEAD~3 значит, что вы затрагиваете коммиты в интервале HEAD~3..HEAD.

Юзаем инструкцию edit или reword. В любой непонятной ситуации пишем git rebase --continue, чтобы наверняка понимать, завершился ли rebase. Если он чего-то не сможет сделать, то он поругается и предложит варианты для исправления.

Изменение порядка коммитов (Reordering Commits)

Та же команда git rebase -i может использоваться, чтобы поменять коммиты местами. Нужно для этого в отркывшемся текстовом редактори пикнуть их (pick) в нужном порядке.

Объединение коммитов (Squashing Commits)

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

Разделение коммитов (Splitting a Commit)

Всё то же самое. Пользуемся командой edit. Он останавливается на шаге с edit, и мы можем манипулировать со стейджем, добавляем и убираем туда, что нам надо, и коммитим, потом ещё и ещё.

Алгоритм такой:

  • гит останавливается на шаге edit.
  • ресет коммита git reset HEAD^ — это отменяет коммит

и даёт вам ресетнутые изменения в рабочую копию.

  • сделать из них сколько угодно коммитов
  • когда закончили, делаем git rebase --continue

В этом месте я заодно научился добавлять в коммит изменения построчно. Про это написано в разделе https://git-scm.com/book/en/v2/Git-Tools-Interactive-Staging. Однако, пока самый удобный инструмент для построчного добавления в коммит — это SourceTree.

Удаление коммита (Deleting a commit)

Юзаем drop или просто удаляем коммит из rebase-скрипта.

Откат рибэйза

Если вы потерялись во время рибэйза, то спасительная команда git rebase --abort.

Если передумали уже после завершения, то вы можете найти старые коммиты через git reflog.

Сайт с практическим руководством по ребэйзу

The Nuclear Option: filter-branch

Эта фича даёт some scriptable way обработать много коммитов. Собственно, ради неё я и залез в этот раздел мануала.

Фича обладает множеством подводных камней, так что стоит быть осторожным.

Удаление файла из каждого коммита (Removing a File from Every Commit)

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

Грохнем файл passwords.txt из всех коммитов:

Так можно грохнуть все бэкапы оставленные вимом:

Есть смысл применять эту команду на пробной ветке и если результат устраивает, то только потом перекидывать на неё мастер.

Флаг --all запускает команду на всех ветках.

Превращаем подкаталог в корневой каталог (Making a Subdirectory the New Root)

Например, вы мигрировались из SVN и хотите подпапку trunk переместить в корень:

Меняем почту авторов