持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
撤销本地提交
如果你发现刚刚的操作一不小心commit了,所幸你还没有推送到远程仓库,你可以用reset命令来撤消你的这次提交。
reset命令的作用:重置HEAD(当前分支的版本顶端)到另外一个commit。
我们来创建一个文件,并附带提交信息[+]骂了我的boss,达到下图的效果
我们使用以下命令达到这样的效果:
- 创建to_boss.txt文件,并向其写入了
my boss is a bad guy! git add然后status查看新文件已经加入跟踪git commit提交了这次的修改
撤消了本次提交
好了,刚刚我们“不小心”diss了我们的老板,要是被发现就完了,所幸还没有push,要快点撤消这些提交,再拍下马屁才行。
先撤销掉现在的提交达到下图的效果
我们使用以下命令达到这样的效果:
git reset --soft head^撤消了本次提交,将工作区恢复到了提交前但是已经add的状态- 将
to_boss.txt的内容改成了my boss is a good boy!
好了,我们现在改成怕马屁的话了,虽然我并不赞成大家给老板拍马屁,但是刚刚骂老板的话实在把人吓得不轻。我们赶快把他提交掉吧,一会老板看见估计要给我加工资了。
修改to_boss.txt的内容,同时创建一个提交信息为[+]夸了我的boss的提交,如下图
我们使用以下命令达到这样的效果:
add然后commit提交
好了,有惊无险,这就是撤消commit的操作。
我们的撤消当前提交的时候往往不希望我们此次提交的代码发生任何丢失,只是撤消掉commit的操作,以便我们继续修改文件。
正常我们想达到上图的效果,宝贵的代码放回到暂存区,如果我们是想直接不要了这次commit的全部内容的任何修改那就把git reset --soft head^改成git reset --hard head^,这样你本地修改就彻底丢掉了(一定要小心啊,不然代码白写了),如果真用了想找回来怎么办?我们后面【救命的后悔药】一节会和大家详细讨论。
当然了,你只要开心,不加soft或hard参数也是安全的(相当于使用了--mixed参数),只不过是撤消以后你的本次修改就会回到add之前的状态,你可以重新检查以后再做修改和commit也可以。
撤销远程提交
撤销远程提交
让我们冷静下来,用 撤消当前commit的方法 先撤消本地的commit,这次我们来试试用hard参数来撤消(不确定用hard 还是 soft,可以到上一篇推送中再做确认-> 撤消当前commit的方法 )
使用git reset --hard head^回滚到上一个commit
- 使用
git status查看现在的工作区情况,提示Your branch is behind 'origin/master' by 1 commit,代表成功表了上一次的提示状态 nothing to commit, working tree clean代表这次的修改全没了,清理的算是一个彻底。如果还想找回来怎么办,我们还真是有办法让你找回来的,以后的推送救命的后悔药会详细讲述。
这个时候我们的状态是:
这个时候我们再把他强制推送到远程:
git push origin master --force命令强制提交到远程仓库(注意,如果是在团队合作的情况下,不到迫不得已不要给命令加--force参数)- 让我们看看
github
真的撤消了远程仓库,长舒一口气。
就是这么简单!
撤销暂存文件与任意切换文件版本
有时候我们想把暂存区的文件取出来。
一、暂存区到工作区
假如我们刚刚执行了git reset --soft或者add等的操作,把一些东西加到了我们的暂存区,比如日志文件,我们就要把他们从暂存区拿出来。
git status查看暂存区,里面有一个mysql.log被放进去了git reset -- mysql.log把mysql.log取出来git status可以看到真的取出来了 然后如果不要想这个文件的话再rm掉就好啦,但是如果这些文件每次自动生成都要用这种方式取出暂存区真的好累,我们可以用 git忽略不想提交的文件(后续技巧篇详细描述)
二、回滚文件到某个提交
当我们想要把某个文件任意的回滚到某次提交上,而不改变其他文件的状态我们要怎么做呢? 我们有两种情况,一种是,只是想在工作区有修改的文件,直接丢弃掉他现在的修改;第二种是想把这个文件回滚到以前的某一次提交。我们先来说第一种
1. 取消文件在工作区的修改
- 更新
time.txt的内容,可以status看到他发生了变化 git checkout -- time.txt, 取消这次在工作区的修改,如果他已经被add加到了暂存区,那么这个命令就没有用了,他的意思是取消本次在工作区的修改,去上一次保存的地方。如果没有add就回到和版本库一样的状态;如果已经加到了暂存区,又做了修改,那么就回加到暂存区后的状态
2. 将文件回滚到任意的版本
我们这里说的把文件回滚到以前的某个版本的状态,完整的含义是保持其他文件的内容不变,改变这个文件到以前的某个版本,然后修改到自己满意的样子和做下一次的提交。
核心命令
git checkout [<options>] [<branch>] -- <file>...
我们还是用time.txt这个文件来做试验,先搞三个版本出来,在这里我已经搞好了,来看看:
版本1,time.txt内容00:50
版本2,time.txt内容18:51
版本3,time.txt内容10:41
现在的是版本1,我们把版本3检出试试。达到下图的状态
- 使用
checkout+commit id+-- filename的组合,横跨版本2把历史版本3的time.txt搞出来了 - 查看状态,time.txt被改变了
我们来把time.txt恢复到版本1,同样的方法,因为版本1是上一次提交我们可以省略掉版本号
看到了吧!只要用git checkout commit_id -- filename的组合,想搞出哪个文件历史版本就搞出哪个。
到了这里,你可能会很懵比,reset和checkout命令真的好像啊!都可以用来做撤消
checkout语义上是把什么东西取出来,所以此命令用于从历史提交(或者暂存区域)中拷贝文件到工作目录,也可用于切换分支。reset语义上是重新设置,所以此命令把当前分支指向另一个位置,并且有选择的变动工作目录和索引。也用来在从历史仓库中复制文件到索引,而不动工作目录。
找回弄丢的代码
- 提交过的就用命令
git reflog来查询提交记录找回
恢复忘记提交的记录
-
未提交但是git add过的就用git fsck --lost-found来生成丢失文件记录来找回。
-
没找回成功就用用
find .git/objects -type f | xargs ls -lt | sed 3q这个命令来输出近期修改的文件找回。