基本概念
4个区
如上图所示,git有4个区,和svn有很大的不同,git中引入了暂存区/缓存区(Stage/Index)的概念
- 工作区(Workspace)
- 暂存区(Stage/Index)
- 本地仓库(Repository)
- 远程仓库(Remote)
在svn中我们都是直接将文件提交到版本仓库中去,而在git中,则多了一层关卡。
工作区很好理解,就是我们能看到的工作目录,就是本地的文件夹。
工作区最原始的状态是未修改状态(Origin),如果修改了某些文件就会变成已修改(Modified)。
我们要通过git add
命令先将他们添加到暂存区中,这时就会产生已暂存(Staged)状态。
git commit
命令则可以将暂存区中的文件提交到本地仓库中去,状态变为已提交(Committed)。
最后通过git push
推送到远程仓库,推送成功状态变为已推送(Pushed)。
基本操作
仓库初始化
仓库的初始化有两种方式:
- 一种是直接从远程仓库克隆
- 另一种则是直接从当前目录初始化
从当前目录初始化的方式很简单,直接执行如下命令:
$ git init
执行完成后当前目录下会多出一个.git的隐藏文件夹,所有git需要的数据和资源都存放在该目录中。
然后正常的add
和commit
之后,
$ git remote add origin <url>
$ git push -u origin master
查看仓库状态
可以通过git status
命令来查看仓库中文件的状态。
git status -s
: 文件状态的简写(M - 修改, A - 添加, D - 删除, R - 重命名,?? - 未追踪)。
提交命令
- 一种是直接通过
git commit -m "备注信息"
命令 - 如果要写的备注很多,可以通过
git commit
来打开指定编辑器,然后在编辑器中输入备注信息。
在.gitconfig文件中 [core] 段中加上 editor=vim来修改git提交信息到编辑器为vim
如图所示,在vim编辑器中按照既定的格式编辑内容,编辑完成后保存退出,此时文件就commit成功了。如果临时改变主意不想提交了,删除备注信息后保存退出,
此时提交就会终止。
提交成功之后,我们可以通过如下命令重新编辑上次提交的备注信息:
$ git commit --amend
查看提交日志
我们可以使用 git log
命令来查看历史提交。git log
命令因为其后边参数的多样性,使用起来是比较灵活而强大的,并且比较实用。
下面列车一些常用的命令:
- 使用
git log
命令我们可以查看以往仓库中提交的日志 - 使用
git log --abbrev-commit
命令缩短版本号 - 使用
git log --pretty=short
命令查询简略信息 - 使用
git log --stat
命令查看简化版的diff日志信息 - 使用
git log --name-only
命令仅在提交信息后显示已修改的文件清单 - 使用
git log --name-status
命令显示新增、修改、删除的文件清单 - 使用
git log --relative-date
命令显示较短的相对时间 - 在
git log
后面加上文件名查看指定文件的提交日志,如果还想查看提交时文件的变化,加上-p参数即可。 - 使用
git log -p -1
来查看最近一次提交的差异 - 使用
git log --graph
命令可以让log以更直观的方式来展示
我们还可以使用
git log --pretty
来定义显示格式,如:git log --graph --pretty=format:"%h - %an, %ar : %s"
, –pretty=format:后边跟着的是格式化的字符串。
其中 %h 表示简化版的Hash值, %an 表示作者名字(Author Name), %ar 表示多久以前提交的,%s 则是提交信息。
查看更改前后的差异
已修改,未暂存
使用
git diff
命令我们可以查看工作区和暂存区的差异。
已暂存,未提交
如果我们执行
git add .
把修改提交到暂存区,然后再执行git diff
,你会发现没有任何信息输出。这说明git diff
这个命令只检查我们的工作区和暂存区之间的差异。
如果我们想看到暂存区和本地仓库之间的差异,就需要加一个参数git diff --cached
。
或者通过命令git diff HEAD
来查看(实际上是工作区与当前分支最近一次commit之间的差异)。
已提交,未推送
现在,如果通过命令
git commit
把修改从暂存区提交到本地仓库,然后再执行git diff –cached,没有差异,执行git diff master origin/master
,可以看到差异
删除文件
当我们需要删除工作区和暂存区上的文件,可以执行git rm <filename>
命令,该命令等同于以下两个命令:
//直接在文件管理器中把文件删了
$ rm file
//提交到工作区
$ git add file //或者 git rm file
当我们希望某个文件不被版本控制,但是本地又需要使用,可以使用git rm --cached <filename>
。
重命名
可以通过git mv <SourceFile> <RenameFile>
命令将SourceFile重命名为RenameFile,该命令等同于以下三个命令:
$ mv SourceFile RenameFile
$ git rm SourceFile
$ git add RenameFile
git add -N
你可以用git add -N <filename>
(“通知”)来告诉Git你想把新添加的文件包含在提交中在你第一次实际提交之前,使用该命令之后执行git diff
命令就可以查看到更改。
git add -p
交互式提交,询问你是否愿意将它提交,跳过,或者推迟决定(还有其他一些更强大的选项,你可以通过在运行这命令后选择?来查看)。git add -p
是一个神奇的工具来生产结构良好的提交。
git checkout -p
与git add -p
类似,git checkout
命令将使用 --patch
或 -p
选项,这会使 git 在本地工作副本中展示每个“大块”的改动,并允许丢弃对应改动 —— 简单地说就是恢复本地工作副本到你改变之前的状态。
压缩提交历史
git rebase -i
命令可以实现提交历史的压缩。比如我们在开发某一个功能时,提交了很多次,当所有功能都写完时,想将这些提交压缩为一个,就可以使用该命令。
如:通过执行git rebase -i HEAD~2
命令来压缩前两个版本的提交历史,会自动打开一个vim编辑器,压缩之后,最新一次的提交日志就没了,但是数据还在。
基于时间修改的指南
这个功能在某些时候会变得十分有用,比如当你处理最新出现的 bug,自言自语道:“这个功能明明昨天还是好好的,到底又改了些什么”,不用盯着满屏的 git 日志的输出试图弄清楚什么时候更改了提交,您只需运行git diff HEAD@{yesterday}
,会看到从昨天以来的所有修改,这也适用于较长的时间段(例如 git diff HEAD@{'2 months ago'}
) ,以及一个确切的日期(例如git diff HEAD@{'2010-01-01 12:00:00'}
)。
您还可以将这些基于日期的修改参数与使用修正参数的任何 Git 子命令一起使用。在 gitrevisions 手册页中有关于具体使用哪种格式的详细信息。
全知的 reflog
你是不是试过在 rebase 时干掉过某次提交,后来又发现你需要保留这次提交的一些东西?你可能觉得这些提交的东西已经永远找不回来了,只能从头再来了。其实不然,但如果你在本地工作副本中提交了,提交就会进入到 “引用日志” ,你仍然可以访问到。
运行 git reflog 将在本地工作副本中显示当前分支的所有活动的列表,并为您提供每个提交的 SHA1 值。一旦发现你 rebase 时放弃的那个提交,你可以运行 git checkout