Git
| 開発元 | Junio C Hamano, リーナス・トーバルズ |
|---|---|
| 初版 | 2005年12月21日 |
| 最新版 | 1.7.8.4 - 2012年1月18日 [+/-] |
| 対応OS | クロスプラットフォーム |
| 種別 | バージョン管理ソフトウェア |
| ライセンス | GNU General Public License バージョン2 |
| 公式サイト | git-scm.com |
Git(ギット)はプログラムなどのソースコード管理を行う分散型バージョン管理システム。動作速度に重点が置かれている。Linuxカーネルのソースコード管理を目的として、リーナス・トーバルズによって開発された。現在のメンテナンスは濱野純 (Junio C Hamano)が担当している。
Gitではワーキングディレクトリがリポジトリの全ての履歴を含んでいるため、中央サーバへのアクセスが不可能な状態であってもリビジョン間の履歴を調査することができる。
目次 |
[編集] 背景および概要
Linuxカーネルの開発では、Linux Kernel Mailing Listに投稿される多数のパッチをメンテナーたちがソースコードに適用するという形式を採用している。これらの作業を効率的にするため、当初BitKeeperというバージョン管理システムを用いていたが、このソフトウェアは商用ソフトウェア(クライアントはバイナリのみ無料で、サーバは商用だがBitMover社の好意で無料で使えていた)であった。この状況を快く思わない人々がBitKeeperのクローンを実装したことからこの環境が使えなくなってしまい(BitKeeper#ライセンス問題やBitKeeper#価格変更を参照)、その代替として2005年にGitが開発された。
Linuxのカーネルでは、相当量のソースコードを扱うため、変更点の抽出やリポジトリ操作に時間がかかっていては困るという状況になっていた。他の様々なバージョン管理システムをあたったが十分なものがなかった。 そのため、このような問題もできるかぎり解決できるよう、いくつかの案が導入されている(この部分は、他のバージョン管理システムにも同様の機能が導入されるようになった)。
[編集] 名前の由来
gitという名前は、「愚か者」とか「間抜け」とかいう意味のイギリス英語のスラングが由来である[1]。リーナス・トーバルズによれば、
| “ | 僕は自己中心的な奴だから、自分のプロジェクトには自分にちなんだ名前を付けるようにしているんだ。最初はLinuxで、今度はgitだ。 | ” |
この自虐ネタはもちろん皮肉で、これはリーナスがLinuxの名前を決める際に自身の名前にちなんだ名前を付けるよう強要されたことから来ている。(Linux#名前を参照)
GitのオフィシャルサイトのWikiでは、「Git」という名前に対して他にもいくつかの解釈がなされている。例としてはGlobal Information Trackerなどが挙げられる[2]。
[編集] 特徴
Gitは、arch等にも採用される分散リポジトリをサポートしており、
- 中央リポジトリからコピーする
- コピーしたリポジトリを編集し、コンテンツの修正、追加、削除を行う
- ローカルへコミットする
- 中央リポジトリへ変更内容を反映させる
という形で行われる。
リポジトリへのアクセスは
- ローカル
- WebDAV
- Git 独自プロトコル
- rsync
- ssh
を用いる(書き込みができるのはローカル、WebDAV および ssh)。
[編集] 設計
Gitの設計はBitKeeperとMonotoneが元になっている[3][4]。元々のGitはローレベルなエンジンとして設計されていたが、これは、他の開発者がCogitoやStGITのようなフロントエンドを容易に開発できるようにすることを目的としていた[5]。現在では、Gitのコア自体もユーザから直接利用できるようになっている[6]。
Gitの設計には、リーナスが大規模プロジェクトのメンテナンスを行った経験や、ファイルシステムのパフォーマンスに関する深い知識、また実用性のあるシステムを短期間に作成しなければならないという差し迫った必要性(BitKeeperを参照)が反映されている。これらの影響は、以下のような形で実装に現れている。
- ノンリニアな開発スタイルに対する強力なサポート。Gitではブランチやマージが高速に行える。また、ノンリニアな開発の履歴を可視化・ナビゲートするための専用のツールを同梱している。また、ツリーに対する1回の変更に対して、複数回のマージが発生するという前提を置いているが、これは変更点が複数のレビュアーによってレビューされることを想定しているためである。
- 分散開発。他の分散型バージョン管理システム(Darcs、BitKeeper、Mercurial、SVK、Bazaar、Monotone)と同様に、Gitでも各々の開発者がリポジトリの完全なコピーをローカルに保持しており、各開発者の行った変更は他のリポジトリへコピーされる。これらの変更は新しい開発用ブランチとしてインポートされる。また、ローカルな開発用ブランチへのマージも可能である。
- HTTP、FTP、rsync、Gitプロトコル(sshを利用したトンネリングも可能)を使用したリポジトリの配布が可能。また、CVSサーバのエミュレーション機能を使用すれば、既存のCVSクライアントやIDEのプラグインからGitリポジトリへアクセスできる。
- git-svnを使用すれば、Subversionおよびsvkのリポジトリを直接操作できる。
- 大きなプロジェクトにおける処理の効率化。Gitは非常に高速かつスケーラブルになるよう記述されている[7]。Mozillaによって行われたパフォーマンステストでは、他のリビジョンコントロールシステムと比較して10倍、処理によっては100倍高速に動作することが示された[8][9]。
- ツールキット化された設計。GitはC言語で書かれたプログラム一式と、それらのラッパーとなる何本かのシェルスクリプトで構成されている[10]。GitをWindowsに移植する過程で、シェルスクリプトのほとんどはC言語で書き直された。しかし、現在でも複数のコンポーネントを繋げることで複雑な処理を容易に行えるような設計になっている[11]。
- プラガブルなマージアルゴリズム。Gitでは不完全なマージに対する優れたモデル化が行われている。また、不完全なマージを補完するアルゴリズムも複数存在する。最終的に自動的なマージが行えなかった場合には、ユーザによる編集が必要である旨がユーザに通知される。
- ガベージコレクションは行われない。操作を中断したり変更の取り消しを行った場合、データベース中には不要なデータが残ったままになる。これらのデータは操作対象のオブジェクトの履歴に比例して大きくなる。
git-gc --pruneコマンドを使用して明示的にガベージコレクションを行うこともできるが、この処理には時間がかかる[12]。
Gitの特徴の一つとして、ディレクトリツリーに対するスナップショットを作成する点が挙げられる。初期のバージョン管理システム(SCCSやRCS)では、個々のファイルを処理の対象としており、直近のバージョンに対して差分符号化を行うことでリポジトリのサイズを縮小することに機能の重点が置かれていた。以降のバージョン管理システムでも、この「プロジェクト内の複数バージョンにまたがって一つのファイルを追跡できる」という概念が継承されていた。
一方、Gitではこのコンセプトを使用していない[13]。その結果として、Gitはソースコードツリー中のファイルのリビジョン間の関係性を記録しなくなっている。これにより、Gitは以下のような特徴を持つようになっている。
- プロジェクト全体の変更履歴を調べるよりも、一つのファイルの変更履歴を調べる方が時間がかかる[14]。特定のファイルの変更履歴を取得する場合、Gitはツリーの履歴全体を走査し、各リビジョンでそのファイルに変更があったかどうか調査する必要がある。ただしこの処理手順では、一つのファイルに対しても、任意のファイルの集合に対しても、ほぼ同じ時間で履歴の調査が行える。よく行われる処理としては、例えば「ソースツリー中のあるサブディレクトリと、それに関係するヘッダファイルの調査を行う」といったものがある。
- ファイル名の変更を明示的に扱わない。CVSに対してよく挙げられる不満として、ファイルのリネームや移動を行うと変更履歴が途切れてしまう問題がある。これは、変更履歴の識別にファイル名を使用しているためである。CVS以降に開発されたバージョン管理システムの多くでは、管理対象のファイルに対してファイル名より寿命の長い、内部的な名前(inode番号のようなもの)を付与することでこの問題を解決している。一方、Gitではそのような内部名を使用しておらず、その点が長所であるとしている[15][16]。プログラムのソースコードに対しては、リネームの他にも分割やマージといった処理が行われる[17]。これらの処理を単純にファイルのリネームとして十把一絡げに扱うと、実際にソースコードツリーに対して行われた処理が何であるか不明瞭なまま履歴に記録されてしまう。Gitでは、リネームの検出をスナップショット作成時ではなく履歴のブラウズの際に行うことでこの問題を解決している[18]。(単純に考えれば、リビジョンN中のあるファイルに対して、リビジョンN-1中に同じ名前のファイルがあれば、それが元ファイルと考えられる。しかし、リビジョンN-1中に似たような名前のファイルがない場合もある。この場合Gitは、リビジョンN-1のみに存在し、かつ似たような内容のファイルを検索する。)しかし、この処理は履歴の表示を行う度にCPUに負荷のかかる処理が必要となる。そのため、使用するヒューリスティックを選択するオプションが提供されている。
リポジトリの保存方法については批判もある。
- Gitは新しく作成されたオブジェクトを個別のファイルの形で保存する。各ファイルは圧縮されて保存されるが、そうであったとしてもこの方法は記録領域を大量に必要とするため非効率的である。Gitはこの問題を“pack”を使用することで解決している。複数のオブジェクトは一つのファイル(またはネットワークバイトストリーム)の形にパックされ、各pack間で差分圧縮が行われる。packの差分圧縮にはヒューリスティックが用いられる。例えば、同じ名前のファイルは似た内容である可能性が高いものとして処理される。ただし、リポジトリの正確性を保つため、ヒューリスティックに完全に依存することはない。現在のGitでも新しく作成されたオブジェクト(新しく加えられた履歴)はまず単一のファイルとして保存されるため、空間効率を高く保つためには定期的な再パックが要求される。Gitはこの定期的な再パックを自動的に行うが、git gcコマンドを使用することで手動で再パックを行うこともできる。
Gitは以下のマージアルゴリズムを実装している。アルゴリズムはマージ時に選択することができる[19]。
- resolve
- 従来通りの3-wayマージアルゴリズムを使用する。
- recursive
- 3-wayマージの変種を使用する。ブランチのmergeやpullを行う場合のデフォルトである。3-wayマージにおいて共通の祖先が複数ある場合、共通の祖先からのmerge treeを作成し、それをreference treeとして3-wayマージを行う。Linuxカーネル2.6の開発で行われたマージコミットの履歴から、このアルゴリズムを使用するとマージの衝突が少なく、マージ漏れもなかったことが報告されている。さらに、リネームを伴うマージに対しても検出および処理が可能である[20]。
- octopus
- 3つ以上のheadからのマージを行う場合のデフォルトである。
[編集] 歴史
- 2005年12月21日 - 1.0.0リリース
- 2006年1月9日 - 1.1.0リリース
- 2006年2月13日 - 1.2.0リリース
- 2006年4月19日 - 1.3.0リリース
- 2006年6月11日 - 1.4.0リリース
- 2007年2月14日 - 1.5.0リリース
- 2008年8月18日 - 1.6.0リリース
- 2010年2月13日 - 1.7.0リリース
[編集] 開発初期の歴史
Gitの開発は、Linuxカーネルの開発者の多くがBitKeeperのシステムに対するアクセスを禁止されたことに端を発している(BitKeeper#価格変更を参照)。これは、アンドリュー・トリジェル(Andrew Tridgell)がプロプラエタリなソフトウェアであるBitKeeperのプロトコルをリバースエンジニアリングしたことに対し、BitKeeperの著作者であるLarry McVoy(en)がこれをライセンス違反であるとして、BitKeeperの無料提供を止めたためである。Linux.conf.au 2005のキーノートにおいて、Tridgellはこのリバースエンジニアリングの手順について説明を行ったが、内容はBitKeeperのサーバの適切なポートにtelnetでアクセスし“help”とタイプするだけという単純なものだった[21]。
リーナスはBitKeeperと同じように使える分散型バージョン管理システムを探していたが、無料のシステムで彼の要求(特に速度面での要求)に適合するものは見つからなかった。リーナスが書いたメールによると、2005年4月7日頃に最初のプロトタイプを作成していたようである[22]。
| “ |
だけど、僕が見たSCMはそれ(bk pull相当のこと)をするのが大変だったんだ。僕がやろうとしていることの1つは(実際はこれが主要なことだけど)その過程を十分にすること。もし1つのパッチを適用してその変更の境界を記録するのに30秒かかったとするよ(正直、Linux規模のプロジェクトで30秒っていうのは大抵のSCMでは良い見積りだけど)。250通のメールパッチを適用するのに2時間かかることになる(Andrew[23] と同期しても取り込めないものだったとすると)。 BKはスピード狂ではなくて、(他のSCMと比較するとBKは1桁か2桁くらいは高速だけど)Andrew[23]とマージをする時に1メールにつき約10-15秒かかる。だけど、BKではそれは大きな問題にならないんだ。BK<->BK間のマージは簡単だからさ。僕は他の主要な開発者とは時間がかかるメールでのマージをしないようにしているんだ。パッチアプリケーションに基づいたSCMは、“マージ機能”をBKよりも速くする必要がある。それは本当に本当に大変なこと。 だから、僕はいまスクリプトを書いていて、変更をずっと速く追跡できるようにしているんだ。最初の目標はパッチを適用するのと同じくらい高速にそれを行うこと。だけど実際、およそ半分はできている。思わぬ障害にぶつかったら嘘になるかもしれないけど。いずれにせよ、僕がそれを高速にできる理由は、僕のスクリプトがSCMではないからで、とても特別で“Linuxの状態を記録する”ようなものだからなんだ。それはリニアなパッチを十分効率的な時間でマージできるようになるだろう。 (パッチの適用が3秒でできるなら、大きな1つながりのパッチシリーズでも問題にはならない: 途中で失敗しても1分か2分で気がつくなら、それで十分で、手作業で修正することができる。待ち時間が重要な理由はそこにある。--“オフライン”で効果的にそれができるなら、問題が起きた時に僕は定義どおりそれを修理できずにいるだろう) |
” |
リーナスは以下のような原則に基づいて設計を行っている。
- CVSを「悪い見本」とする。設計上のことで確信が持てない場合は、CVSと逆の決断をする。リーナスは冗談めかして以下のように語っている。
- “カーネルメンテナンスの最初の10年間、僕らは文字通りtarボールとパッチを使っていた。CVSよりもずっと優れたソース管理システムさ。僕は営利企業 ( トランスメタ[24]) でCVSを7年間使わされたことで、CVSを強烈に憎むようになった。CVSを強烈に憎んでいると言う時には、このことも言っておかなくちゃいけないね。観衆の中にSVN(Subversion)のユーザがいるなら、この場から去ったほうがいいかもしれない。僕がCVSを強烈に嫌悪しているということは、僕がSubversionが史上最大の無意味なプロジェクトであると思っていることも意味しているんだ。Subversionのしばらくのスローガンは‘ちゃんとCVSをやる’とかそんなものだったよね。そんなスローガンから始めたら、どこにも辿りつけないよ。CVSをちゃんとやるなんて不可能なのさ。”[25]
- 分散型の、BitKeeperのようなワークフローをサポートする。
- “BitKeeperだけが、「まあ使ってもいいかな」と最初に思わせてくれたSCMだというわけではないけれど、BitkeeperはSCMというものの存在意義と、実際にどう使うことができるのかを教えてくれた。 だから、Gitは技術的な観点とかいろんなところでBitkeeperとは随分違うものになっているけど(それはもう一つの設計目標でもある。Bitkeeperのクローンではないことをはっきりさせたかったから。)、Gitのワークフローの多くは、Bitkeeperが教えてくれたフローから直接きたものになっているんだ。”[25]
- データ破壊に対する強力な抑止機能。データ破壊は、偶然によるものと意図的なものの両方を想定している[26][25]。
- 非常に高い処理速度。
最初の3つの条件によって、既存のバージョン管理システムはMonotoneを除き全て選に漏れてしまい、4つ目の条件で該当するものがなくなってしまった[25]。そのため、Linuxカーネル2.6.12-rc2のリリース直後に[25]、リーナスは自分で開発を始めた[25]。
Gitの開発は2005年4月3日に開始された[27]。プロジェクトとしてのアナウンスは4月6日に行われ[28]、4月7日にはセルフホスティングされるようになった[27]。4月18日には複数のブランチからのマージが最初に行われた[29]。4月29日にはリーナスの目標としていた処理速度が実現された。Linuxのカーネルツリーにパッチを当てるベンチマークで、初期のGitでは毎秒6.7個のパッチを処理している[30]。6月6日には、GitによるLinuxカーネル2.6.12のリリースが行われた[31]。
BitKeeperからの影響で、リーナスは従来と同じようなアプローチを意図的に避けており、結果としてGitは非常にユニークな設計になっている[32]。技術に長けたユーザがGitを利用できるようになるレベルまではリーナスが開発を行っており、その後、2005年6月26日にはプロジェクトへの主要な貢献者であったJunio C Hamanoにメンテナンスが引き継がれた[33]。Hamanoは2005年12月21日にバージョン1.0のリリースを行い[34]、2009年3月現在も彼がメンテナンスを行っている。
[編集] 脚注
- ^ (2005-04-19)“After controversy, Torvalds begins work on git”InfoWorld. ISSN 0199-6649. 2008年2月20日閲覧。
- ^ GitFaq: Why the 'git' name?
- ^ Linus Torvalds (2006年5月5日). “Re: [ANNOUNCE] Git wiki”. linux-kernel mailing list 2009年3月3日閲覧。 gitの元となったプログラムに関する歴史的経緯
- ^ Linus Torvalds (2005年4月7日). “Re: Kernel SCM saga”. linux-kernel mailing list 2009年3月3日閲覧。
- ^ Linus Torvalds (2005年4月8日). “Re: Kernel SCM saga”. linux-kernel mailing list 2008年2月20日閲覧。
- ^ Linus Torvalds (2006年3月23日). “Re: Errors GITtifying GCC and Binutils”. git mailing list 2009年3月3日閲覧。
- ^ Linus Torvalds (2006年10月19日). “Re: VCS comparison table”. git mailing list 2009年3月3日閲覧。
- ^ Stenback, Johnny (2006-11-30), “bzr/hg/git performance”, Jst's Blog 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 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 2009年3月3日閲覧。
- ^ Bruno Haible (2007年2月11日). “how to speed up "git log"?”. git mailing list 2009年3月3日閲覧。
- ^ Linus Torvalds (2006年3月1日). “Re: impure renames / history tracking”. git mailing list 2009年3月3日閲覧。
- ^ Junio C Hamano (2006年3月24日). “Re: Errors GITtifying GCC and Binutils”. git mailing list 2009年3月3日閲覧。
- ^ Junio C Hamano (2006年3月23日). “Re: Errors GITtifying GCC and Binutils”. git mailing list 2009年3月3日閲覧。
- ^ Linus Torvalds (2006年11月28日). “Re: git and bzr”. git mailing list 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日閲覧。
- ^ Jonathan Corbet (2005-04-20), “How Tridge reverse engineered BitKeeper”, Linux Weekly News 2009年3月26日閲覧。
- ^ Linus Torvalds (2005年4月7日). “Re: Kernel SCM saga..”. linux-kernel mailing list 2009年3月26日閲覧。
- ^ a b ここでは -mm ツリーメンテナのアンドリュー・モートンを指す。
- ^ Linus Torvalds (2005年10月31日). “Re: git versus CVS (versus bk)”. git mailing list 2009年3月26日閲覧。
- ^ a b c d e f Linus Torvalds (05-03). Google tech talk: Linus Torvalds on git. 該当時間:02:30 2007年5月16日閲覧。.
- ^ Linus Torvalds (2007年6月10日). “Re: fatal: serious inflate inconsistency”. git mailing list 2009年3月26日閲覧。 Gitにおけるデータの完全性に関する設計目標に関する概要説明。
- ^ a b Linus Torvalds (2007年2月27日). “Re: Trivia: When did git self-host?”. git mailing list 2009年3月26日閲覧。
- ^ Linus Torvalds (2005年4月6日). “Kernel SCM saga..”. linux-kernel mailing list 2009年3月26日閲覧。
- ^ Linus Torvalds (2005年4月17日). “First ever real kernel git merge!”. git mailing list 2009年3月26日閲覧。
- ^ Matt Mackall (2005年4月29日). “Mercurial 0.4b vs git patchbomb benchmark”. git mailing list 2009年3月26日閲覧。
- ^ Linus Torvalds (2005年6月17日). “Linux 2.6.12”. git-commits-head mailing list 2009年3月26日閲覧。
- ^ Linus Torvalds (2006年10月20日). “Re: VCS comparison table”. git mailing list 2009年3月26日閲覧。 Git vs. BitKeeperの議論
- ^ Linus Torvalds (2005年7月27日). “Meet the new maintainer...”. git mailing list 2009年3月26日閲覧。
- ^ Junio C Hamano (2005年12月21日). “ANNOUNCE: GIT 1.0.0”. git mailing list 2009年3月26日閲覧。
[編集] 関連項目
- バージョン管理システム
- arch
- Subversion
- CVS
- BitKeeper - Git以前にLinuxカーネル開発で使用されていたバージョン管理システム。ライセンス発行に関わる問題によりGitが開発されることとなった。
- Mercurial - Gitとほぼ同時期に開発が開始された。
- Bazaar
[編集] 外部リンク
- Git - Fast Version Control System
- Gitの配布ディレクトリ
- Git入門
- GitSharpは「Mono」と「.Net」のために発達している。
|
|||||||||||||||||||||||||||||||||||||||