17. Удаление коммиттов из ветки
Цели
- Научиться удалять самые последние коммиты из ветки
Revert
из предыдущего раздела является мощной командой, которая позволяет отменить любые коммиты в репозиторий. Однако, и оригинальный и «отмененный» коммиты видны в истории ветки (при использовании команды git log
).
Часто мы делаем коммит, и сразу понимаем, что это была ошибка. Было бы неплохо иметь команду «возврата», которая позволила бы нам сделать вид, что неправильного коммита никогда и не было. Команда «возврата» даже предотвратила бы появление нежелательного коммита в истории git log
.
01 Команда reset
Мы уже видели команду reset
и использовали ее для согласования буферной зоны и выбранного коммита (мы использовали коммит HEAD в нашем предыдущем уроке).
При получении ссылки на коммит (т.е. хэш, ветка или имя тега), команда reset
…
- Перепишет текущую ветку, чтобы она указывала на нужный коммит
- Опционально сбросит буферную зону для соответствия с указанным коммитом
- Опционально сбросит рабочий каталог для соответствия с указанным коммитом
02 Проверьте нашу историю
Давайте сделаем быструю проверку нашей истории коммитов.
Выполните:
git hist
Результат:
$ git hist * 45fa96b 2011-03-09 | Revert "Oops, we didn't want this commit" (HEAD, master) [Alexander Shvets] * 846b90c 2011-03-09 | Oops, we didn't want this commit [Alexander Shvets] * fa3c141 2011-03-09 | Added HTML header (v1) [Alexander Shvets] * 8c32287 2011-03-09 | Added standard HTML page tags (v1-beta) [Alexander Shvets] * 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets] * 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Мы видим, что два последних коммита в этой ветке - «Oops» и «Revert Oops». Давайте удалим их с помощью сброса.
03 Для начала отметьте эту ветку
Но прежде чем удалить коммиты, давайте отметим последний коммит тегом, чтобы потом можно было его найти.
Выполните:
git tag oops
04 Сброс коммитов к предшествующим коммиту Oops
Глядя на историю лога (см. выше), мы видим, что коммит с тегом «v1» является коммитом, предшествующим ошибочному коммиту. Давайте сбросим ветку до этой точки. Поскольку ветка имеет тег, мы можем использовать имя тега в команде сброса (если она не имеет тега, мы можем использовать хэш-значение).
Выполните:
git reset --hard v1 git hist
Результат:
$ git reset --hard v1 HEAD is now at fa3c141 Added HTML header $ git hist * fa3c141 2011-03-09 | Added HTML header (HEAD, v1, master) [Alexander Shvets] * 8c32287 2011-03-09 | Added standard HTML page tags (v1-beta) [Alexander Shvets] * 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets] * 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Наша ветка master теперь указывает на коммит v1, а коммитов Oops и Revert Oops в ветке уже нет. Параметр --hard
указывает, что рабочий каталог должен быть обновлен в соответствии с новым head ветки.
05 Ничего никогда не теряется
Что же случается с ошибочными коммитами? Оказывается, что коммиты все еще находятся в репозитории. На самом деле, мы все еще можем на них ссылаться. Помните, в начале этого урока мы создали для отмененного коммита тег «oops». Давайте посмотрим на все коммиты.
Выполните:
git hist --all
Результат:
$ git hist --all * 45fa96b 2011-03-09 | Revert "Oops, we didn't want this commit" (oops) [Alexander Shvets] * 846b90c 2011-03-09 | Oops, we didn't want this commit [Alexander Shvets] * fa3c141 2011-03-09 | Added HTML header (HEAD, v1, master) [Alexander Shvets] * 8c32287 2011-03-09 | Added standard HTML page tags (v1-beta) [Alexander Shvets] * 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets] * 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Мы видим, что ошибочные коммиты не исчезли. Они все еще находятся в репозитории. Просто они отсутствуют в ветке master
. Если бы мы не отметили их тегами, они по-прежнему находились бы в репозитории, но не было бы никакой возможности ссылаться на них, кроме как при помощи их хэш имен. Коммиты, на которые нет ссылок, остаются в репозитории до тех пор, пока не будет запущен сборщик мусора.
06 Опасность сброса
Сброс в локальных ветках, как правило, безопасен. Последствия любой «аварии» как правило, можно восстановить простым сбросом с помощью нужного коммита.
Однако, если ветка «расшарена» на удаленных репозиториях, сброс может сбить с толку других пользователей ветки.