撤销修改
撤销修改是指将工作区中的修改撤销。
语法:git checkout 文件名或路径
# 撤销工作区中当前目录中的所有更改
git checkout .
# 撤销工作区中指定文件的修改
git checkout -- filename
git checkout 命令只能撤销工作区中的修改,而不能撤销暂存区中的修改。
git checkout 命令还有一个非常重要的功能就是切换分支。可用于分支管理。
# 切换到已经存在的分支
git checkout master
# 切换分支的同时,创建分支 git checkout -b my-dev
这里,只是简单说一下 git checkout 如何切换分支,等你需要用到分支管理的时候,自然就明白了。
版本回退
版本回退是指将版本库从当前版本回退到其他的版本。
语法:git reset --hard 版本号
有时,我们需要将 Git 版本库回退(还原)到以前的某个版本,可以使用 git reset 命令。
在 Git 中,HEAD 指针指向的是当前版本,也就是最新的 commit id,上一个版本是 HEAD^,上上一个版本就是 HEAD^^,上50个版本可以写成 HEAD~50。
可以使用下面的命令,将 Git 回退到上一个版本:
git reset --hard HEAD^
这时,我们再来使用 git log 命令查看版本库被修改的日志。却发现,看不到被回退的版本之后的历史记录了。如果,想再回到最新的版本,怎么办?
只要刚刚的命令行窗口没有关掉,你就可以顺着往上面找,直到发现最新的版本号(如4b2a0c88a2d03675694013ac6a2bd6f55c830cdc),于是,就可以使用下面的命令还原到指定的版本:
git reset --hard 4b2a0c8
版本号(commit id)没必要写全,一般写前七位就够了,Git会自动去匹配。
但是,假如你回退到了某个版本后,把电脑关了。第二天又后悔了,想要恢复到最新版本。
这时,可以使用命令 git reflog 来查看你的每一次操作日志,该命令可以输出对应的版本号的操作记录。这样,我们就可以恢复到任意版本了。
git reset 的选项
git reset 有很多可用的选项。可以通过帮助命令来查看。
git reset -h
其中,最常用的三个选项是:
- --mixed: reset HEAD and index。表示重置 HEAD 指针和 index 暂存区,但保持工作区不变。它是默认选项。
- --soft: reset only HEAD。表示仅仅重置 HEAD 指针,即只改变 HEAD 的指向,但保持工作区和暂存区不变。
- --hard: reset HEAD, index and working tree。表示重置 HEAD 指针、index 暂存区和工作区。这个才是完整的版本回退。
查看版本库的状态
git status
git status 命令非常有用。它可以查看版本库的当前状态,还可以看到相关操作的提示信息。
查看修改
如果你修改了工作区中的某些文件,想要查看具体更改了什么内容,可以使用 git diff 命令。
git diff .
git diff filename
查看工作区和版本库的区别
如果你只是修改了工作区,还没有 git add 到暂存区,想要查看工作区和版本库的区别。
# 查看工作区和版本库的区别
git diff
上述命令只能查看到工作区中已经存在的文件的修改,如果是新创建的文件,它追踪不到。如果修改和新文件已经 git add 到了暂存区,就需要使用下面的命令来查看。
查看暂存区和版本库的区别
如果你修改了工作区,已经 git add 到了暂存区,想要查看暂存区和版本库的区别。
git diff --cached
查看两个版本之间的区别
如果你修改了工作区,已经 git add 到了暂存区,并且 git commit 到了版本库。这样 head 指针就指向了最新的版本。想要比较两个版本之间的区别。
语法: git diff 版本号1 版本号2
# 比较两个版本之间的差异
git diff 4129523 0a7d9af
在这个例子中,412952 是上一个版本的版本号,0a7d9af 是当前的版本号(最新版本号)。只取前 7 位就够了。
# 比较之前的版本和当前版本的差异
git diff 4129523 head
# 比较某个文件在两个版本之间的差异
git diff 09d9b45 head ./config/app.php
# 比较之前的版本和当前版本的差异的简写形式
git diff 4129523
查看本地的两个分支的区别
语法格式为:git diff branch1 branch2
# 比较 develop 分支和 master 分支的区别
git diff develop master
查看本地分支和远程分支的区别
# 对比本地的 develop 分支和远程的 master 分支的区别
git diff develop origin/master
查看版本库的历史记录
如果你想查看版本库提交的历史记录 ,可以使用 git log 命令。
# 查看版本库的历史记录
git log
# 查看版本库的历史记录,美化输出
git log --pretty=oneline
# 查看版本库的历史记录,只显示前 5 条
git log -5
git log -5 --pretty=oneline
git log 命令默认会进入日志查看模式,可按 q 退出查看模式。
git log 命令会显示从最近到最远的提交日志,每一行的前面的一大串字符就是 commit id(版本号),它和 SVN 的版本号不一样,Git 的版本号不是递增的数字,而是一个 SHA1 加密计算出来的一个非常大的数字,用十六进制表示。
场景分析
场景一
假如你只是修改了工作区,还没有 git add 到暂存区。可以使用下面的命令撤销工作区中的修改。
# 仅仅是撤销工作区中的修改
git checkout .
场景二
假如你修改了工作区,并把工作区中的修改 git add 到了暂存区。
如果你想撤销工作区和暂存区中的修改。
git reset --hard head
# 简写为
git reset --hard
如果你仅仅只是想要撤销暂存区中的修改。
git reset --mixed
# 简写为
git reset
场景三
假如你修改了工作区,并把工作区中的修改 git add 到了暂存区,然后又 git commit 提交到了版本库。
如果你想回退到上一个版本,可以使用下面的命令。
git reset --hard head^
查看当前的版本号,可以使用。
git rev-parse HEAD
需要注意的是,在 Windows 的 CMD 中, ^ 代表换行,即命令没输完,在下一行继续输命令。它相当于 Linux 中的 \ 。
因此,在 CMD 中回退到上一个版本的写法,就略有不同。
具体的解决方法有:
- git reset --hard "head^"
- git reset --hard HEAD^^
- git reset --hard HEAD~
- git reset --hard HEAD~1
- 改用 PowerShell 或 Git Bash 终端
还有一个需要注意的问题是,通常我们所说的版本回退是指完整的版本回退。
如果你回退版本时,采用的是 『 git reset --mixed 版本号 』,--mixed 其实本来就是默认选项。那么,你只是更改了 head 的指向和回退了暂存区,而并没有回退工作区。如果想要继续把工作区也回退,你还需执行下面的命令
git checkout .
这样,才算完整的版本回退。
完整的版本回退,包含三个要素:
- 更改 HEAD 指针的指向(即让 HEAD 指向目标版本)
- 回退工作区(即工作区中的内容也要回退到目标版本)
- 回退暂存区(即暂存区中的内容也要回退到目标版本)
为此,推荐使用 git reset --hard 来完成版本回退。