Undo add

$ edit
$ git add frotz.c filfre.c
$ mailx
$ git reset
$ git pull git://info.example.com/ nitfol

我正在开心地写代码,现在写的这俩文件没什么问题,待会 git diff 的时候我就不需要再看到它俩了,所以我就把它俩加到暂存区去了。这时候,有人让我 pull 一份代码,这代码确实不错。但是问题是,我现在暂存区已经更新了俩文件,我也知道要 pull 的这份代码不会和暂存的这俩文件冲突。所以我把暂存区的修改回退到了工作区。然后我执行 fetch, merge,这一切完成之后的frotz.cfilfre.c还毫发无损地躺在工作区里。

Undo a commit and redo

$ git commit ...
$ git reset --soft HEAD^
$ edit
$ git commit -a -c ORIG_HEAD

我提交了之后,发现工作区还没改完。那我先把这次的提交撤回来好了,reset --soft会帮我把这次的提交放到 ORIG_HEAD 里面,所以我待会还能找得着它。然后我去工作区编辑一下,因为我也用不着去改提交信息了,所以就不用-m了,直接用-c提交。

Undo a commit, making it a topic branch

$ git branch topic/WIP
$ git reset --hard HEAD~3
$ git checkout topic/WIP

正在 master 分支工作,我做了 3 次提交,但是发现这些提交放到 master 分支还是不够成熟,目前来说还是先搬到 topic/WIP 分支去好了。所以我先把 master 整体迁移到之前的环境,回到 topic/WIP 继续工作。

Undo commits permantly

$ git commit ...
$ git reset --hard HEAD~3

这次的场景就是上一次的缩减版。这一次彻底地把之前三个提交撤销了。当然也不是说就彻底找不到了,我们知道 git 里面,所有提交过的内容几乎就没有能丢的掉了(git reflog)。但是呢,千万不要把一个已经推到远程,别人会基于此提交做开发的提交撤销了。具体的问题可以在git rebase这一节看从上游变基中恢复数据

Undo a merge or pull

$ git pull
Auto-merging nitfol
CONFLICT (content): Merge conflict in nitfol
Automatic merge failed; fix conflicts and then commit the result.

$ git reset --hard
$ git pull . topic/branch
Updating from 41223... to 13134...
Fast-foward
$ git reset --hard ORIGIN_HEAD

我想把远程仓库合并进来,但是有冲突。但是目前我还不想去研究解决冲突的事儿,我先接着做本地的开发。我把工作区和暂存区都清理了一下,把 topic branch 合并进来。但是我又后悔了(我还真是事儿多啊),我觉着这个 topic 分支啊还不够好,我得把它弄出去先。每次 "pull" 和 "merge" 操作的时候都会把当前这个提交留在 ORIG_HEAD 里面。回到之前的状态呢,就是reset --hard

Undo a merge or pull inside a dirty working tree

$ git pull
Auto-merging nitfol
Merge made by recursive.
 nitfol                |   20 +++++----
 ...

 $ git reset --merge ORIG_HEAD

我在工作区干着活呢,突然脑子一抽,去 Pull 一下远程代码,为啥我这么自信干这种蠢事?因为我知道我搭档的提交跟我的没冲突。但是我看了看这个合并的结果啊,很不满意。这时候我要是用 git reset --hard ORIG_HEAD呢,我工作区的东西就没了。用git reset --merge ORIG_HEAD 的话,工作区的成果就留下了。

Interrupted workflow

$ git checkout feature
$ work work work
$ git commit -a -m "snapshot WIP"
$ git checkout master
$ fix fix fix
$ git commit ;# commit with real log
$ git checkout feature
$ git reset --soft HEAD^;# go back to WIP state
$ git reset

我正在做一次大改呢,正干一半呢,突然有个紧急的 bug。于是我赶紧随手写了个 msg,这没事,反正待会回来还要改的。然后我切回 master 搞定了 bug,再切回之前的分支。现在要干的呢就是先把之前那个提交给撤了,把暂存区也给撤了,然后在工作区继续愉快地写 feature。

实际上,最后一步把 HEAD 和 index 都撤销只要git reset HEAD^就够了。另外,这个例子做的事儿实际上就是git stash

把暂存区的文件撤回到工作区

$ git reset --frotz.c
$ git commit -m "Commit files in index"
$ work work work on frotz.c
$ git add frotz.c

这回我往暂存区里加了个文件,但是过了一会我觉得还是得再打磨打磨。于是先把它拿出来,把其它的都提交了。然后单独把这个文件拿出来修改,改好了之后再提交。

#

$ git tag start
$ git checkout -b branch1
$ edit
$ git commit ...
$ edit
$ git checkout -b branch2
$ git reset --keep start

我新开了一个分支 branch1,然后在上面写了点代码提交了,然后接着写别的部分。但是我发现现在写的这些东西貌似很复杂,最好是得再开个分支来写。这时候呢,我新开了一个分支 branch2 然后切过去。现在我只想回到最初的样子,还好开始我打了个标签,现在只要回到标签的位置就行了。

资料

progit-blog-重置揭秘,可能是最基础、简洁的介绍,和 checkout 做了一些对比。

results matching ""

    No results matching ""