Git

git（note=no，音频）是一个分散式版本控制软件，最初由林纳斯·托瓦兹创作，于2005年以GPL授权条款释出。最初目的是为了更好地管理Linux核心开发而设计。应注意的是，这与GNU Interactive Tools（一个类似界面的文件管理器）不同。
git最初的开发动力来自于BitKeeper和Monotone。git最初只是作为一个可以被其他前端（比如Cogito或Stgit）包装的后端而开发的，但后来git内核已经成熟到可以独立地用作版本控制。很多被广泛使用的软体专案都使用 git 进行版本控制，其中包括 Linux 核心、X.Org服务器和OLPC内核等项目的开发流程。

**历史**
自2002年开始，林纳斯·托瓦兹（Linus Torvalds）决定使用BitKeeper作为Linux内核主要的版本控制系统用以维护程式码。因为BitKeeper为专有软件，这个决定在社群中长期遭受质疑。在Linux社群中，特别是理查德·斯托曼与自由软体基金会的成员，主张应该使用开放原始码的软体来作为Linux核心的版本控制系统。林纳斯·托瓦兹曾考虑过采用现成软体作为版本控制系统（例如Monotone），但这些软体都存在一些问题，特别是效能不佳。现成的方案，如CVS的架构，受到林纳斯·托瓦兹的批评。
2005年，安德鲁·垂鸠（Andrew Tridgell）写了一个简单程式，可以连接BitKeeper的储存库，BitKeeper著作权拥有者拉里·麦沃伊认为安德鲁·垂鸠对BitKeeper内部使用的协议进行逆向工程，决定收回无偿使用BitKeeper的授权。Linux内核开发团队与BitMover公司进行磋商，但无法解决他们之间的歧见。林纳斯·托瓦兹决定自行开发版本控制系统替代BitKeeper，以十天的时间编写出git第一个版本。

**命名**
林纳斯·托瓦兹讽刺地嘲笑git这个名字（在英式英语俚语中表示「不愉快的人」）
源代码的自述文件进一步阐述了：

**版本**

**主要功能**
git是用于Linux内核开发的版本控制工具。与CVS、Subversion一类的集中式版本控制工具不同，它采用了分布式版本库的作法，不需要服务器端软件，就可以运作版本控制，使得源代码的发布和交流极其方便。git的速度很快，这对于诸如Linux内核这样的大项目来说自然很重要。git最为出色的是它的合并追踪（merge tracing）能力。
实际上Linux内核开发团队决定开始开发和使用git来作为内核开发的版本控制系统的时候，世界上开源社群的反对声音不少，最大的理由是git太艰涩难懂，从git的内部工作机制来说，的确是这样。但是随着开发的深入，git的正常使用都由一些友善的命令来执行，使git变得非常好用。现在，越来越多的著名项目采用git来管理项目开发，例如：wine、等。
作为开源自由原教旨主义项目，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。

**-{zh-cn:库;zh-tw:储存库}-目录**
hooks：存储-{zh-cn:钩子;zh-tw:hook}-的文件夹
*logs：存储日志的文件夹
*refs：存储指向各个分支的指标（SHA-1标识）文件
*objects：存放git对象
*config：存放各种-{zh-cn:设置文档;zh-tw:组态档}-
*HEAD：指向当前所在分支的指标文件路径，一般指向refs下的某文件

**数据结构**
Git中的数据流与存储级别
git有两种数据结构：可变的索引（index、stage或cache）用于缓冲工作目录信息与下一次提交的版本信息；不变的、仅追加的对象数据库。
对象数据库包含4类对象：
*blob （-{zh-cn:二进制大对象;zh-tw:二进位大型物件}-）是使用zlib压缩算法对一个文件的内容压缩后的结果。Blobs没有保存文件名、时间戳或其他元数据。git将其存储在位于隐藏的.git/objects文件夹中。文件的名称为使用SHA-1哈希函数对原文件内容生成的哈希值。这些对象文件称为Blob，每次将新文件添加到存储库时会创建Blob对象。
*tree对象对应于文件目录。包含文件名列表以及文件的类型比特（包含-{zh-cn:许可权;zh-tw:许可权}-post-text=此处许可权具体指涉的是什么概念）、到blob（对应于文件）或tree对象的引用。tree对象是源树（source tree）的快照。用-{zh-cn:默克尔树;zh-tw:杂凑树}--{zh-cn:实现;zh-tw:实作}-。
*commit对象链接tree对象在一起而成为history，包含顶层源目录的tree对象名字、一个时间戳、log信息、0个或多个父commit对象的名字。用于保存特定版本的树型文件夹结构以及提交作者，电子邮件地址，日期和描述性提交消息。
*tag对象是一个容器，包含了到另一个对象的引用，也可以增加关于另外对象的元数据。通常它保存需要追溯的特定版本数据的一个commit对象的数字签名。
以上4类的对象用其内容的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：
某些操作（例如，将提交推送到远程存储库，存储太多对象或手动运行git的垃圾收集命令）可能会导致git将对象重新打包为打包文件，在打包过程中，采用反向差异并进行压缩以消除多余的内容并减小尺寸。该过程将生成包含对象内容的.pack文件，每个文件都有一个对应的.idx索引文件，其中包含对打包对象及其在打包文件中位置的引用。当将分支推送到远程存储库或从远程存储库拉出分支时，这些打包文件将通过网络传输。提取或获取分支时，将打包文件解压缩以在对象存储库中创建松散对象。

**移植性**
在Windows平台上有msysgit与TortoiseGit可资利用。TortoiseGit还提供有GUI。
git也提供Windows版本下载。
Visual Studio 自 2013 版本开始内置 git 功能。

**GIT GUI客户端**
 GitHub Desktop：可用于第三方git仓库网站- Git for Windows- TortoiseGit- SourceTree- GitEye

**使用**

**使用git的专案**
有不少的专案目前都使用git：- Amarok- Android- Arch Linux- Btrfs- Clojure- Debian- Digg- DragonFly BSD- Drupal- Fedora- FFmpeg - Freenet- git- GIMP- GNOME- GStreamer- gThumb- GTK+- Hurd- jQuery- LilyPond (music typesetting)- Linux kernel- Linux Mint- LMMS Music Production Software - Maemo- MeeGo- One Laptop Per Child (OLPC)- OpenFOAM- openSUSE- Perl- PHP- phpBB- PostgreSQL- Prototype JavaScript框架- Qt- Reddit- rsync- Ruby on Rails- Samba- Sugar (用户界面)- VLC- Wine- Xiph- X.org Server- x264- YUI- NOJ

**支持git的源码存取服务**
以下是部分知名的支持git的源码存取服务：- Bitbucket- CodePlex（已于2017年12月15日起关闭）- GitHub- GNU Savannah- Google Code- JavaForge-  Pikacode- SourceForge-  码云 Gitee date=20210201025217 -  CSDN CODE-  Coding date=20210202144136 - GitLab-  GitCode 

**参见**
 分布式版本控制- Gitee- 代码库- 仓库 (版本控制)- GitHub- GitLab- Gitea

**参考文献**

**外部链接**
 git官方网站- git快速入门- git Man Pagedate=20081025105540 - git用户手册 date=20180305063745 - git Community Book- 使用git管理源代码 date=20190629212730 - git# (gitSharp) date=20200817180900 - GNU Interactive Tools date=20210130135718 - git从入门到精通P- 连猴子都能懂的Git入门指南 date=20170722050211