提交错了、文件删错了、合并冲突了,是每个用Git的人都会遇到的问题。先看状态,再选命令,不要慌着用会丢数据的命令。
动手前先看一下状态:
bash
git status
git log --oneline -5
一、撤销提交
先分清有没有推送,这是最关键的区别。
1. 还没有推送
git reset有三种模式:
- soft:只回退提交,改动留在暂存区。
-
- mixed:默认方式,取消暂存,改动留在工作区。
-
- hard:同时丢弃工作区和暂存区改动,风险最高,用前先备份。
常用命令如下,HEAD~1表示上一次提交:
- hard:同时丢弃工作区和暂存区改动,风险最高,用前先备份。
bash
git reset --soft HEAD~1
git reset --mixed HEAD~1
git reset --hard HEAD~1
只改最近一次提交信息,且没有推送时,可以用amend:
bash
git commit --amend -m 修正信息
2. 已经推送
已经推送的提交,优先用revert生成反向提交,历史保留,别人拉取也不会乱。
bash
git revert HEAD
git push
不要在公共分支上用reset加force覆盖历史。如果是只有自己用的分支,确认无人基于它开发后,也要先备份,并优先用force-with-lease代替force。
二、找回误删文件
先分清删除有没有提交。
1. 还没有提交的删除
文件只是从工作区删掉,直接从最近一次提交恢复:
bash
git restore app.js
git checkout -- app.js
2. 已经提交的删除
先用log找到文件最后一次存在的提交,再从那个提交恢复:
bash
git log --oneline -- app.js
git checkout <commit> -- app.js
git restore --source=<commit> app.js
3. reflog兜底
如果提交也被reset丢了,先看reflog,找到原来的提交号,再恢复。
bash
git reflog
git checkout <commit>
注意:从未被Git跟踪、从未提交过的文件,reflog也救不回来。
三、解决冲突
出现冲突先不要急着提交,先看哪些文件冲突了:
bash
git status
git diff
git diff --check
逐个打开冲突文件,删掉冲突标记,保留正确内容,不要把标记提交上去:
<<<<<<< HEAD
当前分支的内容
=======
对方分支的内容
>>>>>>> feature-branch
上半部分是当前分支,下半部分是对方分支,按实际需要保留一边或两边都要。
每解决一个文件,就用git add标记已解决:
bash
git add app.js
git status
全部冲突都解决后,再完成合并或变基:
bash
git commit
git rebase --continue
合并时用git commit,变基时用git rebase --continue。
如果不想继续合并,可以放弃合并:
bash
git merge --abort
放弃合并会丢弃已解决的结果,确认后再用。
小结
救急顺序是先看状态,再分清场景,优先选不丢数据的命令。