逆转与恢复   逆转与恢复:git reset
  项目跟踪工具的一个重要任务之一,就是使我们能够随时逆转(Undo)和恢复(Redo)某一阶段的工作。
  git reset 命令就是为这样的任务准备的。它将当前的工作分支的 头 定位到以前提交的任何版本中,它有三个重置的算法选项。
  命令形式:
  git reset [--mixed | --soft | --hard] [<commit-ish>]
  命令的选项:
  --mixed
  仅是重置索引的位置,而不改变你的工作树中的任何东西(即,文件中的所有变化都会被保留,也不标记他们为待提交状态),并且提示什么内容还没有被更新了。这个是默认的选项。
  --soft
  既不触动索引的位置,也不改变工作树中的任何内容,我们只是要求这些内容成为一份好的内容(之后才成为真正的提交内容)。这个选项使你可以将已经提交的东西重新逆转至“已更新但未提交(Updated but not Check in)”的状态。就像已经执行过 git update-index 命令,但是还没有执行 git commit 命令一样。
  --hard
  将工作树中的内容和头索引都切换至指定的版本位置中,也就是说自 <commit-ish> 之后的所有的跟踪内容和工作树中的内容都会全部丢失。因此,这个选项要慎用,除非你已经非常确定你的确不想再看到那些东西了。
  一个重要技巧--逆转提交与恢复

使用技巧

  可能有人会问,--soft 选项既不重置头索引的位置,也不改变工作树中的内容,那么它有什么用呢?现在我们介绍一个 --soft 选项的使用技巧。下面我们用例子来说明:
  $ git checkout master
  $ git checkout -b softreset
  $ git show-branch
  这里我们创建了一个 master 的拷贝分支 softreset,现在我们可以看到两个分支是在同一起跑线上的。
  ! [master] Merge branch 'robin'
  ! [robin] some work
  * [softreset] Merge branch 'robin'
  ---
  - - [master] Merge branch 'robin'
  + * [master^] Some fun
  ++* [robin] some work
  我们为 文件增加一些内容并提交。
  $ echo "Botch, botch, botch" >> hello
  $ git commit -a -m "some botch"
  $ git show-branch
  我们可以看到此时 softreset 比 master 推进了一个版本 "some botch" 。
  ! [master] Merge branch 'robin'
  ! [robin] some work
  * [softreset] some botch
  ---
  * [softreset] some botch
  - - [master] Merge branch 'robin'
  + * [master^] Some fun
  ++* [robin] some work
  现在让我们来考虑这样的一种情况,假如我们现在对刚刚提交的内容不满意,那么我们再编辑项目的内容,再提交的话,那么 "some botch" 的内容就会留在版本库中了。我们当然不希望将有明显问题的内容留在版本库中,这个时候 --soft 选项就很有用了。为了深入了解 --soft 的机制,我们看看现在 softreset 分支的头和 ORIG_HEAD 保存的索引。
  $ cat .git/refs/heads/softreset .git/ORIG_HEAD
  结果如下:
  5e7cf906233e052bdca8c598cad2cb5478f9540a
  7bbd1370e2c667d955b6f6652bf8274efdc1fbd3
  现在用 --soft 选项逆转刚才提交的内容:
  git reset --soft HEAD^
  现在让我们再看看 .git/ORIG_HEAD 的中保存了什么?
  $ cat .git/ORIG_HEAD
  结果如下:
  5e7cf906233e052bdca8c598cad2cb5478f9540a
  看!现在的 .git/ORIG_HEAD 等于逆转前的 .git/refs/heads/softreset 。也就是说,git reset --soft HEAD^ 命令逆转了刚才提交的版本进度,但是它将那次提交的对象的索引拷贝到了 .git/ORIG_HEAD 中。
  我们再编辑 hello 文件成为下面的内容:
  Hello World
  It's a new day for git
  Play, play, play
  Work, work, work
  Nice, nice, nice
  我们甚至可以比较一下现在的工作树中的内容和被取消了的那次提交的内容有什么差异:
  $ git diff ORIG_HEAD
  结果如下:
  diff --git a/hello b/hello
  index f978676..dd02c32 100644
  --- a/hello
  +++ b/hello
  @@ -2,4 +2,4 @@ Hello World
  It's a new day for git
  Play, play, play
  Work, work, work
  -Botch, botch, botch
  +Nice, nice, nice
  接着,我们可以恢复刚才被取消了的那次提交了。
  $ git commit -a -c ORIG_HEAD
  注意,这个命令会打开默认的 文本编辑器 以编辑原来提交的版本日志信息,我们改为 "nice work" 。大家可以自行用 git show-branch 命令来查看一下现在的分支状态。并且我们还可以不断地重复上述的步骤,一直修改到你对这个版本进度满意为止。
  git reset 命令还有很多的用途和技巧,请参考 git reset ,以及 Everyday GIT with 20 commands or So 。
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐