Git откат до коммита

Git откат до коммита

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

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

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

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

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

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

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

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

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

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

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

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

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

Читайте также:  8 800 5 500 500 Чей номер

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

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

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

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

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

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

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

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

Временно оформить предыдущий коммит

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

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

Если в рабочей директории были внесены нежелательные изменения восстановить состояние можно выполнив

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

Команда подтянет изменения из последнего сделанного коммита — содержимого HEAD. Локальные файлы будут замещены.

При этом те, изменения, которые уже были добавлены в индекс с git add в нем останутся.

Если коммиты не нужны — самый простой способ привести состояние локальной системы в соответствие состоянию удаленной:

Все данные в индексе и коммиты сбрасываются, состояние восстанавливается из указанной ветки, в примере master.

Читайте также:  Black ups es 700

Самая частая практика при откате изменений git

Можно не трогать индекс и локальные файлы просто удаляя коммиты.

reflog выведет все список всех действий

reset возвращает состояние по индексу, взятому из списка

Таким же образом можно отменить последний коммит

После знака тильды можно указать любое другое число;

1 означает, что отменяется последний коммит,

3, что последние три и т.д. Список всех коммитов и комментариев можно увидеть выполнив git log

Другой способ сделать то же

Ключ —soft означает, что данные удалены не будут, только коммит, если заменить его на —hard удалятся и данные

В удаленном репозитории откатить изменения можно таким же образом — убрав последние коммиты, затем выполнив git push с локальной системы на которой ведется разработка.

Конфликты при внесении изменений в git репозитории неизбежны — если какое-то действие не возможно система не даст его выполнить и будет выводить предупреждения. Они обычно весьма информативны и конфиликты в версиях разрешаются редактированием файлов вручную.

Я хочу вернуться к более раннему коммиту. Как мне это сделать?

Вот что показывает команда git log :

1 ответ 1

Этот вопрос можно понять по-разному:

  1. Что значит вернуться или откатиться: просто посмотреть, изменить содержимое рабочей области, изменить историю Git?
  2. Что именно откатить: рабочую область (worktree), индекс (область подготовки коммита, staging area), текущую ветку, удаленную ветку?
  3. К какой позиции откатить: к индексу, к последнему коммиту, к произвольному коммиту?

Обозначим начальную ситуацию на следующей схеме:

A , B , C , D — коммиты в ветке master .
(HEAD) — местоположение указателя HEAD.
(i) — состояние индекса Git. Если совпадает c (HEAD) — пуст. Если нет — содержит изменения, подготовленные к следующему коммиту.
(wt) — состояние рабочей области проекта (working tree). Если совпадает с (i) — нет неиндексированных изменений, если не совпадает — есть изменения.
↑ обозначает коммит, на который указывает определенная ветка или указатель.

Вот решения, в зависимости от задачи:

Если вам нужно просто переключиться на другой коммит, чтобы, например, посмотреть на его содержимое, достаточно команды git checkout :

Сейчас репозиторий находится в состоянии «detached HEAD». Чтобы переключиться обратно, используйте имя ветки (например, master ):

Читайте также:  Fujifilm x t100 обзор

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

3.1 Безопасно — с помощью кармана (stash)

3.1.1 Только неиндексированные

Можно удалить прикарманить только те изменения, которые еще не были индексированы (командой add ):

3.1.2 Индексированные и нет

Эта команда отменяет все индексированные и неиндексированные изменения в рабочей области, сохраняя их в карман (stash).

Восстановление несохраненных изменений: легко и просто.

Если stash совсем не нужен, его можно удалить.

После этого восстановить изменения всё ещё можно, но сложнее: How to recover a dropped stash in Git?

3.2 Опасный способ

Осторожно! Эта команда безвозвратно удаляет несохраненные текущие изменения из рабочей области и из индекса Если они вам все-таки нужны, воспользуйтесь git stash .

Восстановление несохраненных изменений: неиндексированные потеряны полностью, но вы можете восстановить то, что было проиндексировано.

Здесь мы будем использовать git reset —hard

Осторожно! Эта команда переписывает историю Git-репозитория. Если вы уже опубликовали ( git push ) свои изменения, то этот способ использовать нельзя (см. почему). Используйте вариант из пункта 5 ( git revert ).

4.1 При этом сохранить изменения в индекс репозитория:

После этого индекс репозитория будет содержать все изменения от cccccc до dddddd . Теперь вы можете сделать новый коммит (или несколько) на основе этих изменений.

4.2 Сохранить изменения в рабочей области, но не в индексе.

Эта команда просто перемещает указатель ветки, но не отражает изменения в индексе (он будет пустым).

4.3 Просто выбросить изменения.

Осторожно! Эта команда безвозвратно удаляет несохраненные текущие изменения. Если удаляемые коммиты не принадлежат никакой другой ветке, то они тоже будут потеряны.

Восстановление коммитов: Используйте git reflog и этот вопрос чтобы найти и восстановить коммиты; иначе сборщик мусора удалит их безвозвратно через некоторое время.

Восстановление несохраненных изменений: неиндексированные потеряны полностью, но вы можете восстановить то, что было проиндексировано.

Воспользуйтесь командой git revert . Она создает новые коммиты, по одному на каждый отменяемый коммит. Таким образом, если нужно отменить все коммиты после aaaaaa :

Восстановление: Если revert-коммит оказался ошибочным, используйте этот ответ.

Ссылка на основную публикацию
Adblock detector