本文将介绍本地仓库的基本操作:
- 文件操作命令
- 代码回滚命令
掌握好这些命令之后,就能完成大部分个人作业了。
文件操作
1. 检查状态 - git status
git status
是一个非常重要的命令,它显示你的代码在工作区和暂存区的状态。
$ git status
On branch master
Untracked files:
(use "git add ..." to include in what will be committed)
modified: readme.txt
可以加-s
参数,以获得简短的结果输出。若没有这个 标记,则会有更多的提示与上下文提醒。
2. 查看改动 - git diff
我们可以通过git diff
命对比三个区之间的数据差别。
命令 | 作用 |
---|---|
git diff | 工作区vs缓存区 |
git diff HEAD | 工作区vs版本区 |
git diff --cached | 缓存区vs版本区 |
当前三个区的数据是一致的,执行命令都为空。
命令 | 结果 |
---|---|
git diff |
|
git diff HEAD |
|
git diff --cached |
|
然后给 master.txt 添加一行内容后,现在工作区内容发生变化,暂存区和版本库内容不变。
!()[]
命令 | 结果 |
---|---|
git diff |
|
git diff HEAD |
|
git diff --cached |
|
执行git add master.txt
之后,修改同步到缓存区,现在工作区与缓存区数据一致。
命令 | 结果 |
---|---|
git diff |
|
git diff HEAD |
|
git diff --cached |
|
执行git commit
操作后,修改已经同步到版本库,三区数据再次保持一致。
命令 | 结果 |
---|---|
git diff |
|
git diff HEAD |
|
git diff --cached |
|
3. 查看版本库提交记录 - git log
简而言之,就是查看版本库中的提交历史记录。
这条命令有很多参数选项,我在下面只列举几个常用的参数。
一、不带参数
- 如果不带任何参数,它会列出所有历史记录,最近的排在最上方,显示提交对象的哈希值,作者、提交日期、和提交说明
- 如果记录过多,则按Page Up、Page Down、↓、↑来控制显示
- 按q退出历史记录列表
$ git log
commit 723ba27fbf4320237639151a4f44cf7b2cf93999 (HEAD -> master)
Author: ColleenKuang <colleenkuang@qq.com>
Date: Wed Jun 20 01:11:41 2018 +0800
add master.txt
commit b556edeab10f7f4365867e0172db4bfeee1b34e6
Author: ColleenKuang <colleenkuang@qq.com>
Date: Tue Jun 19 23:53:20 2018 +0800
add version number
二、带参数
- --graph 显示ASCII图形表示的分支合并历史
- --p 按补丁显示每个更新间的差异,比下一条- -stat命令信息更全
- --stat 显示每次更新的修改文件的统计信息,每个提交都列出了修改过的文件,以及其中添加和移除的行数,并在最后列出所有增减行数小计
- --pretty=oneline 一行显示,只显示哈希值和提交说明(--online本身也可以作为单独的属性)
- -n 显示前n条log记录
- --author="author_name" 显示名为author_name贡献的commit。注意:作者名不需要精确匹配,只需要包含就行了
4. 删除未跟踪文件 - git clean
git clean
命令将未跟踪的文件从你的工作目录中移除。它只是提供了一条捷径,因为用 git status
查看哪些文件还未跟踪然后手动移除它们也很方便。和一般的 rm
命令一样,git clean
是无法撤消的,所以在删除未跟踪的文件之前想清楚,你是否真的要这么做。
$ git clean -n
执行一次git clean的『演习』。它会告诉你那些文件在命令执行后会被移除,而不是真的删除它。
$ git clean -f
移除当前目录下未被跟踪的文件。-f
(强制)标记是必需的,除非 clean.requireForce
配置项被设为了 false
(默认为 true
)。它 不会 删除 .gitignore
中指定的未跟踪的文件。
$ git clean -df
移除未跟踪的文件,以及目录。
$ git clean -xf
移除当前目录下未跟踪的文件,以及 Git 一般忽略的文件。
代码回滚
1. 检出之前的提交 - git checkout
版本控制系统背后的思想就是「安全」地储存项目的拷贝,这样你永远不用担心什么时候不可复原地破坏了你的代码库。当你建立了项目历史之后,git checkout
是一种便捷的方式,来将保存的快照「加载」到你的开发机器上去。
git checkout
这个命令有三个不同的作用:检出文件、检出提交和检出分支。在这一章中,我们只关心前两种用法。
检出文件
git checkout <commit> <file>
执行后,git会从指定的提交中拷贝文件到暂存区域和工作目录,而工作区中剩下的文件不变,接下来看个例子:
$ git checkout da985 hello.py
将提交节点da985中的hello.py复制到工作区和缓存区中,你就可以查看da985节点的hello.py(如果命令中没有指定提交节点,则会从暂存区域中拷贝内容。)注意当前分支不会发生变化。
这里确实会影响你项目的当前状态。旧的文件版本会显示为需要提交的更改,允许你回滚到文件之前的版本。如果你不想保留旧的版本,你可以用下面的命令检出到最近的版本:
$ git checkout HEAD hello.py
检出提交
git checkout <commit>
执行后,更新工作目录中的所有文件,使得和某个特定提交中的文件一致。与此同时,HEAD标识会移动指定的提交。这被称为分离HEAD。
分离的头指针(匿名分支提交) - Detached HEAD
当HEAD处于分离状态(不依附于任一分支)时,提交操作可以正常进行,但是不会更新任何已命名的分支。(你可以认为这是在更新一个匿名分支。)
一旦此后你切换到别的分支,比如说master,那么这个提交节点(可能)再也不会被引用到,然后就会被丢弃掉了。注意这个命令之后就不会有东西引用2eecb。
但是,如果你想保存这个状态,可以用命令git checkout -b name
来创建一个新的分支。
2. 重置提交历史 - git reset
git reset
重设一个旧的提交,你不得不移除那个提交后的所有提交,再移除那个提交,然后重新提交后面的所有提交。不用说,这并不是一个优雅的回滚方案。
此外,git reset
可以通过设置参数有选择的变动工作区、缓存区和版本仓库。
- --soft – 缓存区和工作目录都不会被改变
- --mixed – 默认选项。缓存区和你指定的提交同步,但工作目录不受影响
- --hard – 缓存区和工作目录都同步到你指定的提交
这些标记往往和HEAD
作为参数一起使用。比如,git reset --mixed HEAD
将你当前的改动从缓存区中移除,但是这些改动还留在工作目录中。另一方面,如果你想完全舍弃你没有提交的改动,你可以使用git reset --hard HEAD
。这是git reset
最常用的两种用法。
如果你在本地仓库中作死之后想要毁尸灭迹,git reset --hard
和 git clean -f
是你最好的选择。记住,git reset
只影响被跟踪的文件,所以还需要一个单独的命令来清理未被跟踪的文件。运行这两个命令使工作目录和最近的提交相匹配,让你在干净的状态下继续工作。
3. 撤销已提交快照 - git revert
git revert
命令用来撤销一个已经提交的快照。但是,它是通过搞清楚如何撤销这个提交引入的更改,然后在最后加上一个撤销了更改的新提交,而不是从项目历史中移除这个提交(重写提交历史)。这避免了Git丢失项目历史,这一点对于你的版本历史和协作的可靠性来说是很重要的。
$ git checkout hotfix
$ git revert HEAD~2
相比git reset
,它不会改变现在的提交历史。因此,git revert
可以用在公共分支上,git reset
应该用在私有分支上。
你也可以把git revert
当作撤销已经提交的更改,而git reset HEAD
用来撤销没有提交的更改。
就像git checkout
一样,git revert 也有可能会重写文件。所以,Git 会在你执行 revert 之前要求你提交或者缓存你工作目录中的更改。
小总结
命令 | 作用域 | 常用情景 |
---|---|---|
git reset | 提交层面 | 在私有分支上舍弃一些没有提交的更改 |
git reset | 文件层面 | 将文件从缓存区中移除 |
git checkout | 提交层面 | 切换分支或查看旧版本 |
git checkout | 文件层面 | 舍弃工作目录中的更改 |
git revert | 提交层面 | 在公共分支上回滚更改 |
git revert | 文件层面 | 然而并没有 |
参考链接:
廖雪峰Git教程
30分钟git命令入门到放弃
图解Git
代码回滚:Reset、Checkout、Revert 的选择