Git后悔药大全吐血整理 建议收藏
先上个完整的思维导图,你也可以先点个赞😊
一、撤销文件修改
- 撤销单个文件的修改
git reset HEAD XXX.js
- 撤销所有未提交的修改
git reset --hard
因为此时的代码还没有提交到仓库,所以这种撤销是不可恢复的,请谨慎操作。撤销之后代码版本将会回回退到最近一次拉取/提交的状态。
二、暂存区添加撤销
1. 暂存区添加
- 首先查看项目文件状态(有哪些没有被添加到暂存区的文件 Untracked files)
- Changes to be committed 新创建未提交的文件(暂存区中)
- Changes not staged for commit 已修改未提交的文件(暂存区中)
- Untracked files 未添加到暂存区的文件(不在暂存区中)
git status
上一步的结果中 Untracked files
对应的就是没有被添加到暂存区的文件,直接使用 git add + <Untracked files中的文件路径> 即可添加到暂存区(添加到暂存区的文件才会在 commit 时参与提交),举个栗子:
git add leetcode/977.js
2. 暂存区移除
- 第一步还是
git status
查看暂存区状态,在Changes to be committed
中找到对应你要从暂存区删除的文件列表 - 第二步通过
git reset HEAD <要移除的文件路径>
命令将无需提交的文件从暂存区移除
git reset HEAD <要移除的文件路径>
- 第三步 本来移除到这里就结束了,这里建议再使用
git status
检查下删除结果
三、编辑最近一次提交
高能警告,以下操作可以支持三种维度的commit修改
- 重新编辑 commit message
- 添加漏提交的文件
- 修改已提交的文件内容
其实这三个问题使用一个命令就能搞定,方便理解,所以就不分开写了。至于怎么提交,各位看官有不会的吗?…… 很好大家都会,那我们就从提交完成开始讲起
1. 提交完成,先查看提交状态
git status
如果你突然发现 Untracked files
中存在你漏提交的文件,以截图中勾出来的test.vue
文件为例
2. 发现漏提交的文件,添加到缓存区
git add src/components/fileEdit/test.vue
根据
Unix
设计哲学,没有消息就是最好的消息。添加成功你不会有任何提示。
当然,如果你只想要修改 commit message
,那就忽略第二条。
3. 存在要修改的文件,添加到缓存区
注意,当你之前的提交已经包含如 index.vue
文件,你在提交之后发现你提交有误,但是要又不想重新来一次commit,这时需要将你修改的文件手动加到缓存区。很简单,只需以下三步:
- 修改完文件
- git status 查看改动文件
- git add <上一步查看到的文件名对应路径>
注意,index.vue
文件是你已经提交过的文件,但是要想合并到上一次 commit 中也需要 git add 添加一次。因为git add
添加的是具体的文件改动内容,而不是文件名。
4. 撤销
amend 是修正的意思。
当在 commit 命令后边加上 --amend
命令,Git 不会在当前 commit 上增加一条 commit 记录,而是会把当前 commit 里的内容和暂存区(stageing area)里的内容合并起来后创建一个新的 commit,用这个新的 commit 把当前 commit 替换掉。所以撤销后,你在 git 提交历史中只会看到一条 commit 记录,之前的那一条被覆盖了。
git commit --amend
输入以上命令你应该是进入了如下界面图所示的界面,根据操作系统的不同它可能是 nano 或者 vi,这里介绍一下它的最基本用法。
- 默认进入是在命令模式,按一次小写
i
,进入编辑模式 - 输入完成,按一次ESC回到命令模式
- 输入两次大写
Z
(支持组合键)即可保存退出
了解了以上用法,要想修改 commit message
信息就简单,先按一次小写 i
,配合键盘上下左右按键修改完message信息后按一次 ESC
,然后再按两次大写 Z
,大功告成。
看图,提交信息已经变了
再看看提交记录,有彩蛋哦
现在已经是是下午四点多了,用git commit --amend
修改过的commit记录在提交历史中显示的时间还是你首次提交的时间。也就是说你可以偷偷的把提交过的文件修正,而git提交记录中只显示一条。
四、编辑任意一次提交
发现某一次提交的代码有问题,想修改回退?
回顾一下刚刚学会的第三条,你已经已经学会了直接修改上一条提交有误的commit,所以我们只需要考虑你要修改或回退的提交不是最新提交的情况。
其实学会了git commit --amend
,这一次的操作也很简单。我们只需要把要修改的焦点移动到你要修改的那次commit即可,这里就要用到 rebase -i
命令(i是 interactive 的缩写,意为交互式,rebase -i 可以理解为交互式变基)。
交互式变基?是不是有点蒙圈?举个最简单的例子,你在电脑上写文章时光标一直指向的是最后一个字符,你可以直接按
back
键实现删除;但是你发现之前的字有误又不想把最后写的几个字全部删掉怎么办?当然是将光标移动到错误字符处,你可以认为交互式变基和移动光标的操作差不多。 不过这里的焦点不是指HEAD
再来张动图理解一下。
继续说rebase -i
这个命令,如果发现倒数第三次commit有误,也就是说当前光标要向前移动两次在考虑编辑修改,这里需要了解一下Git支持的两种偏移符号
- ^ 一个
^
代表往回偏移一次。- 偏移三次对应commit语法应该是
git rebase -i HEAD^^^
- 偏移三次对应commit语法应该是
- ~ ~加一个数字n代表偏移往回偏移n次。
- 偏移三次对应commit语法应该是
git rebase -i HEAD~3
- 偏移三次对应commit语法应该是
接下来的操作和第三条的流程一样了,我大概罗列一下
- 修改文件
- 添加文件
git add <修改了要提交的文件>
git commit --amend
等等,还有最后一步,把你的光标
移到最后,依旧是 rebase 语法。
git rebase --continue
到这要恭喜你,这次交互式 rebase 的过程就完美结束了。
rebase 的中文解释是变基/重定基底,在你理解了以上流程后你会发现这个解释还是比较准确的,可以留意品味一下。
五、回退某一次提交
首先要变基到你想撤销的那一次提交。(刚已经讲过rebase具体用法,没看明白的可以再看一遍)
git rebase -i HEAD~2
回退的原理其实就是生成一个新的提交,把之前提交的内容抵消掉。
git revert HEAD^
如果你本地存在没提交的文件你可能会遇到如下警告阻止你回退。你可以先提交或将这些修改暂存到某处再回退来解决。
error: your local changes would be overwritten by revert.
hint: commit your changes or stash them to proceed.
完成后你会发现本地仓库多了一次commit,这时直接push到对应的远程仓库即可。
六、撤销分支删除
有的 task 或 bug 分支,用完就删是个好习惯,但是一不小心把一个有用的分支删除了怎么办?
这里介绍一下 reflog
命令,全称 reference log
,它可以查看 Git 仓库中的引用的移动记录。如果不指定引用,它会显示 HEAD 的移动记录,(关于HEAD和引用的深入介绍之后应该会单独写一篇讲解)。
我在本地建了一个 dev-reflog
且 push 到了远程仓库,然后使用如下命令删除了这个分支(注意我用的 -D 是强制删除,实际项目中请慎用)。
git branch -D dev-reflog
好了,到这里 dev-reflog
分支就被删除了,要想恢复首先通过 git reflog
查看操作记录。
git reflog
上图中是倒数第二条我框出来的就是被删掉的 dev-reflog
分支对应的引用code,接下来就可以进行找回操作了
git checkout 715b2cb
git checkout -b dev-reflog
因为Git的回收机制,一定时间被删除的分支会被Git彻底回收导致无法找回,所以使用
reflog
一定要及时。
七、无法找回的情景
大多数情况下git操作都是有迹可循可回退的,但也有三种特殊情况是无法恢复的。
1. 本地文件reset
本地文件reset后因为没有提交,在git中还没有留下记录所以是无法找回的。(当然ctrl/command+z
这种非git操作不在我们的讨论范畴)
2. amend 修改后的文件
amend
命令修改文件实际是用当前文件修改覆盖之前的 commit 提交,因为是覆盖所以在git历史中只会存在最新一次的commit记录,所以 amend
修改前的状态是不可回退的。
3. 被 Git 回收的分支
在删除一个分之后,git 会自动回收长时间被删除的分支。
感谢
转载自:https://juejin.cn/post/6948338652845965348