Вопрос: Как вернуть репозиторий Git в предыдущую фиксацию?


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

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

$ git log
commit a867b4af366350be2e7c21b8de9cc6504678a61b`
Author: Me <me@me.com>
Date:   Thu Nov 4 18:59:41 2010 -0400

blah blah blah...

commit 25eee4caef46ae64aa08e8ab3f988bc917ee1ce4
Author: Me <me@me.com>
Date:   Thu Nov 4 05:13:39 2010 -0400

more blah blah blah...

commit 0766c053c0ea2035e90f504928f8df3c9363b8bd
Author: Me <me@me.com>
Date:   Thu Nov 4 00:55:06 2010 -0400

And yet more blah blah...

commit 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Author: Me <me@me.com>
Date:   Wed Nov 3 23:56:08 2010 -0400

Yep, more blah blah.

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


5876


источник


Ответы:


Это сильно зависит от того, что вы подразумеваете под «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's 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страница руководства фактически покрывает много этого в его описании. Еще одна полезная ссылка - этот раздел git-scm.com обсуждает git-revert ,

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

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


7670



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

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

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? ,


1230



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

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

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

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

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


1186



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

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

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


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

Кроме того, из комментариев, если вы хотите использовать менее «простой» метод, вы можете использовать

git clean -i


148



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

git add . && git checkout master -f

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

  • Он не будет создавать никаких коммитов в качестве git revertделает.
  • Он НЕ будет отсоединять ваш HEAD, как git checkout <commithashcode>делает.
  • Он будет отменять все ваши локальные изменения и УДАЛИТЬ все добавленные файлы с момента последнего фиксации в ветке.
  • Он работает только с именами филиалов, поэтому вы можете вернуться только к последнему фиксации в ветке таким образом.

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

git add . && git reset --hard HEAD

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

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


95



If you want to "uncommit", erase the last commit message, and put the modified files back in staging, you would use the command:

git reset --soft HEAD~1
  • --soft indicates that the uncommitted files should be retained as working files opposed to --hard which would discard them.
  • HEAD~1 is the last commit. If you want to rollback 3 commits you could use HEAD~3. If you want to rollback to a specific revision number, you could also do that using its SHA hash.

This is an extremely useful command in situations where you committed the wrong thing and you want to undo that last commit.

Source: http://nakkaya.com/2009/09/24/git-delete-last-commit/


94



Before answering lets add some background, explaining what is this HEAD.

First of all what is HEAD?

HEAD is simply a reference to the current commit (latest) on the current branch.
There can only be a single HEAD at any given time. (excluding git worktree)

The content of HEAD is stored inside .git/HEAD and it contains the 40 bytes SHA-1 of the current commit.


detached HEAD

If you are not on the latest commit - meaning that HEAD is pointing to a prior commit in history its called detached HEAD.

enter image description here

On the command line it will look like this- SHA-1 instead of the branch name since the HEAD is not pointing to the the tip of the current branch

enter image description here


A few options on how to recover from a detached HEAD:


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

This will checkout new branch pointing to the desired commit.
This command will checkout to a given commit.
At this point you can create a branch and start to work from this point on.

# 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

You can always use the reflog as well.
git reflog will display any change which updated the HEAD and checking out the desired reflog entry will set the HEAD back to this commit.

Every time the HEAD is modified there will be a new entry in the reflog

git reflog
git checkout HEAD@{...}

This will get you back to your desired commit

enter image description here


git reset HEAD --hard <commit_id>

"Move" your head back to the desired commit.

# 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's 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.
  • Note: (Since Git 2.7)
    you can also use the git rebase --no-autostash as well.

This schema illustrate which command does what.
As you can see there reset && checkout modify the HEAD.

enter image description here


90



You can do this by the following two commands:

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

It will remove your previous Git commit.

If you want to keep your changes, you can also use:

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

Then it will save your changes.


73



Say you have the following commits in a text file named ~/commits-to-revert.txt (I used git log --pretty=oneline to get them)

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

Create a Bash shell script to revert each of them:

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

This reverts everything back to the previous state, including file and directory creations, and deletions, commit it to your branch and you retain the history, but you have it reverted back to the same file structure. Why Git doesn't have a git revert --to <hash> is beyond me.


51