Git

git（g）是一個分散式版本控制軟體，最初由林納斯·托瓦茲創作，於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這個名字（在英式英語俚語中表示「不愉快的人」）

源代碼的自述文件進一步闡述了：

The name "git" was given by Linus Torvalds when he wrote the very first version. He described the tool as "the stupid content tracker" and the name as (depending on your way):

- random three-letter combination that is pronounceable, and not actually used by any common UNIX command. The fact that it is a mispronunciation of "get" may or may not be relevant.
- "global information tracker": you're in a good mood, and it actually works for you. Angels sing, and a light suddenly fills the room.
- stupid. contemptible and despicable. simple. Take your pick from the dictionary of slang.

林納斯·托瓦茲在編寫第一個版本時就使用了「git」這個名稱。他將工具描述為「愚蠢的內容跟蹤器」，並將其描述為（取決於您的方式）：

- 可以發音唸出的隨機三個字母組合，而且並未被實際用在任何 UNIX 指令上。它是「get」的錯誤發音，這點可能相關也可能無關。
- 「全球資訊跟蹤器」：您的心情不錯，對你而言它也確實說得通。天使唱歌，房間突然充滿光明。
- 愚蠢的。鄙視和卑鄙的。簡單。從俚語字典中選擇。

### 版本

版本｜最初發布日期｜最新修訂版本｜最新修訂版本發布日期

o｜2005-07-11｜0.99.9n｜2005-12-15

o｜2005-12-21｜1.0.13｜2006-01-27

o｜2006-01-08｜1.1.6｜2006-01-30

o｜2006-02-12｜1.2.6｜2006-04-08

o｜2006-04-18｜1.3.3｜2006-05-16

o｜2006-06-10｜1.4.4.5｜2008-07-16

o｜2007-02-14｜1.5.6.6｜2008-12-17

o｜2008-08-17｜1.6.6.3｜2010-12-15

o｜2010-02-13｜1.7.12.4｜2012-10-17

o｜2012-10-21｜1.8.5.6｜2014-12-17

o｜2014-02-14｜1.9.5｜2014-12-17

o｜2014-05-28｜2.0.5｜2014-12-17

o｜2014-08-16｜2.1.4｜2014-12-17

o｜2014-11-26｜2.2.3｜2015-09-04

o｜2015-02-05｜2.3.10｜2015-09-29

o｜2015-04-30｜2.4.12｜2017-05-05

o｜2015-07-27｜2.5.6｜2017-05-05

o｜2015-09-28｜2.6.7｜2017-05-05

o｜2015-10-04｜2.7.6｜2017-07-30

o｜2016-03-28｜2.8.6｜2017-07-30

o｜2016-06-13｜2.9.5｜2017-07-30

o｜2016-09-02｜2.10.5｜2017-09-22

o｜2016-11-29｜2.11.4｜2017-09-22

o｜2017-02-24｜2.12.5｜2017-09-22

o｜2017-05-10｜2.13.7｜2018-05-22

o｜2017-08-04｜2.14.5｜2018-09-27

o｜2017-10-30｜2.15.3｜2018-09-27

o｜2018-01-17｜2.16.5｜2018-09-27

2018-04-02｜2.17.5｜2018-04-19

2018-06-21｜2.18.4｜2020-04-19

2018-09-10｜2.19.5｜2020-04-19

2018-12-09｜2.20.4｜2020-04-19

2019-02-24｜2.21.3｜2020-04-19

2019-06-07｜2.22.4｜2020-04-19

2019-08-16｜2.23.3｜2020-04-19

2019-11-04｜2.24.3｜2020-04-19

2020-01-13｜2.25.4｜2020-04-19

2020-03-23｜2.26.2｜2020-04-19

2020-06-01｜2.27.0｜2020-06-01

2020-07-27｜2.28.0｜2020-07-27

2020-10-19｜2.29.2｜2020-10-29

2020-12-27｜2.30.0｜2020-12-27

2021-03-15｜2.31.1｜2021-04-02

2021-06-06｜2.32.0｜2021-06-06

2021-08-16｜2.33.2｜2022-03-23

2022-01-24｜2.35.0｜2022-01-24

2022-04-18｜2.36.0｜2022-04-18

2022-06-27｜2.37.0｜2022-06-27

2022-10-02｜2.38.2｜2022-12-11

2022-12-12｜2.39.0｜2022-12-12

2023-03-12｜2.40.0｜2023-03-12

2023-06-01｜2.41.0｜2023-06-01

2023-08-21｜2.42.1｜2023-11-02

2023-01-20｜2.43.2｜2024-02-13

2024-02-23｜2.44.0｜2024-02-23

c｜2024-04-29｜2.45.0｜2024-04-29

l

## 主要功能

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。

## 儲存庫目錄

- hooks：存儲hook的文件夾
- logs：存儲日誌的文件夾
- refs：存儲指向各個分支的指標（SHA-1標識）文件
- objects：存放git對象
- config：存放各種組態檔
- HEAD：指向當前所在分支的指標文件路徑，一般指向refs下的某文件

## 數據結構

<image>

git有兩種數據結構：可變的索引（index、stage或cache）用於緩衝工作目錄資訊與下一次提交的版本資訊；不變的、僅追加的對象資料庫。

對象資料庫包含4類對象：

- blob （二進位大型物件）是使用zlib壓縮演算法對一個文件的內容壓縮後的結果。Blobs沒有保存文件名、時間戳或其他元數據。git將其存儲在位於隱藏的.git/objects文件夾中。文件的名稱為使用SHA-1哈希函數對原文件內容生成的哈希值。這些對象文件稱為Blob，每次將新文件添加到存儲庫時會創建Blob對象。
- tree對象對應於文件目錄。包含文件名列表以及文件的類型比特（包含許可權）、到blob（對應於文件）或tree對象的引用。tree對象是源樹（source tree）的快照。用雜湊樹實作。
- 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命名空間等

某些操作（例如，將提交推送到遠程存儲庫，存儲太多對象或手動運行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
- Codeberg
- GNU Savannah
- Google Code
- JavaForge
- Pikacode
- SourceForge
- 碼雲 Gitee
- CSDN CODE
- Coding
- GitLab
- GitCode

## 基本資料

- 日語原文：git
- 作者：林納斯·托瓦茲
- 開發者：濱野純、林納斯·托瓦茲
- 發行日期：2005年4月7日
- 程式語言：C、Perl、sh、Tcl
- 作業系統：POSIX, Windows
- 類型：版本控制
- 許可協議：GNU通用公共許可證 第二版，GNU寬通用公共許可證 2.1版