Git

Git（ギット）は、プログラムのソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システムである。Linuxカーネルのソースコード管理に用いるためにリーナス・トーバルズによって開発され、それ以降ほかの多くのプロジェクトで採用されている。Linuxカーネルのような巨大プロジェクトにも対応できるように、動作速度に重点が置かれている。現在のメンテナンスは濱野純 (Junio C Hamano) が担当している。 Gitでは、各ユーザのワーキングディレクトリに、全履歴を含んだリポジトリの完全な複製が作られる。したがって、ネットワークにアクセスできないなどの理由で中心リポジトリにアクセスできない環境でも、履歴の調査や変更の記録といったほとんどの作業を行うことができる。これが「分散型」と呼ばれる理由である。 Linuxカーネルの開発では、Linux Kernel Mailing Listに投稿される多数のパッチをメンテナーたちがソースコードに適用するという形式が採用されている。これらの作業を効率的に行うため、当初はBitKeeperというバージョン管理システムを用いていたが、このソフトウェアは商用ソフトウェアであった（クライアントはバイナリ版のみ無料で、サーバは商用だがBitMover社の厚意で無料で使えていた）。この状況を快く思わない人々がBitKeeperのクローンを実装したことから、この環境が使えなくなってしまい（BitKeeper#ライセンス問題やBitKeeper#価格変更を参照）、その代替として2005年にGitが開発された。 Linuxカーネルの開発では、巨大なソースコードの集合を扱うため、変更点の抽出やリポジトリ操作ができるかぎり高速にできる必要がある。他の様々なバージョン管理システムをあたったが、満足のいくものがなかったため、Gitではこのような問題も出来る限り解決できるよう、いくつかのアイデアが導入されている（この部分は、他のバージョン管理システムにも同様の機能が導入されるようになった）。 Gitは分散型のソースコード管理システムであるため、リモートサーバ等にある中心リポジトリの完全なコピーを手元（ローカル環境）に作成して、そのローカルリポジトリを使って作業を行う。 一般的な開発スタイルでは、大雑把に言えば、以下のようなステップの繰り返しで作業が行なわれる： リモートサーバ等にある中心リポジトリをローカルに複製する (git clone)。 ローカルでコンテンツの修正・追加・削除を行い、ローカルリポジトリに変更履歴を記録する (git commit)。必要に応じて過去の状態の閲覧や復元などを行う。場合によってはこのステップを何度か繰り返す。 中心リポジトリに加えられた他人による変更をローカルに反映させる (git pull)。他人の変更内容が自分の変更内容と衝突することもある。衝突は、Gitが自動で解決できることもあれば、手動で解決しなければならないこともある (git merge)。 ローカルの変更内容を中心リポジトリに反映させる (git push)。ステップ2.へ戻る。 リポジトリ間の通信 (clone, pull, push) では以下のプロトコルが使用できる。 ローカルファイルシステム SSH git（認証機能なし） HTTP/HTTPS（WebDAV）（pushするためにはWebDAVが必要） FTP/FTPS: ただし、もはや使うべきではないとされている。 以前はrsyncも使用できたが、2.8.0で廃止された。 Gitの設計はBitKeeperとMonotoneが元になっている。元々のGitはローレベルなエンジンとして設計されていたが、これは、他の開発者がCogitoやStGITのようなフロントエンドを容易に開発できるようにすることを目的としていた。現在では、Gitのコア自体もユーザから直接利用できるようになっている。 Gitの設計には、リーナスが大規模プロジェクトのメンテナンスを行った経験や、ファイルシステムのパフォーマンスに関する深い知識、また実用性のあるシステムを短期間に作成しなければならないという差し迫った必要性（BitKeeperを参照）が反映されている。これらの影響は、以下のような形で実装に現れている。 ノンリニアな開発スタイルに対する強力なサポート。Gitではブランチやマージが高速に行える。また、ノンリニアな開発の履歴を可視化・ナビゲートするための専用のツールを同梱している。また、ツリーに対する1回の変更に対して、複数回のマージが発生するという前提を置いているが、これは変更点が複数のレビュアーによってレビューされることを想定しているためである。 分散開発。他の分散型バージョン管理システム（Darcs、BitKeeper、Mercurial、SVK、Bazaar、Monotone）と同様に、Gitでも各々の開発者がリポジトリの完全なコピーをローカルに保持しており、各開発者の行った変更は他のリポジトリにコピーされる。これらの変更は新しい開発用ブランチとしてインポートされる。また、ローカルな開発用ブランチへのマージも可能である。 HTTP、FTP、gitプロトコル（sshを利用したトンネリングも可能）を使用したリポジトリの配布が可能。また、CVSサーバのエミュレーション機能を使用すれば、既存のCVSクライアントやIDEのプラグインからGitリポジトリにアクセスできる。 git-svnを使用すれば、Subversionおよびsvkのリポジトリを直接操作できる。 大きなプロジェクトにおける処理の効率化。Gitは非常に高速かつスケーラブルになるよう記述されている。Mozillaによって行われたパフォーマンステストでは、他のリビジョンコントロールシステムと比較して10倍、処理によっては100倍高速に動作することが示された。 ツールキット化された設計。gitはC言語で書かれたプログラム一式と、それらのラッパーとなる何本かのシェルスクリプトで構成されている。GitをWindowsに移植する過程で、シェルスクリプトのほとんどはC言語で書き直された。しかし、現在でも複数のコンポーネントを繋げることで複雑な処理を容易に行えるような設計になっている。 プラガブルなマージアルゴリズム。Gitでは不完全なマージに対する優れたモデル化が行われている。また、不完全なマージを補完するアルゴリズムも複数存在する。最終的に自動的なマージが行えなかった場合には、ユーザによる編集が必要である旨がユーザに通知される。 ガベージコレクションは行われない。操作を中断したり変更の取り消しを行った場合、データベース中には不要なデータが残ったままになる。これらのデータは操作対象のオブジェクトの履歴に比例して大きくなる。git-gc --pruneコマンドを使用して明示的にガベージコレクションを行うこともできるが、この処理には時間がかかる。 Gitの特徴の一つとして、ディレクトリツリーに対するスナップショットを作成する点が挙げられる。初期のバージョン管理システム（SCCSやRCS）では、個々のファイルを処理の対象としており、直近のバージョンに対して差分符号化を行うことでリポジトリのサイズを縮小することに機能の重点が置かれていた。以降のバージョン管理システムでも、この「プロジェクト内の複数バージョンにまたがって一つのファイルを追跡できる」という概念が継承されていた。 一方、Gitではこのコンセプトを使用していない。その結果として、Gitはソースコードツリー中のファイルのリビジョン間の関係性を記録しなくなっている。これにより、Gitは以下のような特徴をもつようになっている。 プロジェクト全体の変更履歴を調べるよりも、一つのファイルの変更履歴を調べる方が時間がかかる。特定のファイルの変更履歴を取得する場合、Gitはツリーの履歴全体を走査し、各リビジョンでそのファイルに変更があったかどうか調査する必要がある。ただしこの処理手順では、一つのファイルに対しても、任意のファイルの集合に対しても、ほぼ同じ時間で履歴の調査が行える。よく行われる処理としては、例えば「ソースツリー中のあるサブディレクトリと、それに関係するヘッダファイルの調査を行う」といったものがある。 ファイル名の変更を明示的に扱わない。CVSに対してよく挙げられる不満として、ファイルのリネームや移動を行うと変更履歴が途切れてしまう問題がある。これは、変更履歴の識別にファイル名を使用しているためである。CVS以降に開発されたバージョン管理システムの多くでは、管理対象のファイルに対してファイル名より寿命の長い、内部的な名前（inode番号のようなもの）を付与することでこの問題を解決している。一方、Gitではそのような内部名を使用しておらず、その点が長所であるとしている。プログラムのソースコードに対しては、リネームの他にも分割やマージといった処理が行われる。これらの処理を単純にファイルのリネームとして十把一絡げに扱うと、実際にソースコードツリーに対して行われた処理が何であるか不明瞭なまま履歴に記録されてしまう。Gitでは、リネームの検出をスナップショット作成時ではなく履歴のブラウズの際に行うことでこの問題を解決している。（単純に考えれば、リビジョンN中のあるファイルに対して、リビジョンN-1中に同じ名前のファイルがあれば、それが元ファイルと考えられる。しかし、リビジョンN-1中に似たような名前のファイルがない場合もある。この場合Gitは、リビジョンN-1のみに存在し、かつ似たような内容のファイルを検索する。）しかし、この処理は履歴の表示を行う度にCPUに負荷のかかる処理が必要となる。そのため、使用するヒューリスティックを選択するオプションが提供されている。 リポジトリの保存方法については批判もある。 Gitは新しく作成されたオブジェクトを個別のファイルの形で保存する。各ファイルは圧縮されて保存されるが、そうであったとしてもこの方法は記録領域を大量に必要とするため非効率的である。Gitはこの問題を“pack”を使用することで解決している。複数のオブジェクトは一つのファイル（またはネットワークバイトストリーム）の形にパックされ、各pack間で差分圧縮が行われる。packの差分圧縮にはヒューリスティックが用いられる。例えば、同じ名前のファイルは似た内容である可能性が高いものとして処理される。ただし、リポジトリの正確性を保つため、ヒューリスティックに完全に依存することはない。現在のGitでも新しく作成されたオブジェクト（新しく加えられた履歴）はまず単一のファイルとして保存されるため、空間効率を高く保つためには定期的な再パックが要求される。Gitはこの定期的な再パックを自動的に行うが、git gcコマンドを使用することで手動で再パックを行うこともできる。 Gitは以下のマージアルゴリズムを実装している。アルゴリズムはマージ時に選択することができる。 resolve 従来通りの3-wayマージアルゴリズムを使用する。 recursive 3-wayマージの変種を使用する。ブランチのmergeやpullを行う場合のデフォルトである。3-wayマージにおいて共通の祖先が複数ある場合、共通の祖先からのmerge treeを作成し、それをreference treeとして3-wayマージを行う。Linuxカーネル2.6の開発で行われたマージコミットの履歴から、このアルゴリズムを使用するとマージの衝突が少なく、マージ漏れもなかったことが報告されている。さらに、リネームを伴うマージに対しても検出および処理が可能である。 octopus 3つ以上のheadからのマージを行う場合のデフォルトである。 リーナス・トーバルズによれば、 英語のスラングとして、Gitには「バカ」「間抜け」といった類の意味がある。この自虐ネタはもちろん皮肉で、これはリーナスがLinuxの名前を決める際に自身の名前にちなんだ名前を付けるよう強要されたことから来ている。(Linux#名前の由来を参照) Gitのオフィシャルサイトのウィキでは、“Git”という名前に対して他にもいくつかの解釈がなされている。例としてはGlobal Information Trackerなどが挙げられる。 Gitの開発は、Linuxカーネルの開発者の多くがBitKeeperのシステムに対するアクセスを禁止されたことに端を発している（BitKeeper#価格変更を参照）。これは、アンドリュー・トリジェル (Andrew Tridgell) がプロプラエタリなソフトウェアであるBitKeeperのプロトコルをリバースエンジニアリングしたことに対し、BitKeeperの著作者であるラリー・マクボイがこれをライセンス違反であるとして、BitKeeperの無料提供を止めたためである。Linux.conf.au 2005のキーノートにおいて、Tridgellはこのリバースエンジニアリングの手順について説明を行ったが、内容はBitKeeperのサーバの適切なポートにtelnetでアクセスし“help”とタイプするだけという単純なものだった。 リーナスはBitKeeperと同じように使える分散型バージョン管理システムを探していたが、無料のシステムで彼の要求（特に速度面での要求）に適合するものは見つからなかった。リーナスが書いたメールによると、2005年4月7日頃に最初のプロトタイプを作成していたようである。 リーナスは以下のような原則に基づいて設計を行っている。 CVSを「悪い見本」とする。設計上のことで確信が持てない場合は、CVSと逆の決断をする。リーナスは冗談めかして以下のように語っている。 “カーネルメンテナンスの最初の10年間、僕らは文字通りtarボールとパッチを使っていた。CVSよりもずっと優れたソース管理システムさ。僕は営利企業（トランスメタ）でCVSを7年間使わされたことで、CVSを強烈に憎むようになった。CVSを強烈に憎んでいると言う時には、このことも言っておかなくちゃいけないね。観衆の中にSVN (Subversion) のユーザがいるなら、この場から去ったほうがいいかもしれない。僕がCVSを強烈に嫌悪しているということは、僕がSubversionが史上最大の無意味なプロジェクトであると思っていることも意味しているんだ。Subversionのしばらくのスローガンは‘ちゃんとCVSをやる’とかそんなものだったよね。そんなスローガンから始めたら、どこにも辿りつけないよ。CVSをちゃんとやるなんて不可能なのさ。” 分散型の、BitKeeperのようなワークフローをサポートする。 “BitKeeperだけが、「まあ使ってもいいかな」と最初に思わせてくれたSCMだというわけではないけれど、BitkeeperはSCMというものの存在意義と、実際にどう使うことができるのかを教えてくれた。だから、Gitは技術的な観点とかいろんなところでBitkeeperとは随分違うものになっているけど（それはもう一つの設計目標でもある。Bitkeeperのクローンではないことをはっきりさせたかったから）、Gitのワークフローの多くは、Bitkeeperが教えてくれたフローから直接きたものになっているんだ。” データ破壊に対する強力な抑止機能。データ破壊は、偶然によるものと意図的なものの両方を想定している。 非常に高い処理速度。 最初の3つの条件によって、既存のバージョン管理システムはMonotoneを除き全て選に漏れてしまい、4つ目の条件で該当するものがなくなってしまった。そのため、Linuxカーネル2.6.12-rc2のリリース直後に、リーナスは自分で開発を始めた。 Gitの開発は2005年4月3日に開始された。プロジェクトとしてのアナウンスは4月6日に行われ、4月7日にはセルフホスティングされるようになった。4月18日には複数のブランチからのマージが最初に行われた。4月29日にはリーナスの目標としていた処理速度が実現された。Linuxのカーネルツリーにパッチを当てるベンチマークで、初期のGitでは毎秒6.7個のパッチを処理している。6月6日には、GitによるLinuxカーネル2.6.12のリリースが行われた。 BitKeeperからの影響で、リーナスは従来と同じようなアプローチを意図的に避けており、結果としてGitは非常にユニークな設計になっている。技術に長けたユーザがGitを利用できるようになるレベルまではリーナスが開発を行っており、その後、2005年6月26日にはプロジェクトへの主要な貢献者であったJunio C Hamanoにメンテナンスが引き継がれた。Hamanoは2005年12月21日にバージョン1.0のリリースを行い、2009年3月現在も彼がメンテナンスを行っている。 ^ “Git v2.19.1 Release Notes” (2018年9月28日). 2018年10月26日閲覧。 ^ Tech Talk: Linus Torvalds on git (1分30秒の発音) ^ Git - IT用語辞典e-words ^ Git - IT用語辞典 - 日立ソリューションズ ^ 「使い始める-Git略史」『Git Pro』 Git --distributed-is-the-new-centralized ^ a b c d e Scott Chacon. “4.1 Git サーバー - プロトコル”. 2013年1月19日閲覧。 ^ “git-clone(1) Manual Page” (英語). 2017年6月14日閲覧。 “in addition, ftp, and ftps can be used for fetching, but this is inefficient and deprecated; do not use it” ^ “Documentation/RelNotes/2.8.0.txt” (英語). 2017年6月14日閲覧。 “The rsync:// transport has been removed.” ^ Linus Torvalds (2006年5月5日). “Re: [ANNOUNCE] Git wiki”. linux-kernel mailing list.. http://marc.info/?l=git&m=114685143200012 2009年3月3日閲覧。  Gitの元となったプログラムに関する歴史的経緯 ^ Linus Torvalds (2005年4月7日). “Re: Kernel SCM saga”. linux-kernel mailing list.. http://lkml.org/lkml/2005/4/8/9 2009年3月3日閲覧。  ^ Linus Torvalds (2005年4月8日). “Re: Kernel SCM saga”. linux-kernel mailing list.. http://marc.info/?l=linux-kernel&m=111293537202443 2008年2月20日閲覧。  ^ Linus Torvalds (2006年3月23日). “Re: Errors GITtifying GCC and Binutils”. Git mailing list.. http://marc.info/?l=git&m=114314642000462 2009年3月3日閲覧。  ^ Linus Torvalds (2006年10月19日). “Re: VCS comparison table”. Git mailing list.. http://marc.info/?l=git&m=116128307511686 2009年3月3日閲覧。  ^ Stenback, Johnny (2006-11-30), “bzr/hg/git performance”, Jst's Blog, http://weblogs.mozillazine.org/jst/archives/2006/11/vcs_performance.html 2008年2月20日閲覧。 , "git diff"と"bzr diff"のベンチマーク結果の比較。ケースによっては、gitの処理速度はBazzarの100倍以上になる。 ^ Roland Dreier (2006年11月13日). “Oh what a relief it is”. 2009年3月3日閲覧。, "git log"は"svn log"と比較して100倍以上高速だが、これは後者はリモートのサーバにアクセスする必要があるためである。 ^ Linus Torvalds (2006年10月18日). “Re: VCS comparison table”. Git mailing list.. http://marc.info/?l=git&m=116118369005954 2009年3月3日閲覧。 , Gitのスクリプト指向デザインについて ^ iabervon (2005年12月22日). “Git rocks!”. 2009年3月3日閲覧。, Gitを使ったスクリプトの書きやすさに関する賞賛 ^ “Git User's Manual” (2007年8月5日). 2009年3月3日閲覧。 ^ Linus Torvalds (2005年4月10日). “Re: more git updates..”. linux-kernel mailing list.. http://marc.info/?l=linux-kernel&m=111314792424707 2009年3月3日閲覧。  ^ Bruno Haible (2007年2月11日). “how to speed up "git log"?”. Git mailing list.. http://marc.info/?l=git&m=117119479505638 2009年3月3日閲覧。  ^ Linus Torvalds (2006年3月1日). “Re: impure renames / history tracking”. Git mailing list.. http://marc.info/?l=git&m=114123702826251 2009年3月3日閲覧。  ^ Junio C Hamano (2006年3月24日). “Re: Errors GITtifying GCC and Binutils”. Git mailing list.. http://marc.info/?l=git&m=114316047119262 2009年3月3日閲覧。  ^ Junio C Hamano (2006年3月23日). “Re: Errors GITtifying GCC and Binutils”. Git mailing list.. http://marc.info/?l=git&m=114315795227271 2009年3月3日閲覧。  ^ Linus Torvalds (2006年11月28日). “Re: git and bzr”. Git mailing list.. http://marc.info/?l=git&m=116473016012824 2009年3月3日閲覧。 , git-blameコマンドを使用したソースファイル間のコードの移動の調査について ^ Linus Torvalds (2007年7月18日). “git-merge(1)”. 2009年3月4日閲覧。 ^ Linus Torvalds (2007年7月18日). “CrissCrossMerge”. 2009年3月4日閲覧。 ^ “After controversy, Torvalds begins work on git”. InfoWorld. (2005年4月19日). ISSN 0199-6649. http://www.infoworld.com/article/05/04/19/HNtorvaldswork_1.html 2008年2月20日閲覧。.  ^ GitFaq: Why the 'git' name? ^ Jonathan Corbet (2005-04-20), “How Tridge reverse engineered BitKeeper”, Linux Weekly News, http://lwn.net/Articles/132938/ 2009年3月26日閲覧。  ^ Linus Torvalds (2005年4月7日). “Re: Kernel SCM saga..”. linux-kernel mailing list.. http://marc.info/?l=linux-kernel&m=111288700902396 2009年3月26日閲覧。  ^ a b ここでは -mm ツリーメンテナのアンドリュー・モートンを指す。 ^ Linus Torvalds (2005年10月31日). “Re: git versus CVS (versus bk)”. Git mailing list.. http://marc.info/?l=git&m=113072612805233&w=2 2009年3月26日閲覧。  ^ a b c d e f Linus Torvalds (05-03). Google tech talk: Linus Torvalds on git. 該当時間: 02:30. http://www.youtube.com/watch?v=4XpnKHJAok8 2007年5月16日閲覧。  ^ Linus Torvalds (2007年6月10日). “Re: fatal: serious inflate inconsistency”. Git mailing list.. http://marc.info/?l=git&m=118143549107708 2009年3月26日閲覧。  Gitにおけるデータの完全性に関する設計目標に関する概要説明。 ^ a b Linus Torvalds (2007年2月27日). “Re: Trivia: When did git self-host?”. Git mailing list.. http://marc.info/?l=git&m=117254154130732 2009年3月26日閲覧。  ^ Linus Torvalds (2005年4月6日). “Kernel SCM saga..”. linux-kernel mailing list.. http://marc.info/?l=linux-kernel&m=111280216717070 2009年3月26日閲覧。  ^ Linus Torvalds (2005年4月17日). “First ever real kernel git merge!”. Git mailing list.. http://marc.info/?l=git&m=111377572329534 2009年3月26日閲覧。  ^ Matt Mackall (2005年4月29日). “Mercurial 0.4b vs git patchbomb benchmark”. Git mailing list.. http://marc.info/?l=git&m=111475459526688 2009年3月26日閲覧。  ^ Linus Torvalds (2005年6月17日). “Linux 2.6.12”. git-commits-head mailing list.. http://marc.info/?l=git-commits-head&m=111904216911731 2009年3月26日閲覧。  ^ Linus Torvalds (2006年10月20日). “Re: VCS comparison table”. Git mailing list.. http://marc.info/?l=git&m=116129092117475 2009年3月26日閲覧。  Git vs. BitKeeperの議論 ^ Linus Torvalds (2005年7月27日). “Meet the new maintainer...”. Git mailing list.. http://marc.info/?l=git&m=112243466603239 2009年3月26日閲覧。  ^ Junio C Hamano (2005年12月21日). “ANNOUNCE: GIT 1.0.0”. Git mailing list.. http://marc.info/?l=git&m=113515203321888 2009年3月26日閲覧。  GitHub バージョン管理システム arch Bazaar BitKeeper - Git以前にLinuxカーネル開発で使用されていたバージョン管理システム。ライセンス発行に関わる問題によりGitが開発されることとなった。 Concurrent Versions System (CVS) Mercurial - Gitとほぼ同時期に開発が開始された。 Apache Subversion Git - Fast Version Control System - Gitの公式サイト。 Gitの配布ディレクトリ Git for Windows - Windows版gitの配布サイト。 書籍「Pro Git」第2版（英語版マニュアル） 書籍「Pro Git」第2版（日本語訳マニュアル）