Git简介(from wiki)
git(/ɡɪt/)是一个分布式版本控制软件,最初由林纳斯·托瓦兹(Linus Torvalds)创作,于2005年以GPL发布。最初目的是为更好地管理Linux内核开发而设计。应注意的是,这与GNU Interactive Tools(一个类似Norton Commander界面的文件管理器)有所不同。
git最初的开发动力来自于BitKeeper和Monotone。git最初只是作为一个可以被其他前端(比如Cogito或Stgit)包装的后端而开发的,但后来git内核已经成熟到可以独立地用作版本控制。很多著名的软件都使用git进行版本控制,其中包括Linux内核、X.Org服务器和OLPC内核等项目的开发流程。
一、命名来源
林纳斯·托瓦兹自嘲地取了这个名字“git”,该词源自英国俚语,意思大约是“混账”。
“I’m an egotistical bastard, and I name all my projects after myself. First Linux, now git.”git的官方wiki也给出了多种关于这个名字的解释。
二、历史
自2002年开始,林纳斯·托瓦兹决定使用BitKeeper作为Linux内核主要的版本控制系统用以维护代码。因为BitKeeper为专有软件,这个决定在社区中长期遭受质疑。在Linux社区中,特别是理查德·斯托曼与自由软件基金会的成员,主张应该使用开放源代码的软件来作为Linux核心的版本控制系统。林纳斯·托瓦兹曾考虑过采用现成软件作为版本控制系统(例如Monotone),但这些软件都存在一些问题,特别是性能不佳。现成的方案,如CVS的架构,受到林纳斯·托瓦兹的批评。
2005年,安德鲁·垂鸠写了一个简单程序,可以连接BitKeeper的存储库,BitKeeper著作权拥有者拉里·麦沃伊认为安德鲁·垂鸠对BitKeeper内部使用的协议进行逆向工程,决定收回无偿使用BitKeeper的授权。Linux内核开发团队与BitMover公司进行磋商,但无法解决他们之间的歧见。林纳斯·托瓦兹决定自行开发版本控制系统替代BitKeeper,以十天的时间,编写出第一个git版本。
三、主要功能
git是用于Linux内核开发的版本控制工具。与CVS、Subversion一类的集中式版本控制工具不同,它采用了分布式版本库的作法,不需要服务器端软件,就可以运作版本控制,使得源代码的发布和交流极其方便。git的速度很快,这对于诸如Linux内核这样的大项目来说自然很重要。git最为出色的是它的合并追踪(merge tracing)能力。
实际上内核开发团队决定开始开发和使用git来作为内核开发的版本控制系统的时候,世界上开源社区的反对声音不少,最大的理由是git太艰涩难懂,从git的内部工作机制来说,的确是这样。但是随着开发的深入,git的正常使用都由一些友善的命令来执行,使git变得非常好用。现在,越来越多的著名项目采用git来管理项目开发,例如:wine、U-boot等。
作为开源自由原教旨主义项目,git没有对版本库的浏览和修改做任何的权限限制,通过其他工具也可以达到有限的权限控制,比如:gitosis、CodeBeamer MR。原本git的使用范围只适用于Linux/Unix平台,但在Windows平台下的使用也日渐成熟,这主要归功于Cygwin、msysgit环境,以及TortoiseGit这样易用的GUI工具。git的源代码中也已经加入了对Cygwin与MinGW编译环境的支持且逐渐完善,为Windows用户带来福音。
四、实现原理
git和其他版本控制系统(如CVS)有不少的差别,git本身关心文件的整体性是否有改变,但多数的版本控制系统如CVS或Subversion系统则在乎文件内容的差异。git拒绝保持每个文件的版本修订关系。因此查看一个文件的历史需要遍历各个history快照;git隐式处理文件更名,即同名文件默认为其前身,如果没有同名文件则在前一个版本中搜索具有类似内容的文件。
git更像一个文件系统,直接在本机上获取数据,不必连接到主机端获取数据。 每个开发者都可有全部开发历史的本地副本,changes从这种本地repository复制给其他开发者。这些changes作为新增的开发分支被导入,可以与本地开发分支合并。
分支是非常轻量级的,一个分支仅是对一个commit的引用。
git是用C语言开发的,以追求最高的性能。git自动完成垃圾回收,也可以用命令git gc –prune直接调用。
git存储每个新创建的object作为一个单独文件。为了压缩存储空间占用, packs操作把很多文件(启发式类似名字的文件往往具有类似内容)使用差分压缩入一个文件中(packfile),并创建一个对应的索引文件,指明object在packfile中的偏移值。新创建的对象仍然作为单独文件存在。repacks操作非常费时间,git会在空闲时间自动做此操作。也可用命令git gc来直接启动repack。packfile与索引文件都用SHA-1作为校验和并作为文件名。git fsck命令做校验和的完整性验证。
Git服务器典型的TCP 监听端口为9418。
五、库目录
- hooks:存储钩子的文件夹
- logs:存储日志的文件夹
- refs:存储指向各个分支的指针(SHA-1标识)文件
- objects:存放git对象
- config:存放各种设置文档
- HEAD:指向当前所在分支的指针文件路径,一般指向refs下的某文件
六、数据结构
Git有两种数据结构:可变的索引(index或stage或cache)用于缓冲工作目录信息与下一次提交的版本信息;不变的、仅追加的对象数据库。
对象数据库包含4类对象:
- blob (二进制大对象)是一个文件的内容。Blobs没有适当的文件名、时间戳、或其他元数据。一个blob的内部名字是它的内容的hash。
- tree对象等效于目录。包含文件名列表以及文件的类型比特、到blob或tree对象的引用。tree对象是源树(source tree)的快照。用默克树实现。
- commit对象链接tree对象在一起而成为history. 包含顶层源目录的tree对象名字、一个时间戳、log信息、0个或多个父commit对象的名字。
- tag对象是一个容器,包含了到另一个对象的引用,也可以增加关于另外对象的元数据。通常它保存需要追溯的特定版本数据的一个commit对象的数字签名。
每个对象用其内容的SHA-1 hash来标识。对象放入它的hash值得前两个字符标识的目录中,其余hash字符作为这个对象的文件名。
Git数据库中不变引用的对象将会被垃圾回收清除。Git命令可以创建、移动、删除引用。”git show-ref”列出所有引用。某些引用类型:
- heads: 引用一个本地对象,是commit的指针。每个head可以指任意一个这样的指针。可以包含任意数量的heads。而”HEAD”(全部大写),仅仅指的是当前有效的head。默认情况下,在每个仓库下都有一个head,叫做master。
- remotes: 引用远程repository中的一个对象
- stash: 引用一个还没有committed的一个对象
- meta: 例如一个bare repository中的一个配置, 用户权限; refs/meta/config名字空间等
- tags:
七、移植性
在Windows平台上有msysgit与TortoiseGit可资利用。TortoiseGit还提供有GUI。
现在git也提供windows版本下载。
Visual Studio 自 2013 版本开始内置 Git 功能。
八、GIT GUI客户端
- GitHub Desktop:可用于第三方Git仓库网站
- Git for Windows
- TortoiseGit
- SourceTree
- GitEye
九、使用git的项目
1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|
Amarok | Android | Arch Linux | Aquamacs Emacs | BlueZ |
Btrfs | Clojure | CakePHP | Debian | Digg |
DragonFly BSD | Drupal | Elinks | Fedora | FFmpeg |
Freenet | git | GIMPGNOME | GPM | GStreamer |
gThumb | GTK+ | Hurd | jQuery | Laika (EHR testing framework) |
LilyPond (music typesetting) | Linux kernel | Linux Mint | LMMS Music Production Software | Maemo |
MeeGo | Merb | MooTools | One Laptop Per Child (OLPC) | OpenFOAM |
openSUSE | Perl | PHP | phpBB | PostgreSQL |
Prototype.js | Qt | rsync | Ruby on Rails | |
Samba | SproutCore | Sugar | SWI-Prolog | VLC |
Wine | Xiph | X.org Server | x264 | YUI |
十、Git 与 SVN 区别
GIT不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。
Git 与 SVN 区别点:
- GIT是分布式的,SVN不是:这是GIT和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别。
- GIT把内容按元数据方式存储,而SVN是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn,.cvs等的文件夹里。
- GIT分支和SVN的分支不同:分支在SVN中一点不特别,就是版本库中的另外的一个目录。
- GIT没有一个全局的版本号,而SVN有:目前为止这是跟SVN相比GIT缺少的最大的一个特征。
- GIT的内容完整性要优于SVN:GIT的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。