git(/ɡɪt/[3],ⓘ)是一個分散式版本控制軟件,最初由林納斯·托瓦茲創作,於2005年以GPL特許條款釋出。最初目的是為了更好地管理Linux核心開發而設計。應注意的是,這與GNU Interactive Tools[4](一個類似Norton Commander介面的檔案管理器)不同。
git最初的開發動力來自於BitKeeper和Monotone[5][6]。git最初只是作為一個可以被其他前端(比如Cogito或Stgit[7])包裝的後端而開發的,但後來git核心已經成熟到可以獨立地用作版本控制[8]。很多被廣泛使用的軟件專案都使用 git 進行版本控制[9],其中包括 Linux 核心、X.Org伺服器和OLPC核心等專案的開發流程[10]。
歷史
自2002年開始,林納斯·托瓦茲(Linus Torvalds)決定使用BitKeeper作為Linux內核主要的版本控制系統用以維護程式碼。因為BitKeeper為專有軟件,這個決定在社群中長期遭受質疑。在Linux社群中,特別是理查德·斯托曼與自由軟件基金會的成員,主張應該使用開放原始碼的軟件來作為Linux核心的版本控制系統。林納斯·托瓦茲曾考慮過採用現成軟件作為版本控制系統(例如Monotone),但這些軟件都存在一些問題,特別是效能不佳。現成的方案,如CVS的架構,受到林納斯·托瓦茲的批評[11]。
2005年,安德魯·垂鳩(Andrew Tridgell)寫了一個簡單程式,可以連接BitKeeper的儲存庫,BitKeeper著作權擁有者拉里·麥沃伊認為安德魯·垂鳩對BitKeeper內部使用的協定進行逆向工程,決定收回無償使用BitKeeper的特許。Linux內核開發團隊與BitMover公司進行磋商,但無法解決他們之間的歧見。林納斯·托瓦茲決定自行開發版本控制系統替代BitKeeper,以十天的時間編寫出git第一個版本[12][13]。
林納斯·托瓦茲諷刺地嘲笑git這個名字(在英式英語俚語中表示「不愉快的人」)[14][15][16]
原始碼的讀我檔案進一步闡述了:[17]
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」的錯誤發音,這點可能相關也可能無關。
- 「全球資訊跟蹤器」:您的心情不錯,對你而言它也確實說得通。天使唱歌,房間突然充滿光明。
- 愚蠢的。鄙視和卑鄙的。簡單。從俚語字典中選擇。
版本 | 最初釋出日期 | 最新修訂版本 | 最新修訂版本釋出日期 |
---|---|---|---|
0.99 | 2005-07-11 | 0.99.9n | 2005-12-15 |
1.0 | 2005-12-21 | 1.0.13 | 2006-01-27 |
1.1 | 2006-01-08 | 1.1.6 | 2006-01-30 |
1.2 | 2006-02-12 | 1.2.6 | 2006-04-08 |
1.3 | 2006-04-18 | 1.3.3 | 2006-05-16 |
1.4 | 2006-06-10 | 1.4.4.5 | 2008-07-16 |
1.5 | 2007-02-14 | 1.5.6.6 | 2008-12-17 |
1.6 | 2008-08-17 | 1.6.6.3 | 2010-12-15 |
1.7 | 2010-02-13 | 1.7.12.4 | 2012-10-17 |
1.8 | 2012-10-21 | 1.8.5.6 | 2014-12-17 |
1.9 | 2014-02-14 | 1.9.5 | 2014-12-17 |
2.0 | 2014-05-28 | 2.0.5 | 2014-12-17 |
2.1 | 2014-08-16 | 2.1.4 | 2014-12-17 |
2.2 | 2014-11-26 | 2.2.3 | 2015-09-04 |
2.3 | 2015-02-05 | 2.3.10 | 2015-09-29 |
2.4 | 2015-04-30 | 2.4.12 | 2017-05-05 |
2.5 | 2015-07-27 | 2.5.6 | 2017-05-05 |
2.6 | 2015-09-28 | 2.6.7 | 2017-05-05 |
2.7 | 2015-10-04 | 2.7.6 | 2017-07-30 |
2.8 | 2016-03-28 | 2.8.6 | 2017-07-30 |
2.9 | 2016-06-13 | 2.9.5 | 2017-07-30 |
2.10 | 2016-09-02 | 2.10.5 | 2017-09-22 |
2.11 | 2016-11-29 | 2.11.4 | 2017-09-22 |
2.12 | 2017-02-24 | 2.12.5 | 2017-09-22 |
2.13 | 2017-05-10 | 2.13.7 | 2018-05-22 |
2.14 | 2017-08-04 | 2.14.5 | 2018-09-27 |
2.15 | 2017-10-30 | 2.15.3 | 2018-09-27 |
2.16 | 2018-01-17 | 2.16.5 | 2018-09-27 |
2.17 | 2018-04-02 | 2.17.5 | 2018-04-19 |
2.18 | 2018-06-21 | 2.18.4 | 2020-04-19 |
2.19 | 2018-09-10 | 2.19.5 | 2020-04-19 |
2.20 | 2018-12-09 | 2.20.4 | 2020-04-19 |
2.21 | 2019-02-24 | 2.21.3 | 2020-04-19 |
2.22 | 2019-06-07 | 2.22.4 | 2020-04-19 |
2.23 | 2019-08-16 | 2.23.3 | 2020-04-19 |
2.24 | 2019-11-04 | 2.24.3 | 2020-04-19 |
2.25 | 2020-01-13 | 2.25.4 | 2020-04-19 |
2.26 | 2020-03-23 | 2.26.2 | 2020-04-19 |
2.27 | 2020-06-01 | 2.27.0 | 2020-06-01 |
2.28 | 2020-07-27 | 2.28.0 | 2020-07-27 |
2.29 | 2020-10-19 | 2.29.2 | 2020-10-29 |
2.30 | 2020-12-27 | 2.30.0 | 2020-12-27 |
2.31 | 2021-03-15 | 2.31.1 | 2021-04-02 |
2.32 | 2021-06-06 | 2.32.0 | 2021-06-06 |
2.33 | 2021-08-16 | 2.33.2 | 2022-03-23 |
2.35 | 2022-01-24 | 2.35.0 | 2022-01-24 |
2.36 | 2022-04-18 | 2.36.0 | 2022-04-18 |
2.37 | 2022-06-27 | 2.37.0 | 2022-06-27 |
2.38 | 2022-10-02 | 2.38.2 | 2022-12-11 |
2.39 | 2022-12-12 | 2.39.0 | 2022-12-12 |
2.40 | 2023-03-12 | 2.40.0 | 2023-03-12 |
2.41 | 2023-06-01 | 2.41.0 | 2023-06-01 |
2.42 | 2023-08-21 | 2.42.1 | 2023-11-02 |
2.43 | 2023-01-20 | 2.43.2 | 2024-02-13 |
2.44 | 2024-02-23 | 2.44.0 | 2024-02-23 |
2.45 | 2024-04-29 | 2.45.0 | 2024-04-29 |
格式: 舊版本 舊版本,仍被支援 目前版本 最新的預覽版 |
主要功能
git是用於Linux核心開發的版本控制工具。與CVS、Subversion一類的集中式版本控制工具不同,它採用了分散式版本庫的作法,不需要伺服器端軟件,就可以運作版本控制,使得原始碼的釋出和交流極其方便。git的速度很快,這對於諸如Linux核心這樣的大專案來說自然很重要。git最為出色的是它的合併追蹤(merge tracing)能力。
實際上Linux核心開發團隊決定開始開發和使用git來作為核心開發的版本控制系統的時候,世界上開源社群的反對聲音不少,最大的理由是git太艱澀難懂,從git的內部工作機制來說,的確是這樣。但是隨着開發的深入,git的正常使用都由一些友善的命令來執行,使git變得非常好用。現在,越來越多的著名專案採用git來管理專案開發,例如:wine、U-boot等[18]。
作為開源自由基本教義派專案,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下的某檔案
數據結構
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命名空間等[19]
- tags:
某些操作(例如,將提交推播到遠端儲存庫,儲存太多對象或手動執行git的垃圾收集命令)可能會導致git將對象重新打包為打包檔案,在打包過程中,採用反向差異並進行壓縮以消除多餘的內容並減小尺寸。該過程將生成包含對象內容的.pack檔案,每個檔案都有一個對應的.idx索引檔案,其中包含對打包對象及其在打包檔案中位置的參照。當將分支推播到遠端儲存庫或從遠端儲存庫拉出分支時,這些打包檔案將通過網絡傳輸。提取或取得分支時,將打包檔案解壓縮以在對象儲存庫中建立鬆散對象。
移植性
在Windows平台上有msysgit與TortoiseGit可資利用。TortoiseGit還提供有GUI。
git也提供Windows版本下載。
Visual Studio 自 2013 版本開始內建 git 功能。
GIT GUI用戶端
- GitHub Desktop:可用於第三方git儲存庫網站[20][21]
- Git for Windows[22]
- TortoiseGit
- SourceTree
- GitEye[23]
使用
有不少的專案目前都使用git:[24]
- Amarok[25]
- Android[26]
- Arch Linux
- Aquamacs Emacs
- BlueZ[27]
- Btrfs[28]
- Clojure
- CakePHP
- Debian[29]
- Digg[30]
- DragonFly BSD[31]
- Drupal[32]
- Elinks[33]
- Fedora
- FFmpeg [34]
- Freenet
- git[35]
- GIMP
- GNOME[36][37]
- GPM
- GStreamer[38]
- gThumb[39]
- GTK+[40]
- Hurd[41]
- jQuery[42]
- Laika (EHR testing framework)[43]
- LilyPond (music typesetting)[44]
- Linux kernel
- Linux Mint[45]
- LMMS Music Production Software [46]
- Maemo[47]
- MeeGo[48]
- Merb[49]
- MooTools[50]
- One Laptop Per Child (OLPC)[10]
- OpenFOAM
- openSUSE[51]
- Perl[52]
- PHP[53]
- phpBB[54]
- PostgreSQL
- Prototype JavaScript框架[55]
- Qt[56]
- Reddit[57]
- rsync
- Ruby on Rails[58]
- Samba[59]
- SproutCore[60]
- Sugar (用戶介面)[61]
- SWI-Prolog[62]
- VLC[63]
- Wine[64]
- Xiph[65]
- X.org Server[66]
- x264[63]
- YUI[67]
- NOJ
以下是部分知名的支援git的原始碼存取服務:
參見
參考文獻
外部連結
Wikiwand in your browser!
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.