Git: вернуться к предыдущей фиксации

Если я чему-то научился за 15 с лишним лет программирования, так это тому, что ошибки - обычное дело, и я делаю их много. Это в равной степени относится и к инструментам управления версиями. Независимо от того, случайно ли вы зафиксировали изменения или только что осознали, что ваш предыдущий зафиксированный код - это не то, что вам нужно, часто вам нужно отменить предыдущую фиксацию в Git. В этой статье я покажу несколько способов отменить ваши коммиты в зависимости от вашего варианта использования. Это сложная тема (что верно для многих тем Git в общих

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

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

Удалить неопубликованные коммиты

Если вы еще не опубликовали свои коммиты в удаленном репозитории, таком как GitHub, вы можете удалить предыдущие коммиты с помощью команды reset .

Хотя это эффективное решение, оно опасно, поскольку вы переписываете историю и оставляете «удаленные» коммиты без ссылок или «сиротскими». Единственный способ найти и восстановить эти коммиты без git reflog .

Команда reset имеет три различных варианта, два из которых мы опишем здесь:

 $ git reset --hard <hash-or-ref> 

Используя параметр --hard , все возвращается к указанной фиксации. Сюда входят указатели ссылок на историю фиксации, промежуточный индекс и ваш рабочий каталог.

Это означает, что, используя только эту команду, вы не только вернетесь к предыдущей фиксации, но и потеряете все рабочие изменения в процессе. Чтобы не потерять какие-либо рабочие изменения, вы можете использовать команды stash и stash pop :

 $ git stash 
 $ git reset --hard <hash-or-ref> 
 $ git stash pop 

Команда stash сохраняет ваши рабочие изменения (без каких-либо коммитов или изменений в дереве), а затем stash pop возвращает их.

Другой вариант, который вы можете рассмотреть, - это опция --soft Этот параметр работает почти так же, как git reset --hard <hash-or-ref> , но влияет только на историю коммитов, а не на ваш рабочий каталог или промежуточный индекс.

 $ git reset --soft <hash-or-ref> 

Так что, если у вас есть незафиксированные изменения, которые вы хотите сохранить, то это, вероятно, тот вариант, который вам нужен.

Удаление опубликованных коммитов

Допустим, вы зафиксировали свой код, а затем отправили его в удаленный репозиторий. На этом этапе настоятельно рекомендуется не использовать что-то вроде git reset так как вы будете переписывать историю.

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

 $ git revert <hash-or-ref> 

Допустим, в вашем репо есть текстовый файл со следующим содержимым:

 This is my sample text 

А затем вы меняете его на:

 This is my awesome sample text 

История ваших коммитов может выглядеть примерно так:

 $ git log --pretty=oneline 
 676ec97a9cb2cebbb5c77904bbc61ced05b86f52 Added 'awesome' to text 
 735c5b43bf4b5b7107a9cc3f6614a3890e2889f6 Initial commit 

Если мы решим, что больше не хотим использовать "awesome" в нашем тексте, но не хотим удалять 676ec , мы можем использовать revert чтобы отменить это изменение:

 $ git revert 676ec 
 [master f68e546] Revert "Added 'awesome' to text" 
 1 file changed, 1 insertion(+), 1 deletion(-) 

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

 $ git log --pretty=oneline 
 f68e546ac2ae240f22b2676b5aec499aab27f1ca Revert "Added 'awesome' to text" 
 676ec97a9cb2cebbb5c77904bbc61ced05b86f52 Added 'awesome' to text 
 735c5b43bf4b5b7107a9cc3f6614a3890e2889f6 Initial commit 

В результате первая и третья фиксации представляют одно и то же состояние проекта. Фиксация была отменена, и история не была потеряна.

Обратите внимание, что есть несколько других способов использования этой команды, например, если вы хотите отменить 2 фиксации, вы можете использовать:

 $ git revert HEAD~2 

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

 $ git revert 676ec 735c5 

Временно проверить предыдущую фиксацию

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

 $ git checkout <hash-or-ref> 

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

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus