git是当前最流行的版本控制软件之一。全世界的程序员都在使用它。它出自linus大神之手,现在被用于内核的版本控制。在最流行的代码托管软件github,你几乎可以找到所有开源项目的代码。
## 版块控制软件:我需要吗?
的确对于许多人——尤其是非程序员,他们可能不会想到已经出现了专门的版本控制的软件。但其实多人对版本控制其实都有类似的需求,举个例子,Tom是社团的秘书处成员,他们经常需要做的事情就是写活动文档,然后不停地改改到大家都觉得可以了。
不幸运的话,Tom可能有个文件夹叫“openSUSE活动策划",里面有这样的一堆文件”openSUSE活动策划", “活动策划1”, “活动策划2”, “活动策划3”, “活动策划4” … “活动策划20” (可怜的Tom,一份文档改了不少于20次)
这种作法很有效,因为我们可能发现第5个版本的策划有问题,我们准备在第3个版本上面重新来过。但是也看到,这个作法有些很丑陋的地方:一份文件,我们留了20个备份,而且还要注意文件名。
如果可以这样就好了:文件夹上只有一个“openSUSE活动策划",但当我需要第5个版本的时候,我来一个”给我还原到第5个版本吧!“,然后这时候我们打开这个文件,它就是第5个版本的了。类似的,我们可以取出任意的版本。
这就是版本控制。这种事情在程序里面发生的太多了,于是出现了各种版本控制软件。事实上,有些项目已经发展到第1000+甚至更高的版本数了……
## 单线的工作流
我们可以把我们的一个项目想象为一个仓库,然后我们可以把我们的东西塞进仓库里面,也可以把想要的东西拿出来。而git则是仓库的管理员。下面是一个例子,希望有一个直观的印象,不求完全的理解和掌握。
```bash
mkdir myproject // 假设myproject是工作目录
cd myproject
git init // git <- (init) ,告诉仓库管理员,在当前目录初始化
echo 'Eat the banana' > file // 编辑了一个文件
git add file // 加入仓库
git commit -m 'add first file' // 提交更改
echo 'Eat the apply' > file // 修改了这个文件
git add file // 加入仓库
git commit -m 'update first file' // 再提交更改
```
这时候我们就有两个commit了,我们来看看工作日志:
```bash
git log
# 以下是输出
# commit ac1371173b4e630ddaebda3f9f5d948b36146c07
# Author: Norman Mo <LTaoist@@@>
# Date: Thu Jun 27 21:59:10 2013 +0800
#
# update first file
#
# commit 3c43cc913454f92bb4b80c56ba45e4ffaf556fc0
# Author: Norman Mo <LTaoist6@@@@>
# Date: Thu Jun 27 21:58:48 2013 +0800
#
# add first file
```
看到了,我们提交了两次。我们来看看现在file里面是什么:
```bash
cat file # 显然输出是 'Eat the apply'
# 现在,我们来拿回第一个版本的file文件
git checkout 3c43cc913454f92bb4b80c56ba45e4ffaf556fc0 -- file
cat file # 这时候就是eat banana了
```
这种工作的方式是单人使用最常见的方式,写一点代码,提交一下到仓库里面。写一点,提交到仓库里面。然后出问题的时候就回退过去。git非常强大,基本上你想到的他都可以做到,提交到仓库的数据基本不会丢失,像时间机器一样控制着代码。
## 多人协作
git非常强大,上面只是一个功能。考虑Tom的秘书处有两个人,他们在同时写。其中Tom写前6章,他的同伴写第7~12章。
这时候可以考虑用这种工作的方式:设立一个公共的仓库。Tom维护自己的版本,他的同伴维护自己的版本。然后大家定期把代码合并到公共仓库上面,然后定期把新的版本取回来合并再提交到公共仓库。
如果他们用纯文本,得益于一些文本分析的方法,几乎不需要校对就可以做到。
```
git commit -m 'finish ch5' // 假设此时Tom写完了第5章
git push // Tom将代码推送到远程仓库
```
```
git commit -m 'finish ch11' // 假设此时Tom的同伴完成了第11章
git pull // pull会将最新版本拉下来,合并,然后推送到远程仓库
```
实际上工作中,为了不混淆,会新开一个分支来开发新的特性,然后对分支进行合并。
## 代码自动发布
另一个很强大的功能是可以实现代码的自动发布。事实上,很多云就有使用这个。具体来说,利用git的hooks,当服务器收到一个push,服务器可以自动运行一些脚本。也可以在客户端使用hooks,当客户端准备push的时候,客户端先运行一些脚本。
例如,我们希望在每次服务器收到push以后,杀死全部的 p
进程,然后重开 p
进程。我们可以修改 hooks/post-receive
:
```
echo "Killing all p process..."
killall -9 p
echo "Restart p process..."
p
```
## 更多更多更多……
这份教程就到这里了,更多的自己马上动手去试试吧!
在openSUSE的安装方法:
```
sudo zypper in git
```
默认应该就装了。
一般linux命令查看帮助都是 --help
选项:
```
git --help
```
此外,对一个子命令也是有help看的:
```
git init --help
```
这里有一个交互教程,在浏览器上面跑的模拟git的运行的,有兴趣的试试:
github的help文档写得很不错,推荐一下:
书籍有个远近闻名的《Pro Git》,而且有中文版的,虽然我认为这本书太厚了。。。但似乎就这么一本书……
国内有个gitcafe,也是做git托管的,他们也有整理一份help:
当然,上面只是一个演示,多试试push,多尝试。有一天你会喜欢用这个有效的工具的。