前言
Git 是目前世界上最先进的分布式版本控制系统。相比较CVS及SVN这种老式的集中式版本控制系统,要更加灵活方便,也更安全稳定。集中式是指版本库是放在中央服务器中,需要联网才能工作。分布式是指没有中央服务器,每个人电脑上有个完整的版本仓库,可以本地修改代码再联网提交到Git服务器上,Git服务器作用仅仅“交换”大家的修改即代码同步。此外,Git还拥有极其强大的分支管理功能。
Git 命令
本文主要介绍基础的 Git 命令,更加复杂的 Git 命令可以查看:Git 进阶教程。另外 Git 的常用命令文档可以参考:git-cheatsheet。
创建仓库
始终要记住你的本地和Git服务器上都存在版本仓库(repository),Git实现代码同步实际上是同步你的本地仓库和远程仓库。有两种方式创建仓库:1. 从服务器上克隆一个仓库;2. 初始化一个本地仓库。
从Git服务器上克隆(clone)一个仓库下来,可以通过ssh或http的方式。ssh需要将你的公钥存放在Git服务器上,而http不需要但是速度相较ssh要慢。
1 | git clone git@github.com:s1mplecc/MyHashMap.git |
从远程库克隆下来的是完整的版本库,含有.git
文件夹,其下的config
文件夹包括了本仓库的配置信息。包含了url、远程库的名字以及分支等:
1 | ➜ cat .git/config |
第二种方式,git init
是将当前目录初始化为Git可以管理的仓库。会在当前目录下生成了.git
文件夹。
如果要将本地仓库推到服务器上,需要现在服务器上创建一个repository,然后在本地目录下绑定服务器上的repository,origin是版本库默认的名字:
1 | git remote add origin git@github.com:s1mplecc/MyHashMap.git |
提交变更
当你对版本库中的文件做了变更(增删改),可以使用git status
命令查看当前版本库的状态:
1 | ➜ github.io git:(hexo) ✗ git status |
git add .
或者git add all
将所有修改提交到暂存区。.
表示当前目录下所有修改了的文件,当然也可以指定某个文件。
将暂存区的所有内容提交到当前分支,默认分支即Git为我们自动创建的master分支。-m
参数后面接提交的message:
1 | git commit -m "balabala" |
将当前分支提交到远程库中,-u
第一次使用时将本地的master分支绑定到远程库的master分支,以后可以省略不加:
1 | git push -u origin master |
从远程库拉取修改:
1 | git pull origin master |
在开发过程中会有频繁的提交,所以日常中我们用到最多的就是上述命令了。本质上本地与远程版本库的同步就是记录下每次的修改信息。Git会帮我们记录下每次提交的修改,方便我们进行同步、回退以及合并。
.gitignore
说到add
不得不提.gitignore
这个文件,它的作用是忽略一些文件的提交,比如IntelliJ IDEA生成的.idea
文件、编译生成的target
文件等等。这类文件不需要提交到服务器污染大家的环境。关于.gitignore
的编写github上都有现成的模版。另外IDE也可以安装相应的gitignore插件。
查看提交历史
正是Git帮我们记录了每次提交的修改,我们可以通过命令查看历史信息,以及每次做了什么修改。
git log
查看提交历史,每条记录有一个唯一的id用于标识,使用时可以使用可以唯一表示的前几位。添加参数-p <file>/<commit id>
查看指定文件或某次commit的历史信息:
1 | commit 24345a1a74184f99eb32202bfcc1cd0fd6ac945d (HEAD -> master) |
git diff b90b6da
查看某次提交后与当前版本的区别,可以看到我在文本中添加了一行second:
1 | @@ -1 +1,2 @@ |
git reflog
查看命令操作历史。
撤销变更
如果你在提交了某次变更后又想撤销这次变更,Git也提供了撤销和回退的功能。Git将提交记录(节点)串成一条线,HEAD就是一指向当前版本的指针,做回退操作其实就是这个指针在这条线上的节点间移动。牢记:Git跟踪并管理的是修改,而非文件。
reset
命令回退到指定的某个版本,HEAD
表示当前版本,HEAD^
表示上一个版本。也可以用具体的 commit id:
1 | git reset --hard HEAD^ |
如果你修改了某个文件,但还没有add
,可以直接舍弃这次修改:
1 | git checkout -- <file> |
如果你已经commit
了,也可以还原回去:
1 | git revert <commit id> |
revert与reset的区别在于,revert会生成一次新的提交去移除某些提交(相当于反向操作),在节点线上还是向前走的。而reset是把HEAD指针后移到指定节点,直接从这个节点走出新的一条线。可以参考代码回滚:git reset、git checkout和git revert区别和联系。