Git撤销本地修改
Posted by 付辉 on Tuesday, August 7, 2018 共1609字
懂得了好多大道理,但还是过不好这一生!
用了git就会发现,再也不想用svn了。
Note
:在执行push
操作前,所有的修改都发生在本地,可以使用reset
随便回滚本地的提交。但要注意:本地修改一旦回滚,无法找回。在push
后,想要回滚到指定的版本,便需要使用revert
,这样的代价就是:你的回滚记录被记录在了log
中,所有人都可以看见。
使用reset
回退
本质上是commit
操作的回退。Git
工作流可以简化为三个部分:Working Directory
、index
、HEAD
。后两部分对应的git
命令便是add
和commit
。如果使用的是Sourcetree
工具,那么这三部分就更直观了。
该命令的具体功能是移动HEAD
,即移动分支的指针。将当前的HEAD
重新指向之前的版本,本地工作环境也会跟着切换。适用场景:本地已经commit
,但尚未push
到远端仓库的回滚操作。
该命令提供了三个属性:分别是soft
、mixed
、和hard
。
soft
撤销上一次的commit
命令,返回到HEAD
前的index
状态。mixed
撤销了上一次的git add
和git commit
命令,将index
的修改回滚到Working Directory
。hard
撤销了最后git add
和git commit
命令以及工作目录中的所有修改。
所以reset
重写的顺序如下:
- 移动 HEAD 指向的分支(如果是
soft
,则到此停止)。 - 使索引看起来像 HEAD(如果是
mixed
,则到此停止)。 - 使工作目录看起来像索引。
Example
当执行pull命令发生冲突时时,本地代码需要做merge操作。但本地代码只是临时调试修改,并不需要保存提交。执行如下命令,便会清空本地的修改,hard相当于一个版本的指针,origin/master可以替换为具体的版本号
git reset --hard origin/master
git reset --hard version-number
git reset --hard HEAD
获取版本号可以通过git log
直接查看。
checkout
stash
储藏
将工作区的修改进行存储,使本地重新成为一个干净的环境,同时方便在之后应用这些改动。可以用于存储已被索引的文件、或者未跟踪的文件。执行git stash -a
来暂存所有改动的文件。常见的包括如下命令:
git stash
储藏修改git stash list
查看储藏的列表- 将储藏重新应用到当前分支:
git statsh apply stash@{1}
或者git stash pop stash@{1}
。后者会在应用暂存之后从堆栈上删除 git stash drop stash@{1}
移除暂存git stash clear
清除本地所有的贮藏历史
使用clean
清空
用于从==工作区==移除==未被追踪的文件==,执行git clean -d -f
来移除所有未被追踪的文件或目录。
git clean -d -n
可以用来做一次删除前的演示git clean -d -i
用于交互式的删除文件
使用revert
我们工作区看到的内容,是所有版本修改合并的结果。如果觉得某个版本的提交有问题,使用revert
便可以直接撤销这个版本的修改。本质上通过提交新的版本来撤销修改。
--> (modify version 1) --> (modify version 2) --> (modify version3)
执行git revert 版本号
仅仅是撤销这个版本的修改。如果你想将版本回滚到version 1
,你需要执行2次revert
操作。且每次执行revert
都会有一个新的版本生成。
Revert a merge
回滚merge
提交跟普通的提交是有区别的。我们一般都是在分支上开发,然后将修改合并到主分支上。所以merge
的那个提交版本,存在两个parent
分支。
所以,执行git revert MERGE_HASH
是不能正常工作的。原因在于这个提交存在多个parent
,它需要有额外的信息来决定哪一个分支作为回滚的主线。参数-m
就是用来干这个的。
git revert 0cce3a0837da60fb8ef458d98f81feaa97397363
error: Commit 603c1333339bc9b5ad4d8b864e948d4bd950bf05 is a merge but no -m option was given.
fatal: 还原失败
Revert vs Reset
reset
是在正常的commit
历史中,删除了指定的commit
,这时HEAD
是向后移动了,而revert
是在正常的commit
历史中再commit
一次,只不过是反向提交,他的HEAD
是一直向前的.git revert
是用一次新的commit
来回滚之前的commit
,git reset
是直接删除指定的commit
Revert the revert
听着这个标题,就感觉很有意思!
参考文档: