Как использовать Git Revert

110

Как git revertиспользуется?

Это может звучать как повторяющийся вопрос, но когда люди задают его, ответ часто звучит git resetтак: « Вернуть к фиксации» с помощью хэша SHA в Git?

Затем, когда кто-то спрашивает, как использовать, git resetлюди отвечают, что вы должны использовать git revertсогласно Git - как откатиться

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

Итак, давайте попробуем придерживаться брифинга и написать руководство для чайников git revert.

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

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

Это и есть контроль версий. Я уверен, что это легко.

Хорошо, собираешься использовать, git revertно как?

И после бега git revertнужно ли делать что-то еще после? Вы должны зафиксировать изменения, которые были сделаны, или сделать возврат непосредственно в репо, или что?

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

Люк Пуплетт
источник

Ответы:

124

git revert делает новую фиксацию

git revert просто создает новую фиксацию, противоположную существующей фиксации.

Он оставляет файлы в том же состоянии, как если бы отмененная фиксация никогда не существовала. Например, рассмотрим следующий простой пример:

$ cd /tmp/example
$ git init
Initialized empty Git repository in /tmp/example/.git/
$ echo "Initial text" > README.md
$ git add README.md
$ git commit -m "initial commit"
[master (root-commit) 3f7522e] initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
$ echo "bad update" > README.md 
$ git commit -am "bad update"
[master a1b9870] bad update
 1 file changed, 1 insertion(+), 1 deletion(-)

В этом примере история фиксации содержит две фиксации, последняя из которых является ошибкой. Использование git revert:

$ git revert HEAD
[master 1db4eeb] Revert "bad update"
 1 file changed, 1 insertion(+), 1 deletion(-)

В журнале будет 3 коммита:

$ git log --oneline
1db4eeb Revert "bad update"
a1b9870 bad update
3f7522e initial commit

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

cat README.md 
Initial text

Неважно, где в истории находится коммит, который нужно отменить (в приведенном выше примере отменяется последний коммит - любой коммит может быть отменен).

Заключительные вопросы

вам нужно сделать что-то еще после?

A git revert- это просто еще одна фиксация, поэтому, например, нажмите на удаленный компьютер, чтобы другие пользователи могли вытащить / получить / объединить изменения, и все готово.

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

git revert является фиксацией - нет никаких дополнительных шагов, предполагающих, что откат одной фиксации - это то, что вы хотели сделать.

Очевидно, вам нужно будет подтолкнуть снова и, возможно, объявить об этом команде.

В самом деле - если пульт находится в нестабильном состоянии - правильным решением будет сообщить остальной части команды, что им нужно выполнить, чтобы получить исправление (откат фиксации).

AD7six
источник
В качестве подтверждения как для первого утверждения здесь, так и для всех, кто интересуется тем же самым, что я только что интересовался, как это работает, вы можете отменить откат, когда есть несколько новых коммитов с момента отката, который вы возвращаете. Итак, откат на самом деле - это просто фиксация, противоположная отмененной фиксации. У вас, конечно, могут быть конфликты ... но это другая история.
GG2
Я всегда считаю, что лучше избегать коммитов с этим, просто чтобы сначала просмотреть изменения, и я использую, git revert -n <commitToRevet> или git revert --no-commit <commitToRevet>
Эклавия
2
Просто хотел сказать, что после многих лет работы с stackoverflow, я думаю, что это может быть один из лучших ответов, с которыми я когда-либо сталкивался. Отличный пример и объяснение. Спасибо.
user3344977 02
Я вошел сюда, ожидая получить больше информации, что-то вроде TLDR этого raw.githubusercontent.com/git/git/master/Documentation/howto/…
wviana
1
@wviana Если информации, которую вы нашли, недостаточно, напишите ответ. Обратите внимание, что переполнение стека не заменяет официальную документацию (на которую вы, похоже, ссылаетесь, и охватывает гораздо более широкий круг вопросов, чем этот вопрос).
AD7six,
35

Используйте git revert так:

git revert <insert bad commit hash here>

git revertсоздает новую фиксацию с отмененными изменениями. git resetстирает вашу историю git вместо того, чтобы делать новую фиксацию.

Последующие шаги такие же, как и при любом другом коммите.

Джонни З
источник
Разница между «откатить фиксацию» и «вернуться к фиксации» достаточно тонкая, поэтому я много лет боролся с этой командой. Ваше объяснение помогло мне мгновенно решить эту проблему. Спасибо!
claviska
24

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

В частности, люди, которые привыкли к SVN или P4 и хотят выбросить незафиксированные изменения в файл, часто обращаются к ним, revertпрежде чем им скажут, что они действительно хотят reset.

Аналогично, revertэквивалент в других VCS часто называется rollbackили что-то подобное, но «откат» также может означать «Я хочу полностью отменить несколько последних коммитов», что подходит, resetно не подходит revert. Итак, возникает большая путаница, когда люди знают, что они хотят сделать, но не понимают, какую команду они должны использовать для этого.

Что касается ваших реальных вопросов о возврате ...

Хорошо, вы собираетесь использовать git revert, но как?

git revert first-bad-commit..last-bad-commit

И после запуска git revert вам нужно делать что-то еще после? Вы должны зафиксировать изменения, которые были сделаны, или сделать возврат непосредственно в репо, или что?

По умолчанию git revertзапрашивает сообщение о фиксации, а затем фиксирует результаты. Это можно изменить. Цитирую страницу руководства :

--редактировать

С этой опцией git revert позволит вам отредактировать сообщение фиксации перед фиксацией возврата. Это значение по умолчанию, если вы запускаете команду из терминала.

--no-commit

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

Это полезно при возврате эффекта нескольких коммитов к вашему индексу подряд.

В частности, по умолчанию он создает новую фиксацию для каждой отменяемой фиксации. Вы можете использовать revert --no-commitдля создания изменений, отменяя их все, не фиксируя эти изменения как отдельные коммиты, а затем фиксировать на досуге.

Ядовитая лягушка
источник
git revert first-bad-commit..last-bad-commit: Думаю так и должно быть git revert parent-of-first-bad-commit..last-bad-commit.
user1071847
10

Вопрос довольно старый, но откат все еще сбивает с толку людей (таких как я)

Как новичок, после некоторых проб и ошибок (больше ошибок, чем проб) у меня есть важный момент:

  • git revertтребует идентификатор коммита, который вы хотите удалить, сохраняя его в своей истории

  • git resetтребует фиксации, которую вы хотите сохранить , и впоследствии удалит все, что будет после этого, из истории.

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

Чтобы быть еще более понятным, с журналом вроде этого:

# git log --oneline

cb76ee4 wrong
01b56c6 test
2e407ce first commit

Используя git revert cb76ee4волю по умолчанию принести свои файлы обратно в 01b56c6 и добавит еще совершить свою историю:

8d4406b Revert "wrong"
cb76ee4 wrong
01b56c6 test
2e407ce first commit

git reset 01b56c6 вместо этого вернет ваши файлы на 01b56c6 и очистит любой другой коммит после этого из вашей истории:

01b56c6 test
2e407ce first commit

Я знаю, что это «основа», но меня это сбивало с толку, запустив revertпервый идентификатор ('первая фиксация'), я ожидал найти свои исходные файлы, потребовалось некоторое время, чтобы понять, что если вам понадобятся ваши файлы обратно в качестве «первой фиксации» вам нужно использовать следующий идентификатор.

nnsense
источник
Я наблюдал то же самое. это действительно сбивает с толку, но так важно знать. совсем недавно мне пришлось помочь коллеге и я забыл об этом. Это было немного неловко.
ExOfDe
1

Я отменил несколько коммитов, выполнив git revert commit id, например:

git revert b2cb7c248d416409f8eb42b561cbff91b0601712

Затем мне было предложено зафиксировать откат (точно так же, как при запуске git commit). Моя терминальная программа по умолчанию - Vim, поэтому я запустил:

:wq 

Наконец, я отправил изменение в репозиторий с помощью:

git push
jrc16
источник