Git必知必会

到了Palm之后开始接触Git,逐渐发现Git的便利之处。于是觉得很有必要掌握更多的Git技巧,而不能重演SVN的历史(只懂得基本的操作:checkout checkin update info)。

Git必知必会之:Git好在哪里

个人体验,Git最好的地方在亮点:

  • 离线管理(也就是通常说的“分布式”)
  • 分支

先说说离线管理。

Git能做到离线管理基于Git本地仓库是对“服务器”仓库的完全拷贝,本地拥有版本管理所需要的任何信息:变更历史、分支、标签等等。

有了离线管理,大部分的工作都不需要依赖网络了。虽然说现在的网速是越来越快,但网络的速度总是比不上本地的速度。(虽然版本历史多了之后,Git查看日志的速度也不算很快 :( )。

至于为什么Git要实现离线管理的功能,应该跟Git的背景有关:开发Linux的多数是些自愿者,他们崇尚开源、自由和免费,并且分布在世界各地,能依赖一个中央版本仓库来管理源代码并不方便。

分支

在SVN里,分支其实就是一个目录,比如通常的项目目录结构如下:

+trunk
+tags
+branches
   --production
   --emergency
   ...

在SVN的世界里,一个分支其实就是一个目录,production对应:http://server/project/branches/production; emergency对应http://server/project/branches/emergency。

而Git则完全不同,不同的分支是不同的时空,分支之间除了可以merge之外没有任何联系。比如http://server/porject.git

这个项目,本地的工作空间是/home/user/project/,在该目录内同时只能有一个branch的内容,即/home/user/project/readme.txt在另外一个branch的目录也是/home/user/project/readme.txt

Git必知必会之:基本Git命令

对一个版本控制系统来说,总少不了这样的命令:

  1. 添加文件进入版本控制系统
  2. 提交修改过的内容进入版本系统
  3. 将文件从版本系统中删除
  4. 查看某文件(或全部)的修改历史
  5. 比较两个文件的差异

下面分别介绍对应的Git命令。在这之前,需要在本地搭建一个git仓库:

git init

 输出:

Initialized empty Git repository in /home/gavin/project/git/blog/.git/

执行之后在该目录下多了个.git的隐藏目录,就算初始化成功了。这个目录里包含了git的全部信息,关于里面的文件结构以后可以继续研究。

添加文件进入版本控制系统

init之后,仓库还是空的,看不到任何log。(如果运行git log 将会出现这样的错误:fatal: bad default revision 'HEAD')。现在将文件readme.txt添加进工作区(工作区的概念在下一节)

git add readme.txt

 这样readme.txt就已经在工作区里了(但还未提交),即此文件以后就归git管理了。

提交文件修改

git commit -m "Jira-0001: first commit"

 也可以加另外一个参数:-a 表示直接提交所有文件(而不是只在工作区中的文件,从未add过的文件除外),这样就可以不执行git add命令了。

查看日志

git log readme.txt

 如果已经习惯SVN的日志输出格式,还可以加一些参数限制输出格式:

git log --pretty=format:'%h %an %cd %s' readme.txt

其中,

%h 表示此次提交的唯一标识;

%an 表示提交人 (author name)

%cd 表示提交日企 (commit date)

%s 表示提交时输入的消息 (即通过-m参数指定的字符串)

在linux下还有些图形化的日志工具:gitg 和gitk

git log的更多用法可以参见:http://gitref.org/inspect/#log

从仓库中删除指定文件

将文件添加进git可以用git add和git commit,那么从库中删除指定文件,即不再需要将某个文件纳入版本管理的命令是:

git rm --cached readme.txt
git commit -m "delete readme.txt" 

注意,如果不加--cached参数,则会将文件从磁盘删除。

放弃本地修改

偶尔会出现修改代码,却越改越乱的情况,这时候就想reset到原始状态。

git reset HEAD -- readme.txt

也可以通过checkout:

git checkout readme.txt

  checkout 和 reset的区别在于:reset是将当前“指针”指向到某处(默认为最新版本),而自某处之后的版本将被丢弃(通过低级命令可以找回); 而checkout只是将指定版本的内容签出到当前版本。

比较两个文件

git diff

将显示所有未“git add”的修改内容。而:

git diff --cached

将显示所有已经经过“git add”但未经过“git commit”的变动。

如果想比较同一个文件的不同历史版本可以:

git diff 6a5a54f:readme.txt 91d2ea9:readme.txt

 当然如果只是想比较两个版本的不同,不需要特别指定某个文件,则只需将版本后的“:readme.txt”去掉即可。

创建分支

前面提到过分支的强大,我通常为每个任务创建一个分支:

git branch jira-0001

这样就创建了一个名为jira-0001的分支,可以通过:

git checkout jira-0001

切换到该分支。想查看所有已经创建的分支:

git branch -l

合并分支

在分支上的工作上结束之后,需要将修改合并到主分支上,比如需要将jira-0001的工作合并到master中,则:

git merge jira-0001
 

如果一切顺利,则工作就算完成了,如果不走运(很遗憾,这经常发生),则会出现这样的错误:

CONFLICT (content): Merge conflict in readme.txt
Recorded preimage for 'readme.txt'
Automatic merge failed; fix conflicts and then commit the result.
 

则需要手动修改文件,提交后工作才算完成。git还为此提供了图形化界面,可以通过:

git mergetool

来进入图形化界面 (前提是在git 配置过mergetool)。

后续内容

经过一次草稿丢失(草稿隔了夜,早上新加的几段没保存)后,发现git有太多的内容需要介绍:

git log

git 配置

git remote、fetch、pull

这些内容不是一篇博文能承载的,留在后面补充吧。

猜你喜欢

转载自shuminghuang.iteye.com/blog/1582359