Поиск по сайту:

Как на самом деле работает Git Reset? Объяснение мягкого, жесткого и смешанного сброса


git reset – мощная команда, которая может изменить историю вашего репозитория Git и исправить допущенные вами ошибки. Однако, несмотря на то, что из-за названия его использование кажется пугающим, на самом деле это довольно просто, поэтому давайте поговорим о том, как это работает.

Что такое Git HEAD?

Прежде чем понять, как работают сбросы, нам нужно поговорить о Git HEAD.

«HEAD» — это просто псевдоним вашего текущего рабочего коммита. Вы можете думать об этом как о головке проигрывателя, положение которой определяет, какие данные используются. Если вы сейчас используете ветку master, HEAD будет последней фиксацией в этой ветке.

Несмотря на то, что HEAD является псевдонимом коммита, в большинстве случаев он не указывает напрямую на коммит. Он указывает на ветку и автоматически использует последнюю фиксацию. Он также может указывать на фиксацию напрямую, что известно как «отделенный HEAD», хотя это не имеет значения для git reset.

Как работает сброс Git?

История коммитов Git хранится в виде дерева коммитов и по большей части должна быть неизменной. Однако иногда необходимо изменить эту историю, и здесь в игру вступает git reset.

Каждая фиксация связана с предыдущей фиксацией и может разветвляться на разные ветви, которые в конечном итоге объединяются обратно в ветвь master. В любом случае HEAD обычно указывает на последний коммит в той ветке, над которой вы работаете.

Так что же происходит, когда вы делаете коммит, который хотите отменить?

Ну, запуск git reset по сути перемещает HEAD назад и оставляет все коммиты перед ним зависшими. Это переписывает обычно неизменную историю Git, чтобы избавиться от коммитов перед HEAD.

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

Или, возможно, вы случайно сделали фиксацию, которая включала некоторые изменения, которые вы не хотели отслеживать. Это может быть очень сложно понять, если вы не знаете, как работает git reset , но этого можно добиться, сбросив HEAD, а затем только подготовив правильные изменения. Обратите внимание, что это отличается от git revert, который отменяет коммиты.

В Git есть три разных вида сброса, и все они различаются в зависимости от того, как они обрабатывают коммиты, которые остались зависшими. Все они переписывают историю Git, и все они перемещают HEAD назад, но по-разному относятся к изменениям:

  • git reset --soft, который сохранит ваши файлы и автоматически вернет все изменения.
  • git reset --hard, который полностью удалит любые изменения и удалит их из локального каталога. Используйте это, только если вы знаете, что делаете.
  • git reset --mixed, который используется по умолчанию и сохраняет все файлы одинаковыми, но отменяет этапы изменений. Это самый гибкий вариант, но, несмотря на название, он не изменяет файлы.

Разница между мягким и смешанным заключается в том, являются ли изменения поэтапными или нет. Staged — это, по сути, промежуточная зона между локальным каталогом и историей Git. git add файлы этапов, а git commit записывает их в историю. В любом случае локальный каталог не затрагивается, он просто меняет состояние отслеживания Git этих изменений.

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

Использование сброса Git

Как только вы поймете, что происходит, использование git reset станет невероятно простым. Для сброса вам понадобится ссылка на фиксацию, к которой вы хотите вернуться. Вы можете получить это, запустив reflog:

git reflog

Скопируйте семизначный код справа. Если вы только что застряли в vim, нажмите Q и, возможно, запустите git config --global core.editor \nano\.

Затем вы можете вернуться к целевому коммиту:

git reset --mixed a560612

Или вы можете ориентироваться на коммиты на основе их положения относительно HEAD. Следующая команда нацелена на коммит прямо перед HEAD, что удобно, если вам нужно сбросить последний коммит:

git reset --mixed HEAD~

Если вы используете клиент Git, такой как Fork, сброс настроек так же прост, как щелчок правой кнопкой мыши на целевом коммите и выбор «Сброс»:

Стоит ли делать жесткий сброс?

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

git fetch origin
git checkout master
git reset --hard origin/master
git clean -d --force

Конечно, вы всегда можете использовать классическое «удалить свой репозиторий и повторно клонировать из Github», но этот способ, по крайней мере, одобрен Git и сбрасывает только одну ветку.