一、说明
鉴于目前使用git的公司越来越多,而笔者之前一直使用SVN,对于使用svn进行项目管理比较熟悉,但是对于git,网络上搜寻的各种资源虽然很多,但是杂乱而且很少有对于完全不懂的小白进行讲解的部分。
因此笔者通过朋友搜集了部分git相关的电子书籍,以及结合一些网络博客,在此文进行一个汇总,同时也算是对于自身学习的一种总结。
二、什么是git
1、版本控制工具。
版本控制用于记录若干文件的内容变化,以便于将来查询某一特定时间点文件的当前内容。例如原本稳定运行的项目需要新增某种新的功能,新功能完成上线后在实际情况中并不如何实用并且带来不可预知的问题,因此需要对该功能进行删除,此时,可以使用版本控制工具,对项目进行版本还原,还原到之前未添加新功能时候的项目内容。在git中,该文件可以是任意类型。
2、集中化的版本控制系统。
在版本控制工具最开始的时候,考虑的问题是如何解决多人同时开发一个项目而进行的协同工作的问题。该类型的版本控制工具也称为集中化的版本控制系统(CVCS)。
CVCS采用的做法是提供一个集中管理的服务器,保存所有文件的修订版本,而参与开发的开发人员通过客户端连接这台服务器,取出最新的文件或者提交更新。
3、分布式版本控制系统。
与集中化的版本控制系统所不同的是, 分布式版本控制系统的每一个客户端都保存了当前仓库的所有版本内容(包括历史版本记录),而不仅仅只是一个当前版本的内容。这样的好处在于避免当唯一的服务器宕机时出现的之前版本记录丢失的问题。这样每一个客户端都相当于一个服务器,都可以对仓库进行恢复,更加保证了项目的安全性。
4、git是一种分布式版本控制系统。
从诞生初期,它便被设定了如下目标:
- 速度
- 简单的设计
- 对非线性开发模式的强力支持(允许上千个并行开发的分支)
- 完全分布式
- 有能力高效管理超大规模项目
5、git与其他版本控制系统的对比。
大多数的其他版本控制系统侧重点在于所提交的某个或多个文件内容的具体差异(如左图),而git侧重点在于对文件整体的变化(右图中)。其他版本控制系统只会记录更新文件的具体修改细节,而git则是对于整个文件与仓库中保存的原文件进行对比,如果不同,则保存新的文件,如果相同,则引入它的索引,作为一个新的版本记录下来。
6、git近乎所有操作均可本地执行。
与笔者所使用的SVN每次进行更新或提交都需要保证网络能连通服务端所不同的是,由于git已经将所有的版本信息保存在了本地,因此不论是提交、更新或者还原操作,均可以在没有网络的情况下进行,等到能与服务端连接的时候,再对所更新的内容提交到服务端保存。
7、时刻保持数据完整性。
在保存到git之前,所有的数据都要进行内容的校验和计算,并将此结果作为数据的唯一标识和索引。
git使用的是SHA-1算法计算数据的校验和,通过对文件的内容或目录的结构计算出一个SHA-1哈希值,作为指纹字符串。该字符串由四十位十六进制数组成。保存在git中的所有文件实际上都是以该哈希值做索引,而不是文件名。
8、git的三种状态。
在git内容有且仅有三种状态:
- 已提交(committed):该文件已被安全地保存在本地数据库。
- 已修改(modified):已修改了某个文件,尚未提交保存。
- 已暂存(staged):把已修改的文件,放在下次提交时要保存的清单中。
由此,我们可以看到git管理项目,文件流转的三个工作区域:git本地数据目录、工作目录、暂存目录
每一个项目都有一个git目录(git directory),它是git用来保存元数据和对象数据库的地方,每次拷贝镜像仓库时,实际拷贝的就是这个目录里的数据。
从项目中取出某个版本的所有文件和目录,用以开始后续工作的叫做工作目录(working directory)。
暂存区域(staging area)只不过是个简单文件,通常放在git目录中。有时候还被称为索引文件。
9、基本git的工作流程。
- 在工作目录中修改某些文件。
- 对这些修改的文章做快照,并保存在暂存区域。
- 提交更新,将保存在暂存区域的文件保存到git目录中。
三、安装并配置git
1、安装git。
linux:
fedora:$ yum instal; git-core
Ubuntu:$ apt-get instal; git-core
windows:
从地址http://code.google.com/p/msysgit下载msysGit项目所提供的安装包(.exe)。
2、git的配置工具。
git提供了一个叫做git config的工具(实际是git-config的命令,只不过可以通过git加一个名字来呼叫此命令。),专用用来配置或读取相应的工作环境变量,这些环境变量存放在以下三个目录:
- /etc/gitconfig文件:系统中对所有用户都适用的配置,使用–system选项配置该文件。
- ~/.gitconfig文件:用户目录下的配置文件只适用于该用户,使用–global选项配置该文件。
- 当前项目的.git目录中的配置文件(工作目录下的./git/config文件):配置仅针对当前的项目。
每一级的配置都会取代更上一级的相同配置, 例如当前项目的.git/config文件中进行过配置,则在~/gitconfig文件中所配置的则会无效。
3、配置用户名称和电子邮箱。
$ git config –global user.name “yxf”
$ git config –global user.email [email protected]
配置成功后,每一次提交项目去git中,均会引用这两条信息,以标识是谁提交的更新。
4、配置文本编辑器。
默认情况下,git会使用操作系统指定的默认编辑器,一般是vi或vim。但可以通过指令来进行重新设定:
使用Emacs编辑器:$ git config –global core.editor emacs。
5、配置差异分析工具。
解决合并冲突时,改用常使用的vimdiff作差异分析工具:$ git config –global merge.tool vimdiff
6、查看配置信息。
$ git config –list
有时候会查询出相同的变量名,这种情况是由于它们来自不同的配置文件,但实际有效(被git所采用)的是最后一个。
也可以直接查询某个环境变量名,只需把特定的变量名加在参数后面即可:$ git config user.name
7、获取帮助。
有三种方式可以使用帮助:
- $ git help <verb>
- $ git <verb> –help
- $ man git-<verb>
比如要学习config命令如何使用:$ git help config
四、git基础
1、取得git仓库
有两种取得git仓库的办法:
- 在现存目录下,通过导入所有文件来创建新的git仓库。
- 从已有git仓库克隆一个新的镜像仓库。
(1)创建新的git仓库步骤:
找到项目所在目录,执行$ git init,将在当前目录下生成一个新的.git目录,所有git所需要的数据和资源都存放在这个目录中。
如果当前目录下有几个文件需要被纳入版本控制,需要使用$ git add告诉git对这些文件进行跟踪,如$ git add README.txt,如果后面一个参数是目录,则表示当前目录下所有文件都需要被添加。全部文件被放入暂存区域后,执行提交命令$ git commit -m ‘initial project version’.
(2)从现有仓库克隆:
如果已经知道一个远程git仓库的地址,可以使用git clone命令。与其他版本控制系统使用checkout不同的是,git是复制包括了历史版本的所有版本,因此使用的是clone。例如远程git仓库地址为git://github.com/schacon/grit.git,使用命令如下:$ git clone git://github.com/schacon/grit.git。
执行完之后,会在当前目录中出现一个名为grit的目录,并且将仓库中最新的文件全部拷贝在该目录下。如果想要克隆时指定自己的目录,则需要在命令行后面添加想要的目录名即可,如:$ git clone git://github.com/schacon/grit.git mygrit。
在以上例子中,git数据传输使用的地址为git://协议,同样的还可以使用http(s)://等SSH传输协议。
2、文件状态
工作目录下的文件都只有两种状态:已跟踪和未跟踪。已跟踪文件指的是已经被纳入版本控制的文件,它们可能是未更新、已修改或者已放入暂存区。而其他文件则全部是未跟踪文件,指的是未被纳入版本控制的文件。初次从远程仓库中克隆到工作目录的文件都属于已跟踪未修改,经过某些编辑后,变为已跟踪已修改,然后将它们放入暂存区域,等待最后一次性提交暂存区域里所有的文件。具体变化周期如下图
如果想要查看当前目录下的文件处于什么状态,可以执行命令$ git status,结果如下图:
git会清楚地告诉我们哪些文件做了修改已放入暂存,哪些文件做了修改未放入暂存,哪些文件未追踪等等。同时如果我们修改了一个文件,并执行$ git add将它放入暂存区域后,又再度对它进行修改,此时查询状态该文件将同时出现在”Changes to be committed”和”Changes not staged for commit”中。但需要注意的是,这两个地方的同一份文件代表的分别是不同的版本,此时执行$ git commit提交是的上一次add时的代码,而新修改的记录仍然显示未放入暂存区域。
3、忽略某些文件
对于项目日志和ide自动生成的某些文件,我们不想要将它们纳入版本控制,同时也不希望每次出现在未跟踪文件列表,因此我们可以创建一个.gitignore的文件,列出要忽略的文件模式。
首先需要执行命令$ touch .gitignore(有些是$ cat .gitignore),在当前目录下生成.gitignore文件。
然后在.gitignore文件中列出要忽略的文件模式。.gitignore格式规范如下:
- 所有空行或以注释符号”#”开头的行都会被git忽略。
- 可以使用标准的glob模式匹配。
- 匹配模式最后跟反斜杠(/)说明要忽略的是目录。
- 要忽略除指定模式以外的所有文件,可以在模式前使用”!”取反。
所谓的glob模式为shell使用的简化了的正则表达式。星号(“*”)匹配零个或任意多个字符;[abc]匹配任何一个列在方括号中的字符;问号(?)只匹配任意一个字符;[0-9]匹配0到9之间的所有数据。如下图,表示忽略目录中的.classpath和.project文件
4、查询已暂存与未暂存的更新
假如我们的文件在存入暂存区后又进行修改但未再存入暂存区域,可以使用命令$ git diff查看当前未暂存区域与暂存区域内容的不同。
如果文件已经被放入暂存区域,则使用命令$ git –cache(在git1.6及以上的版本中还允许使用$ git –staged),可以查看当前暂存区域版本与上一次提交版本的不同。
有时候使用命令$ git diff会无法执行其他命令,需要按键”q”重新退回。
5、提交更新
提交命令是$ git commit。通常在执行该命令之前,都需要先执行$ git status查看是否所有修改文件都已经放入暂存区域。
但是如果只输入提交命令,会进入文本编辑模式,让你输入本次提交的说明。
输入更新说明后,按”Esc”键,然后输入”:wq”,再按回车键,将进行保存并退出,然后提示提交成功。
或者在命令后面添加-m,如:$ git commit -m “first test”。git会将”firsr test”作为更新说明保存并提交。
同时,如果想跳过存储区直接将所有已修改文件更新,可以直接使用命令$ git commit -a -m “commit all”将所有的文件,包括放入存储区域的和未放入存储区域的,全部提交。
6、移除文件
移除文件分为两种情况,一是直接删除本地文件,二是将文件移出git的版本控制。
删除本地文件,再执行$ git status时会提示已修改但未放入存储区域,需要先执行add,再执行commit。
移出git的版本控制,需要使用命令$ git rm <file>,再执行$ git status时会提示已放入存储,但未提交,此时的该文件已经被从目录中删除,只需要再度执行commit即可。
如果仅想要将该文件移出git的版本控制,但不从目录中删除,需要在rm后添加参数–cache,如$ git rm –cache README.txt
7、移动文件
git并不会如同其他VCS系统,并不跟踪文件移动操作,也不会体现改名操作。
如果想要在git中修改文件名,需要使用命令$ git mv file_old file_new。此时,我们已经将修改放入了暂存区,只需等待提交。
但是在实际的git操作中,它相当于替我们执行了三条命令,$ git mv file_old file_new,$ git rm file_old,$ git add file_new。
8、查询提交历史
$ git log
默认不带参数的查询,会按从新到旧的顺序列出所有的更新,每一条更新记录后会有一条SHA-1的校验码,作者、电子邮箱和提交时间,最后缩进一个段落显示帮助说明。
参数-p,显示每次提交的内容差异
参数-<n>,显示最近的n次更新
以及一些常用的参数如下:
参数之间可以搭配使用,例如$ git log -p -2,即为查询最近的两次更新并显示内容差异。
除了以上在git中使用log命令外,还可以通过图形化工具gitk中进行历史版本查询。
9、撤销操作
撤销分为几种情况:修改最后一次提交,已暂存的撤销,取消对文件的修改(文件还原)。
修改最后一次提交:$ git –amend。此命令用在已经提交一次之后,发现提交文件存在问题,或者是遗留未提交的文件,此时将需要修改的文件重新add入存储区,再执行$ git –amend即可。如果想要修改提交说明,在存储区中没有新的文件时执行该命令,会有机会重新编辑提交说明,编辑后保存,即会覆盖上一次的内容。不论是哪一种,都会被作为一次提交处理。git log中也只会有修改后的记录。
取消已暂存的文件:$ git reset HEAD <file>。此命令会将已经执行add添加入暂存区域的文件重新移出。
取消对文件的修改:$ git checkout — <file>
10、远程仓库的使用
查看当前目录下的远程仓库:$ git remote -v(不加-v只显示远程仓库名字,加-v后同时显示远程仓库地址)。远程仓库的默认命名为origin
添加一个新的远程仓库:$ git remote add [shortname] [url]。之后可以使用shortname指代该远程仓库,同时目前尽只是添加远程仓库,还需要执行$ git fetch [shortname]将远程仓库上的文件拷贝到本地。
从远程仓库获取更新:$ git fetch [remote-name]。需要注意的是,该命令只是将远程仓库的数据拉到本地仓库,但并不自动合并到工作分支中。
如果设置了某个分支用于跟踪远程仓库的分支,可以使用$ git pull命令自动抓去数据下来,并自动合并到工作目录。实际上,使用$ git clone命令克隆的远程仓库就是跟踪了分支,可以直接使用$ git pull跟新到本地工作目录。
推送更新去远程仓库:$ git push [remote-name] [brance-name]。如果是clone下来的分支,可以使用默认的名称$ git push origin master。
查看远程仓库信息:$ git remote show [remote-name]
远程仓库的重命名:$ git remote rename [old_name] [new_name]重命名后的本地分支名同样也会跟着变化。
远程仓库的删除:$ git remote rm [remote-name]
《git理解完全手册.zh》P35未完待续……
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/2459.html