Как вернуть Git-репозиторий к предыдущему коммиту

6500

Как я могу вернуться из текущего состояния в моментальный снимок, сделанный на определенной фиксации?

Если я делаю git log, то я получаю следующий вывод:

$ git log
commit a867b4af366350be2e7c21b8de9cc6504678a61b'
Author: Me <[email protected]>
Date:   Thu Nov 4 18:59:41 2010 -0400

blah blah blah...

commit 25eee4caef46ae64aa08e8ab3f988bc917ee1ce4
Author: Me <[email protected]>
Date:   Thu Nov 4 05:13:39 2010 -0400

more blah blah blah...

commit 0766c053c0ea2035e90f504928f8df3c9363b8bd
Author: Me <[email protected]>
Date:   Thu Nov 4 00:55:06 2010 -0400

And yet more blah blah...

commit 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Author: Me <[email protected]>
Date:   Wed Nov 3 23:56:08 2010 -0400

Yep, more blah blah.

Как вернуться к фиксации с 3 ноября, т.е. зафиксировать 0d1d7fc?

  • 9
    Связано Как отменить последний коммит Git? ,
  • 84
    Вот очень четкий и подробный пост об удалении вещей в git, прямо из Github.
Показать ещё 4 комментария
Теги:
git-reset
git-checkout
git-revert

41 ответ

8356
Лучший ответ

Это сильно зависит от того, что вы подразумеваете под "revert".

Временно переключитесь на другую фиксацию

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

# This will detach your HEAD, that is, leave you with no branch checked out:
git checkout 0d1d7fc32

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

git checkout -b old-state 0d1d7fc32

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

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

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

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.

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

Отменить опубликованные коммиты с новыми коммитами

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

# This will create three separate revert commits:
git revert a867b4af 25eee4ca 0766c053

# It also takes ranges. This will revert the last two commits:
git revert HEAD~2..HEAD

#Similarly, you can revert a range of commits using commit hashes:
git revert a867b4af..0766c053 

# Reverting a merge commit
git revert -m 1 <merge_commit_sha>

# To get just one, you could use 'rebase -i' to squash them afterwards
# Or, you could do it manually (be sure to do this at top level of the repo)
# get your index and work tree into the desired state, without changing HEAD:
git checkout 0d1d7fc32 .

# Then commit. Be sure and write a good message describing what you just did
git commit

git-revert manpage действительно покрывает много этого в описании. Еще одна полезная ссылка - это раздел git-scm.com, в котором обсуждается git-revert.

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

Вы также можете найти этот ответ полезным в этом случае:
Как переместить HEAD обратно в предыдущее место? (Отдельная головка)

  • 0
    Я попробовал ваш первый метод, но потом, когда я вернулся к мастеру и попытался объединить новую ветку, он сказал, что Already up-to-date. , Я исправил свою проблему, скопировав файлы из новой ветви и во внешнюю папку, вернув мастер обратно, затем скопировав файлы обратно, переписав все вручную, затем git add git commit и git commit все мастеру. После этого я удалил новую (но временную) ветку.
  • 1
    Только одно ... как мне вернуться к голове? После выполнения git checkout 0d1d7fc32 ??
Показать ещё 64 комментария
1465

Возврат рабочей копии к последней фиксации

Чтобы вернуться к предыдущему фиксации, игнорируя любые изменения:

git reset --hard HEAD

где HEAD является последним фиксатором в вашей текущей ветке

Возврат рабочей копии к более старой фиксации

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

# Resets index to former commit; replace '56e05fced' with your commit code
git reset 56e05fced 

# Moves pointer back to previous HEAD
git reset --soft HEAD@{1}

git commit -m "Revert to 56e05fced"

# Updates working copy to reflect the new commit
git reset --hard

Кредиты переходят к аналогичному вопросу о переполнении стека, Возврат к фиксации с помощью SHA-хеша в Git?.

  • 30
    Я сделал это, но потом я не смог зафиксировать и отправить в удаленный репозиторий. Я хочу, чтобы конкретный коммит стал ГОЛОВОМ ...
  • 6
    Это означает, что вы уже выдвинули коммиты, которые хотите вернуть. Это может создать много проблем людям, которые проверили ваш код и работают над ним. Так как они не могут применить ваш коммит плавно к своим. В таком случае лучше сделать git revert. Если вы единственный, кто использует репо. Сделайте git push -f (но подумайте дважды, прежде чем делать это)
Показать ещё 12 комментариев
1361

Здесь много сложных и опасных ответов, но на самом деле это легко:

git revert --no-commit 0766c053..HEAD
git commit

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

(Флаг --no-commit позволяет git возвращать все коммиты одновременно - в противном случае вам будет предложено отправить сообщение для каждой фиксации в диапазоне, засоряя вашу историю ненужными новыми коммитами.)

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

  • 16
    Если вы действительно хотите иметь отдельные коммиты (вместо того, чтобы возвращать все с одним большим коммитом), тогда вы можете передать --no-edit вместо --no-commit , чтобы вам не приходилось редактировать сообщение коммита для каждый возврат.
  • 54
    Если один из коммитов между 0766c053..HEAD является слиянием, то возникнет ошибка (не указывать -m). Это может помочь тем, кто столкнулся с этим: stackoverflow.com/questions/5970889/…
Показать ещё 17 комментариев
173

Лучшим вариантом для меня и, возможно, для других является опция Git reset:

git reset --hard <commidId> && git clean -f

Это был лучший вариант для меня! Это просто, быстро и эффективно!


Примечание: Как уже упоминалось в комментариях, не делайте этого, если вы делитесь своей веткой с другими людьми, у которых есть копии старых коммитов

Также из комментариев, если вы хотите использовать менее "ballzy" метод, вы можете использовать

git clean -i

  • 31
    Обязательное предупреждение: не делайте этого, если вы делитесь своей веткой с другими людьми, у которых есть копии старых коммитов, потому что при таком жестком сбросе им придется заново синхронизировать свою работу с новой ветвью сброса. Для решения, которое подробно объясняет, как безопасно вернуть коммиты без потери работы с полным сбросом, см. Этот ответ .
  • 6
    Второе предупреждение @ Cupcake ... быть в курсе последствий. Обратите внимание, однако, что если вам действительно нужно, чтобы эти коммиты исчезли из истории навсегда, этот метод reset + clean сделает это, и вам нужно будет принудительно отправить ваши измененные ветви обратно на любой пульт дистанционного управления.
Показать ещё 7 комментариев
126

Прежде чем ответить, добавьте немного фона, объяснив, что это за HEAD.

First of all what is HEAD?

HEAD - это просто ссылка на текущую фиксацию (последнюю) в текущей ветке. В любой момент времени может быть только один HEAD (исключая git worktree).

Содержимое HEAD хранится внутри .git/HEAD и содержит 40 байтов SHA-1 текущего фиксации.


detached HEAD

Если вы не используете последнюю фиксацию - это означает, что HEAD указывает на предыдущую фиксацию в истории, она называется detached HEAD.

Изображение 7442

В командной строке это будет выглядеть так: SHA-1 вместо имени ветки, поскольку HEAD не указывает на конец текущей ветки:

Изображение 7443


Несколько вариантов восстановления после отсоединенной головки:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

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

На этом этапе вы можете создать ветку и начать работу с этого момента:

# Checkout a given commit.
# Doing so will result in a 'detached HEAD' which mean that the 'HEAD'
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# Create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Вы всегда можете использовать reflog. git reflog отобразит любое изменение, которое обновило HEAD и проверив нужную запись reflog, вернет HEAD к этой фиксации.

Каждый раз, когда HEAD изменяется, будет новая запись в reflog

git reflog
git checkout HEAD@{...}

Это вернет вас к вашей желаемой фиксации

Изображение 7395


git reset HEAD --hard <commit_id>

"Переместите" свою голову назад к желаемому фиксации.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.
  • Примечание: (Начиная с Git 2.7) вы также можете использовать git rebase --no-autostash.

Эта схема иллюстрирует, какая команда выполняет что. Как вы можете видеть, reset && checkout изменяет HEAD.

Изображение 7396

  • 4
    Отличный намек на git reflog , это именно то, что мне нужно
  • 2
    Ой! Все это кажется очень сложным ... разве нет простой команды, которая просто делает шаг назад в процессе? Как перейти с версии 1.1 в вашем проекте обратно на версию 1.0? Я бы ожидал что-то вроде: git stepback_one_commit или что-то ....
Показать ещё 2 комментария
116

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

git reset --soft HEAD~1
  • --soft указывает, что незаблокированные файлы должны быть сохранены как рабочие файлы, противоположные --hard, которые отбрасывают их.
  • HEAD~1 - последняя фиксация. Если вы хотите откат 3 фиксации, вы можете использовать HEAD~3. Если вы хотите откат к определенному номеру ревизии, вы также можете сделать это, используя свой SHA-хэш.

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

Источник: http://nakkaya.com/2009/09/24/git-delete-last-commit/

  • 3
    Это мягко и мягко: без риска, если вы не подтолкнули свою работу
109

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

git add . && git checkout master -f

Краткое описание:

  • Он не будет создавать никаких коммитов, как это делает git revert.
  • Он не будет отсоединять ваш ГОЛОВ, как git checkout <commithashcode>.
  • Он перекроет все ваши локальные изменения и удалит все добавленные файлы с момента последнего фиксации в ветке.
  • Он работает только с именами ветвей, поэтому вы можете вернуться только к последнему фиксации в ветке таким образом.

Я нашел гораздо более удобный и простой способ достижения результатов, приведенных выше:

git add . && git reset --hard HEAD

где HEAD указывает на последнюю фиксацию в вашей текущей ветке.

Это тот же код, что и boulder_ruby, но я добавил git add . до git reset --hard HEAD, чтобы стереть все новые файлы, созданные с момента последнего коммита, так как это то, что большинство людей ожидают, когда вернусь к последней фиксации.

86

Вы можете сделать это с помощью следующих двух команд:

git reset --hard [previous Commit SHA id here]
git push origin [branch Name] -f

Он удалит предыдущую фиксацию Git.

Если вы хотите сохранить свои изменения, вы также можете использовать:

git reset --soft [previous Commit SHA id here]

Затем он сохранит ваши изменения.

  • 0
    Я пытался полдюжины ответов в этом посте, пока не добрался до этого ... все эти другие, мой git config постоянно выдавал ошибку при попытке нажать. Этот ответ сработал. Спасибо!
  • 0
    Для меня одной деталью было то, что я потерял различия ... которые я хотел сохранить, чтобы увидеть, что я сделал в коммите, который не сработал. Поэтому в следующий раз я просто сохраню эти данные перед выполнением команды сброса
Показать ещё 1 комментарий
55

Скажем, у вас есть следующие коммиты в текстовом файле с именем ~/commits-to-revert.txt (я использовал git log --pretty=oneline для их получения)

fe60adeba6436ed8f4cc5f5c0b20df7ac9d93219
0c27ecfdab3cbb08a448659aa61764ad80533a1b
f85007f35a23a7f29fa14b3b47c8b2ef3803d542
e9ec660ba9c06317888f901e3a5ad833d4963283
6a80768d44ccc2107ce410c4e28c7147b382cd8f
9cf6c21f5adfac3732c76c1194bbe6a330fb83e3
fff2336bf8690fbfb2b4890a96549dc58bf548a5
1f7082f3f52880cb49bc37c40531fc478823b4f5
e9b317d36a9d1db88bd34831a32de327244df36a
f6ea0e7208cf22fba17952fb162a01afb26de806
137a681351037a2204f088a8d8f0db6e1f9179ca

Создайте Bash оболочку script для возврата каждого из них:

#!/bin/bash
cd /path/to/working/copy
for i in `cat ~/commits-to-revert.txt`
do
    git revert $i --no-commit
done

Это возвращает все обратно в предыдущее состояние, включая создание файлов и каталогов, а также удаляет их, передает их в вашу ветку и сохраняет историю, но вы вернули ее обратно в ту же структуру. Почему Git не имеет git revert --to <hash> вне меня.

  • 40
    Вы можете сделать git revert HEAD~3 чтобы удалить последние 3 коммита
  • 22
    @ Род - Нет, это не правильно. Эта команда вернет коммит, являющийся третьим прародителем HEAD (не последние три коммита).
Показать ещё 6 комментариев
53

Дополнительные альтернативы решениям Jefromi

Jefromi solutions, безусловно, лучшие, и вы обязательно должны их использовать. Однако, для полноты, я также хотел показать эти другие альтернативные решения, которые также могут быть использованы для возврата фиксации (в том смысле, что вы создаете новый коммит, который отменяет изменения в предыдущем commit как это делает git revert).

Чтобы быть ясными, эти альтернативы - это не лучший способ вернуть фиксации, решения Jefromi, но я просто хочу указать что вы также можете использовать эти другие методы для достижения того же уровня, что и git revert.

Альтернатива 1: Жесткий и мягкий сброс

Это очень немного измененная версия решения Charles Bailey для Вернуть фиксацию SHA-хешем в Git?:

# Reset the index to the desired commit
git reset --hard <commit>

# Move the branch pointer back to the previous HEAD
git reset --soft HEAD@{1}

# Commit the changes
git commit -m "Revert to <commit>"

В основном это работает, используя тот факт, что мягкие сбросы оставят состояние предыдущего фиксации, поставленного в области index/staging-area, которую вы затем можете зафиксировать.

Альтернатива 2: Удалите текущее дерево и замените его новым

Это решение исходит из svick-решения для Checkout old commit и делает его новым фиксатором:

git rm -r .
git checkout <commit> .
git commit

Аналогично альтернативе # 1, это воспроизводит состояние <commit> в текущей рабочей копии. Сначала нужно сделать git rm, потому что git checkout не удалит файлы, добавленные с <commit>.

  • 0
    О Альтернативе 1, один быстрый вопрос: тем самым мы не проигрываем между коммитами, верно?
  • 0
    в Альтернативе 2 точки означают что в этих командах?
Показать ещё 2 комментария
52

Вот гораздо более простой способ вернуться к предыдущему фиксации (и иметь его в неуправляемом состоянии, делать с ним все, что вам нравится):

git reset HEAD~1

Итак, нет необходимости в фиксации идентификаторов и т.д.:)

  • 0
    не сработало, git pull после этого приводит к: error: Ваши локальные изменения в следующих файлах будут перезаписаны слиянием:
  • 1
    @malhal Это потому, что у вас были незафиксированные изменения. Спрятать / сбросить их, и тогда это будет работать без этой ошибки.
51

Ничто здесь не работало для меня, кроме этой точной комбинации:

git reset --hard <commit_hash>
git push origin <branch_name> --force

Ключ здесь - это принудительное нажатие, никаких дополнительных сообщений о фиксации/фиксации и т.д.

  • 4
    Это сработало для меня, но вы должны быть осторожны, потому что вся история коммитов после аппаратного сброса потеряна, и это действие необратимо. Вы должны быть уверены, что вы делаете.
46

Хорошо, вернуться к предыдущему коммиту в git довольно просто...

Вернуть обратно без сохранения изменений:

git reset --hard <commit>

Вернитесь назад с сохранением изменений:

git reset --soft <commit>

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

Но, как вы видите, разница заключается в использовании двух флагов --soft и --hard, по умолчанию git reset с использованием флага --soft, но всегда рекомендуется использовать этот флаг, я объясняю каждый флаг:


--soft

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


--hard

Будьте осторожны с этим флагом, он сбрасывает рабочее дерево, и все изменения в отслеживаемых файлах исчезают!


Я также создал изображение ниже, которое может случиться в реальной жизни, работая с git:

Изображение 7444

43

Предполагая, что вы говорите о хозяине и в соответствующем филиале (это говорит о том, что это может быть любая рабочая ветка, о которой вы беспокоитесь):

# Revert local master branch to November 3rd commit ID
git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50

# Revert remote master branch to November 3rd commit ID
git push -f origin 0d1d7fc32e5a947fbd92ee598033d85bfc445a50:master

Я нашел ответ из сообщения в блоге Удалить удаленный репозиторий Git для определенного коммита.

  • 5
    Чем этот ответ отличается от множества других?
  • 2
    Ссылка не работает.
Показать ещё 3 комментария
35

После всех изменений, когда вы нажимаете все эти команды, вам, возможно, придется использовать:

git push -f ...

И не только git push.

  • 12
    Обязательное предупреждение: не делайте этого, если вы делитесь своей веткой с другими людьми, у которых есть копии старых коммитов, потому что подобное принудительное нажатие заставит их пересинхронизировать свою работу. Для решения, которое подробно объясняет, как безопасно вернуть коммиты без потери работы с принудительным толчком, см. Этот ответ .
  • 3
    Иногда это то, что вы хотите. Пример: совершил и передал несколько коммитов в неправильную ветвь (ветвь А). После выбора вишни для ветви B я хочу, чтобы эти коммиты были удалены из ветви A. Я бы не хотел возвращаться, так как обратный процесс позже будет применен, когда ветви A и B будут объединены вместе. Выполнение reset --hard <commitId> в ветви A с последующим принудительным нажатием удаляет эти коммиты из ветви, сохраняя их в ветви B. Я могу избежать неприятностей, потому что знаю, что никто не разрабатывает в ветви A.
Показать ещё 1 комментарий
33

Существует команда (не часть ядра Git, но она находится в пакете git-extras) специально для возврата и выполнения старых коммитов:

git back

На странице man она также может использоваться как таковая:

# Remove the latest three commits
git back 3
28

Вернитесь к последнему фиксации и игнорируйте все локальные изменения:

git reset --hard HEAD
25

Вы можете выполнить все эти начальные шаги самостоятельно и вернуться к git-репо.

  1. Вытащите последнюю версию своего репозитория из Bitbucket, используя команду git pull --all.

  2. Запустите команду git log с -n 4 с вашего терминала. Число после -n определяет количество коммитов в журнале, начиная с последнего фиксации в вашей локальной истории.

    $ git log -n 4

  3. Сбросьте git reset --hard HEAD~N истории вашего репозитория, используя git reset --hard HEAD~N где N - количество фиксаций, которые вы хотите вернуть назад. В следующем примере голова будет установлена одна фиксация, последняя фиксация в истории репозитория:

  4. Нажмите на изменение в git repo с помощью git push --force чтобы принудительно нажать на изменение.

Если вы хотите, чтобы репозиторий git имел предыдущую фиксацию

git pull --all
git reset --hard HEAD~1
git push --force
25

Выберите требуемый фиксатор и проверьте его

git show HEAD
git show HEAD~1
git show HEAD~2 

пока не получите требуемую фиксацию. Чтобы заставить HEAD указывать на это, do

git reset --hard HEAD~1

или git reset --hard HEAD~2 или что-то еще.

  • 7
    Обязательное предупреждение: не делайте этого, если вы делитесь своей веткой с другими людьми, у которых есть копии старых коммитов, потому что при таком жестком сбросе им придется заново синхронизировать свою работу с новой ветвью сброса. Для решения, которое подробно объясняет, как безопасно вернуть коммиты без потери работы с полным сбросом, см. Этот ответ .
  • 1
    Кроме того, чтобы быть ясным, git show HEAD эквивалентно просто использованию git log HEAD -1 .
20

Это еще один способ прямого reset для недавнего фиксации

git stash
git stash clear

Он напрямую очищает все изменения, которые вы делали с момента последнего коммита.

PS: У него небольшая проблема; он также удаляет все недавно сохраненные изменения тайника. Я думаю, в большинстве случаев это не имеет значения.

  • 0
    ПРИМЕЧАНИЕ. Новые файлы, не добавленные в индекс, не сохраняются. Вы тоже добавили их или удалили вручную.
  • 0
    Очистка заначки? Помимо того, что это не решение проблемы, это на самом деле вредно. Чтение самого первого предложения вопроса немедленно делает недействительным решение для тайника (что может быть полезно ТОЛЬКО для сброса в последний коммит).
20

Чтобы сохранить изменения от предыдущей фиксации в HEAD и перейти к предыдущей фиксации, выполните:

git reset <SHA>

Если изменения не требуются от предыдущей фиксации к HEAD и просто отмените все изменения, выполните следующие действия:

git reset --hard <SHA>
19

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

git add -A .
git reset --hard HEAD

Просто git reset --hard HEAD избавится от изменений, но он не избавится от "новых" файлов. В их случае они случайно перетащили важную папку где-то случайную, и все эти файлы обрабатывались как новые с помощью Git, поэтому reset --hard не исправил ее. Запустив git add -A . заранее, он явно отслеживал их все с помощью Git, который был уничтожен с помощью reset.

19

Я считаю, что некоторые люди могут прийти к этому вопросу, желая знать, как откат совершил те изменения, которые они совершили в своем хозяине, - то есть выбросить все и вернуться к происхождению/хозяину, и в этом случае сделайте следующее:

git reset --hard origin/master

https://superuser.com/questions/273172/how-to-reset-master-to-origin-master

16

Revert - это команда откат коммитов.

git revert <commit1> <commit2> 

Пример:

git revert 2h3h23233

Он способен принимать диапазон от HEAD, как показано ниже. Здесь 1 говорит: "Верните последнюю фиксацию".

git revert HEAD~1..HEAD

а затем do git push

14

Revert Most Recent Commit:

git reset --hard HEAD

HEAD - это просто ссылка на текущую фиксацию (последнюю) в текущей ветке. В любой момент времени может быть только один HEAD.

Вернитесь к более старой команде: самым быстрым способом восстановления старой версии является использование команды reset:

# Resets index to former commit
git reset 56e05fced 

# Moves pointer back to previous HEAD
git reset --soft HEAD@{1}

# Updates working copy to reflect the new commit
git reset --hard

Это перемотает вашу ветку HEAD в указанную версию. Все фиксации, которые появились после этой версии, фактически отменены; ваш проект точно так же, как и в тот момент.

Команда reset имеет несколько опций, один из наиболее интересных - флаг --soft. Если вы используете его вместо --hard, Git сохранит все изменения в этих "отмененных" в качестве локальных изменений.

Восстановление версии в новом локальном филиале

Как сказано, использование команды сброса на вашей ветке HEAD является довольно радикальным действием: оно удалит любые коммиты (в этой ветке), которые появились после указанной ревизии. Если вы уверены, что это то, что вы хотите, все в порядке.

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

git checkout -b old-project-state 0ad5a7a6

Обычно команда checkout используется для простого переключения ветвей. Однако, предоставляя параметр -b, вы также можете создать новую ветку (в данном примере - старое состояние проекта). Если вы не хотите, чтобы он начинался с текущей ревизии HEAD, вам также необходимо предоставить хеш-фиксацию - старую ревизию проекта, которую мы хотим восстановить.

Теперь у вас есть новый филиал с именем old-project-state, отражающий старую версию вашего проекта - без прикосновения или даже удаления каких-либо других коммитов или веток.

13

Попробуйте выполнить сброс до требуемого фиксации -

git reset <COMMIT_ID>

(чтобы проверить, что COMMIT_ID использует git log)

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

Теперь вы можете checkout все не добавленные файлы

git checkout.

Проверьте git log чтобы проверить свои изменения.

ОБНОВИТЬ

Если у вас есть одно и только сообщение в вашем репо, попробуйте

git update-ref -d HEAD

13

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

  1. Скопируйте весь каталог и назовите его как-нибудь еще, например, "мой проект - копия".

  2. Делать:

    git reset --hard [first-4-letters&numbers-of-commit's-SHA]
    

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

Очевидная вещь, если вы хотите продолжить состояние проекта без фактической отмены работы, поскольку этот извлеченный коммит состоит в том, чтобы снова переименовать каталог: удалить проект, содержащий извлеченный коммит (или дать ему временное имя), и переименовать ваш " мой проект - скопируйте "каталог" обратно в "мой проект". Тогда, вероятно, сделайте еще один коммит довольно скоро.

Git - блестящее творение, но вы не можете просто "поднять его на лету": также люди, которые слишком часто пытаются объяснить это, предполагают, что они уже знакомы с другими VCS [системами контроля версий] и слишком глубоко копаются, и совершать другие преступления, такие как использование взаимозаменяемых терминов для "проверки" - способами, которые иногда кажутся почти рассчитанными, чтобы запутать новичка.

Чтобы избавить себя от стресса, вы должны прочитать книгу по Git - я бы порекомендовал "Контроль версий с Git". И если вы можете доверять мне (или, скорее, моим шрамам), когда я говорю "должен", из этого следует, что вы можете сделать это СЕЙЧАС. Большая часть сложности Git происходит от ветвления и последующего повторного использования. Но из твоего вопроса нет причин, почему люди должны ослеплять тебя наукой.

Особенно, если, например, это отчаянная ситуация, и вы новичок в Git!

PS: Еще одна мысль: (сейчас) на самом деле довольно просто хранить Git-репозиторий ("repo") в каталоге, отличном от каталога с рабочими файлами. Это означает, что вам не нужно будет копировать весь репозиторий Git, используя вышеуказанное быстрое и грязное решение. Смотрите ответ Фрайера, используя --separate-git-dir здесь. Тем не менее, будьте осторожны: если у вас есть репозиторий "отдельный каталог", который вы не копируете, и вы выполняете полный сброс, все версии, следующие за фиксацией сброса, будут потеряны навсегда, если только у вас нет, как вам абсолютно необходимо, регулярно создавайте резервные копии вашего хранилища, желательно в облаке (например, Google Drive) среди других мест.

11

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

У меня была аналогичная проблема, и я хотел вернуться к предыдущему Commit. В моем случае я не был настроен на то, чтобы сохранить новую фиксацию, поэтому я использовал Hard.

Вот как я это сделал:

git reset --hard CommitId && git clean -f

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

git push -f
11

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

Сначала вам нужно удалить развитие из источника:

git push origin :develop (note the colon)

Затем вам нужно получить статус, который вы хотите, позвольте мне предположить, что хеш фиксации EFGHIJK:

git reset --hard EFGHIJK

Наконец, нажмите снова развернуть:

git push origin develop
10

На GitKraken вы можете сделать это:

  1. Щелкните правой кнопкой мыши фиксацию, которую вы хотите сбросить, выберите: Сбросить на это commit/Hard:

Изображение 7445

  1. Щелкните правой кнопкой мыши на фиксации еще раз, выберите: Current name name/Push:

Изображение 7446

  1. Нажмите на Force Push:

Изображение 7447

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

10

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

9

Откат (или возврат):

  • git revert --no-commit "commit-code-to-remove" HEAD (например, git revert --no-commit d57a39d HEAD)
  • git commit
  • git нажмите

Попробуйте выполнить два шага, и если вы обнаружите, что это то, что вам нужно, тогда git нажмите.

Если вы обнаружили что-то не так:

git revert --abort

8

SourceTree можно сделать намного проще. Щелкните правой кнопкой мыши фиксацию, которую вы ищете, и выберите "Checkout" из меню.

Изображение 7448

8

Во-первых, получите строку, которая идентифицирует фиксацию в какой-то день, делая:

git rev-list -n 1 --before="2009-07-27 13:37" origin/master

он печатает идентификатор фиксации, берет строку (например, XXXX) и делает:

git checkout XXXX
8

Еще одно простейшее решение; вам нужно изменить ветвь, чтобы сделать это, но потом вы можете просто запустить:

git branch -f <<branchname>> 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
  • 4
    О, чувак, почему у вопроса ОП есть так много разных ответов !? Не должен ли отступить быть простым процессом?
  • 0
    Спасибо! Этот метод работает на голом репо (для «git reset» требуется рабочий каталог, поэтому большинство ответов здесь не сработало).
7
git reflog

Выберите номер HEAD (s) из git reflog, в который вы хотите вернуться и выполните (для этого примера я выбираю 12):

git reset HEAD@{12} --hard
7

Я почему-то не смог отменить мой вручную, поэтому вот как я это сделал.

  • Проверено отделение, которое я хотел иметь, скопировал его.
  • Выбрано последнее отделение.
  • Скопировал содержимое из ветки, в котором я хотел, чтобы последний каталог веток переписывал изменения и фиксировал это.
6

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

  1. выйдите из фиксации или ответките свое желание вернуться.
  2. Измените.git/HEAD и измените ref на ветку, на которую вы вернетесь.

Такие как:

echo 'ref: refs/heads/example' > .git/HEAD

Если вы затем выполняете статус git, вы должны увидеть все изменения между филиалом, в котором вы находитесь, и тем, к которому хотите вернуться.

Если все выглядит хорошо, вы можете совершить. Вы также можете использовать git diff revert..example, чтобы убедиться, что он тот же.

5

Если вы хотите временно вернуть изменения, потому что

  • кто-то совершил код, нарушающий сборку или нарушение функциональности, над которой вы работаете.

Вы можете выполнить поиск последней рабочей фиксации с использованием журнала git, а затем запустить

git rebase --onto <commitId>

Когда удаленная ветка снова работает, вы можете

git pull --rebase

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

1

Сброс поэтапных изменений и изменений

Команда git reset позволяет вам изменить HEAD- последний коммит, на который указывает ваше рабочее дерево вашего репозитория. Он изменяет либо область подготовки, либо область подготовки и рабочее дерево. Способность Git создавать коммиты в точности так, как вы хотите, означает, что вам иногда нужно отменить изменения, внесенные вами с помощью git add. Вы можете сделать это, вызвав git reset HEAD <file to change>. У вас есть два варианта, чтобы полностью избавиться от изменений. git checkout HEAD <file(s) or path(s)> - это быстрый способ отменить изменения в вашей промежуточной области и рабочем дереве. Будьте осторожны с этой командой, потому что она удаляет все изменения в вашем рабочем дереве. Git не знает об этих изменениях, так как они никогда не совершались. Невозможно вернуть эти изменения после запуска этой команды. Другая команда в вашем распоряжении - это git reset --hard. Это в равной степени разрушительно для вашего рабочего дерева - любые незафиксированные изменения или поэтапные изменения теряются после его запуска. Запуск git reset -hard HEAD делает то же самое, что и git checkout HEAD. он просто не требует файла или пути для работы. Вы можете использовать --soft с git reset. Он сбрасывает репозиторий в указанный вами коммит и выполняет все эти изменения. На любые изменения, которые вы уже подготовили, это не влияет, равно как и изменения в вашем рабочем дереве. Наконец, вы можете использовать --mixed для сброса рабочего дерева без внесения каких-либо изменений. Это также не выполняет этапные изменения.

Возврат Коммитов

Иногда мы делаем ошибки. Коммит, который не должен был использоваться совместно, помещается в общедоступный репозиторий, в коммите есть ошибка, которую нельзя исправить, и которую необходимо отменить, или, может быть, вам больше не нужен этот код. git revert. Команда git revert делает то, что вы могли ожидать. Он отменяет один коммит, применяя обратный коммит к истории. Иногда вам нужно отменить несколько коммитов, чтобы полностью отменить изменение. Вы можете использовать -no-commit или -n чтобы сказать Git, что нужно выполнить возврат, но не останавливать -n изменения. Это позволяет объединить все возвратные коммиты в один коммит, что полезно, если вам нужно отменить функцию, охватывающую несколько коммитов. Убедитесь, что вы возвращаете коммиты в обратном порядке - сначала самый новый коммит. В противном случае вы можете запутать Git, пытаясь вернуть код, который еще не существует.

-2

В визуальной студии это довольно легко, проверяя исходное дерево. Просто:

Нажмите "Командный проводник" → "Ветви" → разверните (выберите желаемый филиал) → щелкните правой кнопкой мыши и выберите "Просмотр истории" → Выберите фиксацию, которую вы хотите вернуть раньше → щелкните правой кнопкой мыши и нажмите "Восстановить",

это один из моих снимков ниже, как скриншот. Если после возврата требуется конфликт, вы должны разрешить конфликты и затем зафиксировать.

Изображение 7449

Ещё вопросы

Сообщество Overcoder
Наверх
Меню