Git 不同阶段撤回
因为平时使用 SmartGit 这样一个 Git client,所以也没有太大注意 Git 中不同阶段撤回的方式,虽然平时接触过 git reset
的 --soft
和 --hard
来撤销已提交的 commit,但没有形成一个系统的知识体系。大家都知道 Git 是一个分布式版本控制,所以 Git 会有一个本地库,和一个远端库,而平时提交代码的时候,一般也都是先从本地工作区提交代码
git add .
git commit -s
git push
这几个步骤,虽然平淡无奇,但是展开说,就体现了 Git 的重要的环节,一段代码的提交顺序:
工作区 -> git add . -> 暂存区 -> git commit -> 本地仓库 -> git push -> 远程仓库
这里就要提到 Git 中的四个区:
- 工作区 working
- 暂存区 stage
- 本地仓库 local repository
- 远程仓库 remote repository
被追踪的文件,在未进入和进入上述四个区之后分别有一个状态,所以一共有五个状态:
- 未修改 origin
- 已修改 modified
- 已暂存 staged
- 已提交 committed
- 已推送 pushed
在了解这几个基本概念之后,如何检查本地的修改,以及如何查看不同状态之间的修改,这就要用到 git diff
命令。
直接使用 git diff
命令,能够查看已修改,未暂存的内容
使用 git diff --cache
来查看已暂存,未提交的内容
使用 git diff origin/master master
来查看已提交,未推送的差异。
工作区 暂存区 本地仓库 远程仓库
\ / \ / \ /
\ / \ / \ /
git diff git diff --cache git diff origin/master master
图解
在知道如何查看四个不同区之间的差异后,如何使用 git reset
来撤销呢?
撤销工作区修改
如果只是在编辑器中修改了文件的内容,还未使用 git add
将修改提交到暂存区,那么可以使用 git checkout .
或者 git checkout -- <file>
来丢弃本地全部修改或者丢弃某文件的修改。
可以将 git add .
和 git checkout .
看做一对反义词,修改完成后,如果想 Git 往前进一步,让修改进入暂存区,执行 git add .
如果向后退则执行 git checkout .
撤销暂存区修改
如果已经执行了 git add
,意味着暂存区中已经有了修改,但是需要丢弃暂存区的修改,那么可以执行 git reset
对于已经被 Git 追踪的文件,可以使用
git reset <file>
来单独将文件从暂存区中丢弃,将修改放到工作区。
对于从来没有被 Git 追踪过,是 new file 的文件,则需要使用:
git reset HEAD <file>
来将新文件从暂存区中取出放到工作区。
如果确定暂存区中的修改完全不需要,则可以使用
git reset --hard
直接将修改抛弃,谨慎使用 –hard 命令, 暂存区中所有修改都会被丢弃。修改内容也不会被重新放到工作区。
撤销本地提交
对于已经本地的提交,也就是使用 git add
并且执行了 git commit
的修改,这时候本地的修改已经进入了本地仓库,而这是需要撤销这一次提交,或者本地的多次提交,怎么办?
git reset --hard origin/master
同样还是 git reset
命令,但是多了 origin/master
,origin
表示远端仓库的名字,默认为 origin,可能也有其他自己的名字,origin/master
表示远程仓库,既然本地的修改已经不再需要,那么从远端将代码拉回来就行。
不过不建议直接使用 git reset --hard origin/master
这样太强的命令,如果想要撤销本地最近的一次提交,可以使用
git reset --soft HEAD~1
这行命令表示,将最近一次提交 HEAD~1
从本地仓库回退到暂存区,--soft
不会丢弃修改,而是将修改放到暂存区,后续继续修改,或者丢弃暂存区的修改就可以随意了。如果要撤销本地两次修改,则改成 HEAD~2
即可,其他同类。
不过要注意的是,已经提交到远端的提交,不要使用 git reset
来修改,对于多人协作项目会给其他人带来很多不必要的麻烦。
撤销远端仓库修改
对于已经推送的修改,原则上是不要撤销的,不过 Git 给了使用者充分的*,在明确自己在做什么的情况下,可以使用 git push -f
使用 force 选项来将本地库 force 覆盖远端仓库,强制 push 到远端。
对于个人,一个人使用的项目使用这样的方式,并没有太大问题,但是如果对于多人项目,如果你强行改变了远端仓库,别人再使用的时候就会出现很多问题,所以使用 git push -f
时一定要想清楚自己在做什么事情。
上一篇: 请教用rename这个函数如何会出现这样的有关问题
下一篇: Git撤销修改+删除文件