git - 返回到上一个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.

如何恢复到 November 3,的提交,换句话说,提交 0d1d7fc

时间:

这取决于"还原"的含义。

临时 switch 到另一个提交

如果你想暂时回到它,fool,然后回到你的位置,你需要做的就是检查所需的提交:


# 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,复原有一个非常特殊的含义: 创建带有反向补丁的提交以取消它。 这样你就不会重写任何历史。


# 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

# 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

正在将工作副本还原到最近的提交

要恢复到以前的提交,忽略任何更改:


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 hash的提交? 。

这里有很多复杂和危险的答案,但实际上很简单:


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

这将恢复从返回提交哈希,这意味着它将重现,提交国家工作树中的好像以来每次提交已经走了回来。 然后,你就可以提交当前的树,它将创建一个全新的提交,它基本上相当于你要提交的提交。

( --no-commit 标志允许git恢复所有的提交once-否则你会提示每个提交的信息的范围,乱扔垃圾和不必要的历史新提交。)

这是一个的安全方法,可以回滚到以前的状态 。 没有被销毁的历史,所以它可以用于已经公开的提交。

我已经尝试了很多方法来恢复Git中的本地更改,如果你想恢复到最新的提交状态,这似乎是最好的。


git add. && git checkout master -f

简短描述:

  • 它不会像 git revert 那样创建任何提交。
  • 它不会像这样分离你的头 git checkout <commithashcode> 确实。
  • 它将覆盖所有本地更改,并删除自分支中最后一次提交之后添加的所有文件。
  • 它只适用于分支名称,因此你只能在分支中恢复最近的提交。

我找到了一个更加方便和简单的方法来实现上面的结果:


git add. && git reset --hard HEAD

指向当前分支的最新提交的位置。

boulder_ruby建议的代码代码相同,但我在前面添加了 git add.git reset --hard HEAD 删除自上次提交以来创建的所有新文件,这是大多数人在恢复到最新提交时期望的。

对于我和其他人来说,最好的选择是 git reset 选项:


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

这对我来说是最好的选择 ! 它简单快速有效 !

假设在一个名为 ~/commits-to-revert.txt的文本文件中有以下提交( 我使用 git log --pretty=oneline 获取它们)


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

创建一个 Bash shell脚本来恢复它们:


#!/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> 超越我了。

Jefromi解决方案的额外替代方案

Jefromi的解决方案绝对是最好的,你绝对应该使用它们。 然而,为了完整性,我也想给这些其他的替代方案,也可以用来恢复提交( 因为你创建一个新的提交,取消之前提交的变化,就像 git revert 做什么) 。

需要澄清的是,这些替代品不是最好的方法恢复提交, 解Jefromi,但我只是想指出,你还可以使用其他方法实现 git revert 一样。

可选 1: 硬复位和软复位

这是一个非常轻微修改版本的查尔斯·贝利恢复到提交的解决方案在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>"

这基本上是通过使用软重置将先前提交的状态在索引/staging-area,然后你可以提交。

替换 2: 删除当前树并替换为新的树

这个解决方案来自svick到签出的解决方案,并使它的成为一个新的提交:


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

其他 #1, 类似,它在当前工作副本中重现 <commit>的状态。 有必要先做 git rm 因为 git checkout 不会删除 <commit> 以来已经添加的文件。

有一个命令( 不是核心Git的一部分,但它位于 git-extras 软件包中) 专门用于恢复和执行旧提交:

 
git back

 

根据手册页,它也可以用于:


# Remove the latest three commits
git back 3

...