文章 > zhaoqi > 文章详情
Git详细教程
Small  zhaoqi  发表于 2年前  来自话题 #敏捷#  · 

12461 浏览
摘要:Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。


Git基础


若是理解了 Git 的思想和基本工作原理,用起来就会知其所以然,游刃有余。 下面就从它的基本思想和工作原理讲起:


直接记录快照,而非差异比较


Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。这类系统 (CVS,Subversion,Perforce,Bazaar 等等)每次记录有哪些文件作了更新,以及都更新了哪些行的什么内容,请看图 1


1 其他系统在每个版本中记录着各个文件的具体差异

Git 并不保存这些前后变化的差异数据。实际上,Git 更像是把变化的文件作快照后,记录在一个微型的文件系统中。每次提交更新时,它会纵览一遍所有文件的指纹信息并对文件作一快照,然后保存一个指向这次快照 的索引。为提高性能,若文件没有变化,Git 不会再次保存,而只对上次保存的快照作一链接。Git 的工作方式就像图 2 所示。



2 Git 保存每次更新时的照文件快(和图一进行对比)

这是 Git 同其他系统的重要区别。

近乎所有操作都是本地执行


在 Git 中的绝大多数操作都只需要访问本地文件和资源,不用连网。因为 Git 在本地磁盘上就保存着所有当前项目的历史更新,所以处理起来速度飞快。

举个例子,如果要浏览项目的历史更新摘要,Git 不用跑到外面的服务器上去取数据回来,而直接从本地数据库读取后展示给你看。所以任何时候你都可以马上翻阅,无需等待。如果想要看当前版本的文件和一个月 前的版本之间有何差异,Git 会取出一个月前的快照和当前文件作一次差异运算,而不用请求远程服务器来做这件事,或是把老版本的文件拉到本地来作比较。

用 Git 的话,就算你在飞机或者火车上,都可以非常愉快地频繁提交更新,等到了有网络的时候再上传到远程仓库。


时刻保持数据完整性


在保存到 Git 之前,所有数据都要进行内容的校验和(checksum)计算,并将此结果作为数据的唯一标识和索引。换句话说,不可能在你修改了文件或目录之后,Git 一无所知。这项特性作为 Git 的设计哲学,建在整体架构的最底层。所以如果文件在传输时变得不完整,或者磁盘损坏导致文件数据缺失,Git 都能立即察觉。

Git 使用 SHA-1 算法计算数据的校验和,通过对文件的内容或目录的结构计算出一个 SHA-1 哈希值,作为指纹字符串。该字串由 40 个十六进制字符(0-9 及 a-f)组成,看起来就像是:

24b9da6552252987aa493b52f8696cd6d3b00373

Git 的工作完全依赖于这类指纹字串,所以你会经常看到这样的哈希值。实际上,所有保存在 Git 数据库中的东西都是用此哈希值来作索引的,而不是靠文件名。


文件的三种状态


好,现在请注意,接下来要讲的概念非常重要。对于任何一个文件,在 Git 内都只有三种状态:已提交(committed),已修改(modified)和已暂存(staged)。已提交表示该文件已经被安全地保存在本地数据库 中了;已修改表示修改了某个文件,但还没有提交保存;已暂存表示把已修改的文件放在下次提交时要保存的清单中。

由此我们看到 Git 管理项目时,文件流转的三个工作区域:Git 的工作目录,暂存区域,以及本地仓库。如图 3:



3 工作目录,暂存区域,以及本地仓库

每个项目都有一个 Git 目录(译注:如果 git clone 出来的话,就是其中 .git 的目录;如果 git clone --bare 的话,新建的目录本身就是 Git 目录),它是 Git 用来保存元数据和对象数据库的地方。该目录非常重要,每次克隆镜像仓库的时候,实际拷贝的就是这个目录里面的数据。

从项目中取出某个版本的所有文件和目录,用以开始后续工作的叫做工作目录。这些文件实际上都是从 Git 目录中的压缩对象数据库中提取出来的,接下来就可以在工作目录中对这些文件进行编辑。

所谓的暂存区域只不过是个简单的文件,一般都放在 Git 目录中。有时候人们会把这个文件叫做索引文件,不过标准说法还是叫暂存区域。


基本的 Git 工作流程如下:

1. 在工作目录中修改某些文件。

2. 对修改后的文件进行快照,然后保存到暂存区域。

3. 提交更新,将保存在暂存区域的文件快照永久转储到 Git 目录中。

所以,我们可以从文件所处的位置来判断状态:如果是 Git 目录中保存着的特定版本文件,就属于已提交状态;如果作了修改并已放入暂存区域,就属于已暂存状态;如果自上次取出后,作了修改但还没有放到暂存区域,就是已修改状态。


安装 Git


服务器端的安装

Win2003 服务器端的安装请参考: http://www.codeproject.com/Articles/296398/Step-by-Step-Setup-Git-Server-on-Windows-with-CopS

注:因为我们用egit,安照步骤做到3、 Config CopSSH with Git path.就可以了。


Egit安装(当作客户端)

注意:egit插件必须安装在Eclipse3.7以上版本

http://download.eclipse.org/egit/updates/

或者使用Eclipse Marketplace,搜索EGit

通过视图查看插件是否安装成功

Window > show view > other 搜索 git 出现如图所示。



Egit的 使用说明 (Eclipse3.7 以上版本才能使用此插件 )


使用egit首先需要 配置个人信息,最重要的是user.name和user.email

。用于提交代码时使用。

Preferences>Team>Git>configuration:点击Add Enty添加user.mail和user.name如图:


创建git仓库


在服务器端用egit创建一个git仓库(当作git服务器,)。

注:这里因为做Demo。我将项目HelloWorld作为git库。实际中都是项目的父目录作为git库。

首先,创建一个HelloWorld项目。在此项目下建一个HelloWorld.java 如图。


其次,选中项目右击 team > share project


选中Git ,Next

下一步,创建服务器端git仓库。


点Finish 创建完成。

现在,我们在服务器段就有了一个git仓库。

此时,package explore中的项目如图所示


“?”表示此文件处于未被跟踪状态,也就是属于不受git监控的文件。

(注:以后会提到egit中各个图标的含义)

选中HelloWorld.java 右击。 T eam > commit


点击 Commit。我们就把上图中status选中的文件提交到本地git库中了。这些文件从此受git的版本监控了。并且提交注释为version1.0(这个以后用到,当作状态标记)。

此时,来看看git repositories视图:

这个就是我们在服务器上的git仓库的结构。


C lone remote git


客户端Eclipse上,打开git Repositories视图。点击 . clone a git Repository.


N ext.我们会看到服务器端git库唯一的分支master出现了。


N ext,


F inish. 我们的clone完成了。现在在自己的工作空间里存在了在服务器端建的HelloWorld项目。


修改文件commit


当我们修改HelloWorld.java的时候。文件状态会发生改变


选中修改过的文件。右击 Team > commit .提交时注释信息为“version1.1”。提交完成后。git状态如图


C ommit:当执行Team > Commit 时。不管有没有选中更改的文件。所有更改的文件都会提交到本地的git库中。

push:将本地git库中的更改提交到远程的git库。

所以,我们需要将客户端的更改push到服务端。 选中带“箭头”的项目 Team > push to upstream 。等完成之后,再看一下当地的git Repositories 仓库。


这样,我们的更改就提交到服务器上了。 总结一下提交更改,需要两部:commit到本地git 库,push到远程git库。


解决冲突


准备:我用另外一个egit客户端client2对HelloWorld.java进行了修改,并且已经提交到了远程服务器,注释信息为“version1.2”。

当我们在自己的客户端修改HelloWorld.java后。commit到本地git库,push到远程git库时。出现如下图问题,你是不能push到远程服务器的。


(non-fast-forward )这个问题说明有人在你之前更改了这个文件,你需要 从远程仓库pull到最新版本,merge后再push。

首先,pull到最新版本:

选中修改的项目team > pull 会将远程的修改pull到本地git库。如图:


点ok。你会发现工作空间的项目出现冲突的标志。


此时,选择冲突的文件HelloWorld.java右击,Team > merge tool .


选则第二项,Ok。


根据比较修改左边的文件,也就是你工作空间中的文件。解决完冲突之后。保存。如图状态。


现在你可以提交这个文件了。选中HelloWorld.java 右击team > add to index .

此时工作空间中的图标有所变化。


当出现灰色的雪花符号时,你就可以 进行提交并 push 到服务器端。

commit 状态


之后,push


点ok,我们完成了一次解决冲突的过程。

总结一下:遇到冲突,需要经过pull,merge,add to index,commit,push五步。


H istory视图


选中文件。 T eam > show in history


这个视图可以看出我们对这个文件做了几次修改。几个客户端对这个文件进行了修改。

上图显示有两条竖线,所以有两个客户端对这个文件进行了修改,左边的那条线是我们进行的修改,并commit了三次。 (version1.4 提交是为了让这条线更清楚,后来我加的。)


添加新文件


SecondFile.java是我新建的类,“?”表示这个文件未受git库版本监控。要想加入监控:选中这个文件,右击 team > add to index. 之后commit。

Sychronize


在开发之前你可以先同步一下本地的git库,避免大量的冲突。

选中项目,右击team > Synchronize Workspace ,之后查看 Sychronize 视图,如图


P ush to upstream 和 remote > push 比较


这两个都是push更改到远程git库。但是push to upstream 提交时有相对应的远程分支,直接提交就可以。而 push 可以允许你选择提交的分支,如图:


M erge 和 rebase


可以参考 http://blog.csdn.net/luckarecs/article/details/7427605 中的Merge和rebase 的比较。说的比较详细。


问题总结:


1、 当push到服务器时,如下图问题出现时,你是不能push到远程服务器的。


举个例子: 比如A从远程仓库拿到代码后,对文件f进行了修改。然后push到中心仓库。

B在A之前就拿到了远程仓库的代码,在A push成功之后也对f文件进行了修改。这个时候B也运行push命令推送代码。这时,就会出现 (non-fast-forward )这个问题。

解决办法 : 需要先从远程仓库pull到最新版本,merge后再push。


Egit 图标说明(官方英文版)


These are the default decorations:

Image:02-IconDecorations.png


dirty (folder) - At least one file below the folder is dirty; that means that it has changes in the working tree that are neither in the index nor in the repository.

tracked - The resource is known to the Git repository and hence under version control.

untracked - The resource is not known to the Git repository and will not be version controlled until it is explicitly added.

ignored - The resource is ignored by the Git team provider. The preference settings under Team > Ignored Resources , "derived" flag and settings from .gitignore files are taken into account.

dirty - The resource has changes in the working tree that are neither in the index nor in the repository.

staged - The resource has changes which have been added to the index. Note that adding changes to the index is currently possible only in the commit dialog via the context menu of a resource.

partially-staged - The resource has changes which are added to the index and additional changes in the working tree that neither reached the index nor have been committed to the repository.

added - The resource has not yet reached any commit in the repository but has been freshly added to the Git repository in order to be tracked in future.

removed - The resource is staged for removal from the Git repository.

conflict - A merge conflict exists for the file.

assume-valid - The resource has the "assume unchanged" flag. This means that Git stops checking the working tree files for possible modifications, so you need to manually unset the bit to tell Git when you change the working tree file.


需要 后方可回复
如果没有账号可以 一个帐号。

文章作者

Normal
回答数 0 · 文章数 2

该作者的其他文章

文档与知识库

产品官方文档和知识库
提供EOS、BPS的文档在线阅读以及超过2073个咨询故障和800+知识点。

反馈与阅读帮助

意见反馈  ·  阅读帮助