「Git」の版間の差分
m →外部リンク |
|||
(30人の利用者による、間の41版が非表示) | |||
1行目: | 1行目: | ||
{{Otheruses}} |
{{Otheruses}} |
||
{{混同|GitHub|GitLab}} |
|||
{{Infobox Software |
{{Infobox Software |
||
| 名称 = Git |
| 名称 = Git |
||
5行目: | 6行目: | ||
| スクリーンショット = [[ファイル:Gitweb.png|250px]] |
| スクリーンショット = [[ファイル:Gitweb.png|250px]] |
||
| 説明文 = GitのWebインターフェース、gitweb |
| 説明文 = GitのWebインターフェース、gitweb |
||
| 開発元 = 濱野純, [[リーナス・トーバルズ]], {{url|https://github.com/git/git/graphs/contributors|ほか多数}} |
| 開発元 = [[濱野純]], [[リーナス・トーバルズ]], {{url|https://github.com/git/git/graphs/contributors|ほか多数}} |
||
| プログラミング言語 = [[C言語|C]], [[Bourne Shell]], [[ |
| プログラミング言語 = [[C言語|C]], [[Bourne Shell]], [[Tcl]], [[Perl]] |
||
| 対応OS = [[Unix系]] |
| 対応OS = [[Unix系]]、[[Linux]]、[[Microsoft Windows|Windows]]、[[macOS]] |
||
| 種別 = [[バージョン管理ソフトウェア]] |
| 種別 = [[バージョン管理ソフトウェア]] |
||
| ライセンス = [[GNU General Public License]] バージョン2,[[GNU Lesser General Public License]] 2.1 |
| ライセンス = [[GNU General Public License]] バージョン2,[[GNU Lesser General Public License]] 2.1 |
||
| 公式サイト = {{ |
| 公式サイト = {{conditionalURL}} |
||
| 初版 = {{release date and age|2005|12|21}} |
| 初版 = {{release date and age|2005|12|21}} |
||
| frequently updated = yes <!-- バージョン情報は[[Template:Latest stable software release/Git]]。 --> |
| frequently updated = yes <!-- バージョン情報は[[Template:Latest stable software release/Git]]。 --> |
||
}} |
}} |
||
'''Git'''(ギット<ref> |
'''Git'''(ギット<ref>{{Cite video|url=https://www.youtube.com/watch?feature=player_detailpage&v=4XpnKHJAok8#t=88 |title=Tech Talk: Linus Torvalds on git |time=1分30秒 |accessdate=2014-07-21}}</ref><ref>{{Cite web|和書|url=http://e-words.jp/w/Git.html |title=Git - IT用語辞典e-words |accessdate=2014-07-29}}</ref>)は、[[プログラム (コンピュータ)|プログラム]]の[[ソースコード]]などの変更履歴を記録・追跡するための分散型[[バージョン管理システム]]である。[[Linuxカーネル]]のソースコード管理に用いるために[[リーナス・トーバルズ]]によって開発され、それ以降ほかの多くのプロジェクトで採用されている。Linuxカーネルのような巨大プロジェクトにも対応できるように、動作速度に重点が置かれている。現在のメンテナは[[濱野純]] ({{Lang-en|Junio C Hamano}}) で、2005年7月から担当している。 |
||
Gitでは、各ユーザのワーキングディレクトリに、全履歴を含んだ[[リポジトリ]]の完全な複製が作られる。したがって、ネットワークにアクセスできないなどの理由で中心リポジトリにアクセスできない環境でも、履歴の調査や変更の記録といったほとんどの作業を行うことができる。これが「分散型」と呼ばれる理由である。 |
Gitでは、各ユーザのワーキングディレクトリに、全履歴を含んだ[[リポジトリ]]の完全な複製が作られる。したがって、[[コンピュータネットワーク|ネットワーク]]にアクセスできないなどの理由で中心リポジトリにアクセスできない環境でも、履歴の調査や変更の記録といったほとんどの作業を行うことができる。これが「分散型」と呼ばれる理由である。 |
||
== 背景および概要 == |
== 背景および概要 == |
||
Linuxカーネルの開発では、Linux Kernel Mailing List<ref group="※">[https://lkml.org LKML.ORG - the Linux Kernel Mailing List Archive]</ref> に投稿される多数のパッチをメンテナーたちがソースコードに適用するという形式が採用されている。これらの作業を効率的に行うため、当初は[[BitKeeper]]というバージョン管理システムを用いていたが、このソフトウェアは[[プロプライエタリソフトウェア|商用ソフトウェア]]であった([[クライアント (コンピュータ)|クライアント]]はバイナリ版のみ無料で、[[サーバ]]は商用だがBitMover社の厚意で無料で使えていた)。この状況を快く思わない人々がBitKeeperのクローンを実装したことから、この環境が使えなくなってしまい([[BitKeeper#ライセンス問題]]や[[BitKeeper#価格変更]]を参照)、その代替として2005年にGitが開発された<ref>{{Cite book|和書|url=https://git-scm.com/book/ja/v2/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-Git%E7%95%A5%E5%8F%B2 |chapter=1.2 使い始める-Git略史 |title=Pro Git |author1=Scott Chacon |accessdate=2021-03-07}}</ref>。 |
|||
Linuxカーネルの開発では、巨大なソースコードの集合を扱うため、変更点の抽出やリポジトリ操作ができるかぎり高速にできる必要がある。他の様々なバージョン管理システムをあたったが、満足のいくものがなかったため、Gitではこのような問題も出来る限り解決できるよう、いくつかのアイデアが導入されている(この部分は、他のバージョン管理システムにも同様の機能が導入されるようになった)。 |
Linuxカーネルの開発では、巨大なソースコードの集合を扱うため、変更点の抽出やリポジトリ操作ができるかぎり高速にできる必要がある。他の様々なバージョン管理システムをあたったが、満足のいくものがなかったため、Gitではこのような問題も出来る限り解決できるよう、いくつかのアイデアが導入されている(この部分は、他のバージョン管理システムにも同様の機能が導入されるようになった)。 |
||
29行目: | 30行目: | ||
# リモートサーバ等にある中心リポジトリをローカルに複製する (git clone)。 |
# リモートサーバ等にある中心リポジトリをローカルに複製する (git clone)。 |
||
# ローカルでコンテンツの修正・追加・削除を行い、ローカルリポジトリに変更履歴を記録する (git commit)。必要に応じて過去の状態の閲覧や復元などを行う。場合によってはこのステップを何度か繰り返す。 |
# ローカルでコンテンツの修正・追加・削除を行い、ローカルリポジトリに変更履歴を記録する (git commit)。必要に応じて過去の状態の閲覧や復元などを行う。場合によってはこのステップを何度か繰り返す。 |
||
# 中心リポジトリ |
# ローカルの変更内容を中心リポジトリに反映させる (git push)。作業者ごとの変更内容が衝突することもある。Gitが自動で解決できる場合もあれば、手動での解決 (git merge)が必要なこともある。 |
||
# |
# 更新された中心リポジトリ(他者の作業内容も統合されている)をローカルの複製にも反映する (git pull)。これによりローカル環境のコードも最新の内容になるので、改めてステップ2の作業を行う。 |
||
リポジトリ間の通信 (clone, pull, push) では以下のプロトコルが使用できる<ref name="progit-ja-4-1">{{Cite web|url=https://git-scm.com/book/ja/Git-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB|title=4.1 Git サーバー - プロトコル|accessdate=2013-01-19|author=Scott Chacon}}</ref>。 |
リポジトリ間の通信 (clone, pull, push) では以下のプロトコルが使用できる<ref name="progit-ja-4-1">{{Cite web|和書|url=https://git-scm.com/book/ja/Git-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB|title=4.1 Git サーバー - プロトコル|accessdate=2013-01-19|author=Scott Chacon}}</ref>。 |
||
* ローカルファイルシステム<ref name="progit-ja-4-1"/> |
* ローカル[[ファイルシステム]]<ref name="progit-ja-4-1"/> |
||
* [[Secure Shell|SSH]]<ref name="progit-ja-4-1"/> |
* [[Secure Shell|SSH]]<ref name="progit-ja-4-1"/> |
||
* git([[認証]]機能なし)<!-- 編集メモ:pushは可能だが認証がないので通常は使われない --><ref name="progit-ja-4-1"/> |
* git([[認証]]機能なし)<!-- 編集メモ:pushは可能だが認証がないので通常は使われない --><ref name="progit-ja-4-1"/> |
||
* [[Hypertext Transfer Protocol|HTTP]]/[[HTTPS]] |
* [[Hypertext Transfer Protocol|HTTP]]/[[HTTPS]]<ref name="progit-ja-4-1"/> |
||
** pushするためには、サーバー側にgit-http-backendプログラム<ref>{{Cite web|和書|url=https://git-scm.com/book/ja/v2/Git%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-Smart-HTTP|title=Pro Git 2nd Edition 4.6 Gitサーバー - Smart HTTP|accessdate=2021-08-26|author=Scott Chacon|coauthors=Ben Straub}}</ref>または[[WebDAV]]<ref>{{Cite web|url=https://git-scm.com/docs/user-manual#exporting-via-http|title=Git - user-manual Documentation|language=en|accessdate=2021-08-26|quote=(See also setup-git-server-over-http for a slightly more sophisticated setup using WebDAV which also allows pushing over HTTP.)}}</ref>が必要。 |
|||
* [[File Transfer Protocol|FTP]]/[[FTPS]]: ただし、もはや使うべきではないとされている<ref>{{Cite web|url=https://git-scm.com/docs/git-clone|title=git-clone(1) Manual Page|accessdate=2017-06-14|quote=in addition, ftp, and ftps can be used for fetching, but this is inefficient and deprecated; do not use it|language=英語}}</ref>。 |
* [[File Transfer Protocol|FTP]]/[[FTPS]]: ただし、もはや使うべきではないとされている<ref>{{Cite web|url=https://git-scm.com/docs/git-clone|title=git-clone(1) Manual Page|accessdate=2017-06-14|quote=in addition, ftp, and ftps can be used for fetching, but this is inefficient and deprecated; do not use it|language=英語}}</ref>。 |
||
75行目: | 77行目: | ||
* ノンリニアな開発スタイルに対する強力なサポート。Gitではブランチやマージが高速に行える。また、ノンリニアな開発の履歴を可視化・ナビゲートするための専用のツールを同梱している。また、ツリーに対する1回の変更に対して、複数回のマージが発生するという前提を置いているが、これは変更点が複数のレビュアーによってレビューされることを想定しているためである。 |
* ノンリニアな開発スタイルに対する強力なサポート。Gitではブランチやマージが高速に行える。また、ノンリニアな開発の履歴を可視化・ナビゲートするための専用のツールを同梱している。また、ツリーに対する1回の変更に対して、複数回のマージが発生するという前提を置いているが、これは変更点が複数のレビュアーによってレビューされることを想定しているためである。 |
||
* 分散開発。他の分散型バージョン管理システム([[ |
* 分散開発。他の分散型バージョン管理システム([[Mercurial]]、[[BitKeeper]]、[[Darcs]]、[[Bazaar]]、[[SVK (バージョン管理システム)|SVK]]、[[Monotone]])と同様に、Gitでも各々の開発者がリポジトリの完全なコピーをローカルに保持しており、各開発者の行った変更は他のリポジトリにコピーされる。これらの変更は新しい開発用ブランチとしてインポートされる。また、ローカルな開発用ブランチへのマージも可能である。 |
||
* [[HTTP]]、[[FTP]]、gitプロトコル([[Secure Shell|ssh]]を利用したトンネリングも可能)を使用したリポジトリの配布が可能。また、[[Concurrent Versions System|CVS]]サーバのエミュレーション機能を使用すれば、既存のCVSクライアントやIDEのプラグインからGitリポジトリにアクセスできる。 |
* [[HTTP]]、[[File Transfer Protocol|FTP]]、gitプロトコル([[Secure Shell|ssh]]を利用したトンネリングも可能)を使用したリポジトリの配布が可能。また、[[Concurrent Versions System|CVS]]サーバのエミュレーション機能を使用すれば、既存のCVSクライアントやIDEのプラグインからGitリポジトリにアクセスできる。 |
||
* git-svnを使用すれば、Subversionおよびsvkのリポジトリを直接操作できる。 |
* git-svnを使用すれば、[[Apache Subversion|Subversion]]およびsvkのリポジトリを直接操作できる。 |
||
* 大きなプロジェクトにおける処理の効率化。Gitは非常に高速かつスケーラブルになるよう記述されている<ref>{{cite mailing list |
* 大きなプロジェクトにおける処理の効率化。Gitは非常に高速かつスケーラブルになるよう記述されている<ref>{{cite mailing list |
||
| author=Linus Torvalds |
| author=Linus Torvalds |
||
102行目: | 104行目: | ||
}}, "git log"は"svn log"と比較して100倍以上高速だが、これは後者はリモートのサーバにアクセスする必要があるためである。</ref>。 |
}}, "git log"は"svn log"と比較して100倍以上高速だが、これは後者はリモートのサーバにアクセスする必要があるためである。</ref>。 |
||
<!-- 訳注:gitの内部構造について知らないため、以下の文がどういう意味なのか良く分かりませんでした。訳してくださる方を募集します。 --><!-- * Cryptographic authentication of history. The Git history is stored in such a way that the name of a particular revision (a "commit" in Git terms) depends upon the complete development history leading up to that commit. Once it is published, it is not possible to change the old versions without it being noticed. ([[Mercurial (software)|Mercurial]] and [[Monotone (software)|Monotone]] also have this property.) --><!-- Is this a [[hash tree]] technique? If so, say so. --> |
<!-- 訳注:gitの内部構造について知らないため、以下の文がどういう意味なのか良く分かりませんでした。訳してくださる方を募集します。 --><!-- * Cryptographic authentication of history. The Git history is stored in such a way that the name of a particular revision (a "commit" in Git terms) depends upon the complete development history leading up to that commit. Once it is published, it is not possible to change the old versions without it being noticed. ([[Mercurial (software)|Mercurial]] and [[Monotone (software)|Monotone]] also have this property.) --><!-- Is this a [[hash tree]] technique? If so, say so. --> |
||
* ツールキット化された設計。gitはC言語で書かれたプログラム一式と、それらのラッパーとなる何本かのシェルスクリプトで構成されている<ref>{{cite mailing list |
* ツールキット化された設計。gitは[[C言語]]で書かれたプログラム一式と、それらのラッパーとなる何本かの[[シェルスクリプト]]で構成されている<ref>{{cite mailing list |
||
| mailinglist=Git |
| mailinglist=Git |
||
| author=Linus Torvalds |
| author=Linus Torvalds |
||
174行目: | 176行目: | ||
リポジトリの保存方法については批判もある。 |
リポジトリの保存方法については批判もある。 |
||
* Gitは新しく作成されたオブジェクトを個別のファイルの形で保存する。各ファイルは圧縮されて保存されるが、そうであったとしてもこの方法は記録領域を大量に必要とするため非効率的である。Gitはこの問題を“pack”を使用することで解決している。複数のオブジェクトは一つのファイル(またはネットワークバイトストリーム)の形にパックされ、各pack間で差分圧縮が行われる。packの差分圧縮には[[ヒューリスティック]]が用いられる。例えば、同じ名前のファイルは似た内容である可能性が高いものとして処理される。ただし、リポジトリの正確性を保つため、ヒューリスティックに完全に依存することはない。現在のGitでも新しく作成されたオブジェクト(新しく加えられた履歴)はまず単一のファイルとして保存されるため、空間効率を高く保つためには定期的な再パックが要求される。Gitはこの定期的な再パックを自動的に行うが、< |
* Gitは新しく作成されたオブジェクトを個別のファイルの形で保存する。各ファイルは圧縮されて保存されるが、そうであったとしてもこの方法は記録領域を大量に必要とするため非効率的である。Gitはこの問題を“pack”を使用することで解決している。複数のオブジェクトは一つのファイル(またはネットワークバイトストリーム)の形にパックされ、各pack間で差分圧縮が行われる。packの差分圧縮には[[ヒューリスティック]]が用いられる。例えば、同じ名前のファイルは似た内容である可能性が高いものとして処理される。ただし、リポジトリの正確性を保つため、ヒューリスティックに完全に依存することはない。現在のGitでも新しく作成されたオブジェクト(新しく加えられた履歴)はまず単一のファイルとして保存されるため、空間効率を高く保つためには定期的な再パックが要求される。Gitはこの定期的な再パックを自動的に行うが、<code>git gc</code>コマンドを使用することで手動で再パックを行うこともできる。 |
||
Gitは以下のマージアルゴリズムを実装している。アルゴリズムはマージ時に選択することができる<ref>{{cite web |
Gitは以下のマージアルゴリズムを実装している。アルゴリズムはマージ時に選択することができる<ref>{{cite web |
||
199行目: | 201行目: | ||
英語のスラングとして、Gitには「バカ」「間抜け」といった類の意味がある。この自虐ネタはもちろん皮肉で、これはリーナスがLinuxの名前を決める際に自身の名前にちなんだ名前を付けるよう強要されたことから来ている。([[Linux#名前の由来]]を参照) |
英語のスラングとして、Gitには「バカ」「間抜け」といった類の意味がある。この自虐ネタはもちろん皮肉で、これはリーナスがLinuxの名前を決める際に自身の名前にちなんだ名前を付けるよう強要されたことから来ている。([[Linux#名前の由来]]を参照) |
||
Gitのオフィシャルサイトの |
Gitのオフィシャルサイトの[[ウィキ]]では、“Git”という名前に対して他にもいくつかの解釈がなされている。例としては''Global Information Tracker''などが挙げられる<ref>{{Cite web|url=http://git.or.cz/gitwiki/GitFaq#head-90fa13ebe170116f1586156e73b549cc2135b784 |title=GitFaq: Why the 'git' name? |accessdate=2007-03-21}}</ref>。 |
||
=== 開発初期の歴史 === |
=== 開発初期の歴史 === |
||
Gitの開発は、Linuxカーネルの開発者の多くがBitKeeperのシステムに対するアクセスを禁止されたことに端を発している([[BitKeeper#価格変更]]を参照)。これは、[[アンドリュー・トリジェル]](Andrew Tridgell)がプロプラエタリなソフトウェアであるBitKeeperのプロトコルを[[リバースエンジニアリング]]したことに対し、BitKeeperの著作者である[[ |
Gitの開発は、Linuxカーネルの開発者の多くがBitKeeperのシステムに対するアクセスを禁止されたことに端を発している([[BitKeeper#価格変更]]を参照)。これは、[[アンドリュー・トリジェル]] (Andrew Tridgell) がプロプラエタリなソフトウェアであるBitKeeperのプロトコルを[[リバースエンジニアリング]]したことに対し、BitKeeperの著作者である[[ラリー・マクボイ]]がこれをライセンス違反であるとして、BitKeeperの無料提供を止めたためである。[[Linux.conf.au]] 2005のキーノートにおいて、トリジェルはこのリバースエンジニアリングの手順について説明を行ったが、内容はBitKeeperのサーバの適切なポートに[[telnet]]でアクセスし“help”とタイプするだけという単純なものだった<ref>{{Citation |
||
| author=Jonathan Corbet |
| author=Jonathan Corbet |
||
| journal=Linux Weekly News |
| journal=Linux Weekly News |
||
211行目: | 213行目: | ||
}}</ref>。 |
}}</ref>。 |
||
リーナスはBitKeeperと同じように使える分散型バージョン管理システムを探していたが、無料のシステムで彼の要求(特に速度面での要求)に適合するものは見つからなかった。リーナスが書いたメールによると、2005年4月7日頃に最初のプロトタイプを作成していたようである<ref>{{cite mailing list |
リーナスはBitKeeperと同じように使える分散型バージョン管理システムを探していたが、無料のシステムで彼の要求(特に速度面での要求)に適合するものは見つからなかった。リーナスが書いたメールによると、2005年4月7日頃に最初の[[プロトタイプ]]を作成していたようである<ref>{{cite mailing list |
||
| mailinglist=linux-kernel |
| mailinglist=linux-kernel |
||
| author=Linus Torvalds |
| author=Linus Torvalds |
||
221行目: | 223行目: | ||
{{Cquote| |
{{Cquote| |
||
だけど、僕が見た[[バージョン管理システム|SCM]]たちはそれ(''bk pull''相当のこと)をするのが大変だったんだ。僕がやろうとしていることの1つは(実はこれが一番なんだけど)その過程を十分''効率的''にすること。もし1つのパッチを適用してその変更の境界を記録するなどするのに30秒かかったとすると(正直、Linux規模のプロジェクトで30秒っていうのは大抵のSCMでは速いほうの見積りだけど)、250通(例えばAndrew<ref name="andrews">ここでは [[mmツリー|-mm ツリー]]メンテナの[[アンドリュー・モートン]]を指す。</ref> と同期するときには決して珍しい量じゃない)のメールパッチを適用するのに2時間かかることになる。 |
だけど、僕が見た[[バージョン管理システム|SCM]]たちはそれ(''bk pull''相当のこと)をするのが大変だったんだ。僕がやろうとしていることの1つは(実はこれが一番なんだけど)その過程を十分''効率的''にすること。もし1つのパッチを適用してその変更の境界を記録するなどするのに30秒かかったとすると(正直、Linux規模のプロジェクトで30秒っていうのは大抵のSCMでは速いほうの見積りだけど)、250通(例えばAndrew<ref group="※" name="andrews">ここでは [[mmツリー|-mm ツリー]]メンテナの[[アンドリュー・モートン]]を指す。</ref> と同期するときには決して珍しい量じゃない)のメールパッチを適用するのに2時間かかることになる。 |
||
BKはスピード狂ではなくて、 |
BKはスピード狂ではなくて、(他のSCMと比較するとBKは1桁か2桁くらいは高速だけど)Andrew<ref group="※" name="andrews" />とマージをする時に1メールにつき約10-15秒かかっていた。だけど、BKではそれは大きな問題にならなかったんだ。BK⇔BK間のマージは簡単だから、僕は他の主要な開発者とは時間がかかるメールでのマージをしたことはなかったから。パッチアプリケーションに基づいたSCMにするなら、"マージ機能" をBKよりも''速く''しなければならなくなる。それは本当に本当に大変なこと。 |
||
だから、僕はいまスクリプトを書いていて、変更をずっと速く追跡できるようにしているんだ。最初の目標はパッチを適用するのと同じくらい高速にそれを行うこと。だけどはっきりいって、今のところできたのは多く見積もってもまだ半分くらいで、思わぬ障害にぶつかったら全然嘘になるかもしれないけど。いずれにせよ、僕がそれをすぐにできる理由は、僕のスクリプトがSCMではないからで、とても特別で |
だから、僕はいまスクリプトを書いていて、変更をずっと速く追跡できるようにしているんだ。最初の目標はパッチを適用するのと同じくらい高速にそれを行うこと。だけどはっきりいって、今のところできたのは多く見積もってもまだ半分くらいで、思わぬ障害にぶつかったら全然嘘になるかもしれないけど。いずれにせよ、僕がそれをすぐにできる理由は、僕のスクリプトがSCMではないからで、とても特別で "Linuxの状態を記録する" ようなものだからなんだ。それはリニアなパッチを十分効率的な時間でマージできるようになるだろう。 |
||
(パッチの適用が3秒でできるなら、大きな1つながりのパッチでも問題にはならない: 途中で失敗しても1分か2分で気がつくなら、それで十分で、手作業で修正することができる。待ち時間が重要な理由はそこにある。-- |
(パッチの適用が3秒でできるなら、大きな1つながりのパッチでも問題にはならない: 途中で失敗しても1分か2分で気がつくなら、それで十分で、手作業で修正することができる。待ち時間が重要な理由はそこにある。-- "オフライン" で効果的にそれができるなら、問題が起きた時に僕は定義どおりそれを修理できずにいるだろう) |
||
}} |
}} |
||
リーナスは以下のような原則に基づいて設計を行っている。 |
リーナスは以下のような原則に基づいて設計を行っている。 |
||
# [[Concurrent Versions System|CVS]]を「悪い見本」とする。設計上のことで確信が持てない場合は、CVSと逆の決断をする。リーナスは冗談めかして以下のように語っている。 |
# [[Concurrent Versions System|CVS]]を「悪い見本」とする。設計上のことで確信が持てない場合は、CVSと逆の決断をする。リーナスは冗談めかして以下のように語っている。 |
||
# |
#* “カーネルメンテナンスの最初の10年間、僕らは文字通りtarボールとパッチを使っていた。CVSよりもずっと優れたソース管理システムさ。僕は営利企業(''[[トランスメタ]]<ref>{{cite mailing list |
||
| author=Linus Torvalds |
| author=Linus Torvalds |
||
| authorlink=Linus Torvalds |
| authorlink=Linus Torvalds |
||
240行目: | 242行目: | ||
| url=http://marc.info/?l=git&m=113072612805233&w=2 |
| url=http://marc.info/?l=git&m=113072612805233&w=2 |
||
| accessdate=2009-03-26 |
| accessdate=2009-03-26 |
||
}}</ref> |
}}</ref>'')でCVSを7年間使わされたことで、CVSを強烈に憎むようになった。CVSを強烈に憎んでいると言う時には、このことも言っておかなくちゃいけないね。観衆の中にSVN ([[Apache Subversion|Subversion]]) のユーザがいるなら、この場から去ったほうがいいかもしれない。僕がCVSを強烈に嫌悪しているということは、僕がSubversionが史上最大の無意味なプロジェクトであると思っていることも意味しているんだ。Subversionのしばらくのスローガンは‘ちゃんとCVSをやる’とかそんなものだったよね。そんなスローガンから始めたら、どこにも辿りつけないよ。CVSをちゃんとやるなんて不可能なのさ。”<ref name=linusGoogleTalk>{{cite video |
||
| people=Linus Torvalds |
| people=Linus Torvalds |
||
| |
| date=2007-05-03 |
||
⚫ | |||
| date=05-03 |
|||
⚫ | |||
| title=Google tech talk: Linus Torvalds on git |
| title=Google tech talk: Linus Torvalds on git |
||
| time=02:30 |
| time=02:30 |
||
| accessdate=2007-05-16}}</ref> |
| accessdate=2007-05-16}}</ref> |
||
# 分散型の、BitKeeperのようなワークフローをサポートする。 |
# 分散型の、BitKeeperのようなワークフローをサポートする。 |
||
# |
#* “BitKeeperだけが、「まあ使ってもいいかな」と最初に思わせてくれたSCMだというわけではないけれど、BitkeeperはSCMというものの存在意義と、実際にどう使うことができるのかを教えてくれた。だから、Gitは技術的な観点とかいろんなところでBitkeeperとは随分違うものになっているけど(それはもう一つの設計目標でもある。Bitkeeperのクローンではないことをはっきりさせたかったから)、Gitのワークフローの多くは、Bitkeeperが教えてくれたフローから直接きたものになっているんだ。”<ref name=linusGoogleTalk /> |
||
# データ破壊に対する強力な抑止機能。データ破壊は、偶然によるものと意図的なものの両方を想定している<ref>{{cite mailing list |
# データ破壊に対する強力な抑止機能。データ破壊は、偶然によるものと意図的なものの両方を想定している<ref>{{cite mailing list |
||
| author=Linus Torvalds |
| author=Linus Torvalds |
||
306行目: | 307行目: | ||
| date=2006-10-20 |
| date=2006-10-20 |
||
| accessdate=2009-03-26 |
| accessdate=2009-03-26 |
||
}} Git vs. BitKeeperの議論</ref>。技術に長けたユーザがGitを利用できるようになるレベルまではリーナスが開発を行っており、その後、2005年6月26日にはプロジェクトへの主要な貢献者であったJunio C Hamanoにメンテナンスが引き継がれた<ref>{{cite mailing list |
}} Git vs. BitKeeperの議論</ref>。技術に長けたユーザがGitを利用できるようになるレベルまではリーナスが開発を行っており、その後、2005年6月26日にはプロジェクトへの主要な貢献者であった[[濱野純]] (Junio C Hamano) にメンテナンスが引き継がれた<ref>{{cite mailing list |
||
| mailinglist=Git |
| mailinglist=Git |
||
| author=Linus Torvalds |
| author=Linus Torvalds |
||
313行目: | 314行目: | ||
| date=2005-07-27 |
| date=2005-07-27 |
||
| accessdate=2009-03-26 |
| accessdate=2009-03-26 |
||
}}</ref>。 |
}}</ref>。濱野は2005年12月21日にバージョン1.0のリリースを行い<ref>{{cite mailing list |
||
| mailinglist=Git |
| mailinglist=Git |
||
| author=Junio C Hamano |
| author=[[濱野純]] (Junio C Hamano) |
||
| url=http://marc.info/?l=git&m=113515203321888 |
| url=http://marc.info/?l=git&m=113515203321888 |
||
| title=ANNOUNCE: GIT 1.0.0 |
| title=ANNOUNCE: GIT 1.0.0 |
||
| date=2005-12-21 |
| date=2005-12-21 |
||
| accessdate=2009-03-26 |
| accessdate=2009-03-26 |
||
}}</ref>、 |
}}</ref>、2021年5月現在も彼がメンテナンスを行っている。 |
||
== ブランチモデル == |
|||
ソフトウェア開発におけるGitブランチの作成・更新モデルを'''ブランチモデル'''と呼ぶ。 |
|||
=== GitHub flow === |
|||
GitHub flowはブランチモデルの一種である<ref name="scottchacon.com-github-flow">{{Cite web|url=https://scottchacon.com/2011/08/31/github-flow.html |author=Scott Chacon |date=2011-08-31 |title=GitHub Flow |accessdate=2020-05-31}}</ref>。GitHub flowの方針は「<code>master</code>ブランチは常にデプロイ可能」である{{Refnest|"#1 - anything in the master branch is deployable.<br />This is basically the only hard ''rule'' of the system."{{R|scottchacon.com-github-flow}}}}。コードの変更を行う際にはトピックを名称とするブランチを<code>master</code>からforkする。マージ時を含め他者からの意見募集・レビューを行う際にはpull request(merge request)を用いる。pull request時に自動化テスト(c.f. [[継続的インテグレーション]])をおこなうことでmergeの安全性を確保し、<code>master</code>が常に正常 = デプロイ可能に保たれる。GitHub flowが有効な分野は[[継続的デリバリー]]・[[継続的デプロイメント]]が有効な分野、例えばWebサービスが挙げられる。 |
|||
2011年の提唱時と比較して、GitHub社ではモデルの一部を変更している。オリジナルのGitHub flowでは更新が<code>master</code>へマージされ、そこからデプロイされる。GitHub社ではレビュー後(CI後)のtopic branchが最終テストとしてプロダクション環境へデプロイされる。そこで問題がないと確認されたのちに<code>master</code>へmergeされている<ref>{{Cite web|url=https://guides.github.com/introduction/flow/ |title=GitHub Guides |accessdate=2020-05-31 |quote=With GitHub, you can deploy from a branch for final testing in production before merging to master.}}</ref>。このモデル変更により、CIで判明しなかったバグが発生した場合に<code>master</code>のrevert commitではなく<code>master</code>の再デプロイで対応できる。 |
|||
== マージ == |
|||
Gitはブランチの[[バージョン管理システム#%E3%83%AD%E3%83%83%E3%82%AF%E6%96%B9%E5%BC%8F%E3%81%A8%E3%82%B3%E3%83%94%E3%83%BC%E3%83%BB%E3%83%9E%E3%83%BC%E3%82%B8%E6%96%B9%E5%BC%8F|マージ]](merge)に対応している。 |
|||
マージが行われると'''マージコミット'''(英: merge commit)が生成される。コンフリクトが発生しない場合、<code>[https://git-scm.com/docs/git-merge git merge]</code>がマージコミットを自動生成する{{Refnest|"A merged version ... is committed, and your <code>HEAD</code>, index, and working tree are updated to it."<ref name="git_merge" group="git"/>}}。コンフリクトが発生した場合、まず安全な範囲がマージされインデックスとワーキングツリーが更新される{{Refnest|"Paths that merged cleanly are updated both in the index file and in your working tree."<ref name="git_merge" group="git" />}}。自動マージできないコンフリクト部は、ワーキングツリーに特定の記法で両方の変更が併記された状態になる{{Refnest|"When both sides made changes to the same area, however, Git cannot randomly pick one side over the other, and asks you to resolve it by leaving what both sides did to that area."<ref name="git_merge" group="git" />}}。ユーザーによるコンフリクト修正後<code>git add</code>をおこない、<code>git commit</code>あるいは<code>git merge --continue</code>をおこなってはじめてマージコミットが生成される{{Refnest|"Edit the files into shape and git add them to the index. Use git commit or git merge --continue to seal the deal."<ref name="git_merge" group="git" />}}。 |
|||
マージコミットの実体は2つ以上のparent属性を持つただのコミットオブジェクトである(特別なGitオブジェクトではない){{Refnest|"the branches to be merged must be tied together by a merge commit that has both of them as its parents."<ref name="git_merge" group="git" />}}。通常のコミットオブジェクトと同様に変更後ファイルセットがtreeに記録され、更新の元となっている(複数の)コミットがparentに設定されているだけである。 |
|||
== 注釈 == |
|||
{{Reflist|group="※"}} |
|||
== |
== 出典 == |
||
{{ |
{{Reflist|30em}} |
||
<references group="git"> |
|||
<ref name="git_merge">[https://git-scm.com/docs/git-merge git-merge - git] 2020-11-01閲覧</ref> |
|||
</references> |
|||
== 関連項目 == |
== 関連項目 == |
||
{{Portal|FLOSS|[[ファイル:FLOSS_logo. |
{{Portal|FLOSS|[[ファイル:FLOSS_logo.svg|41px]]}} |
||
*[[GitHub]] |
*[[GitHub]] |
||
*[[バージョン管理システム]] |
*[[バージョン管理システム]] |
||
*[[arch]] |
*[[GNU arch|arch]] |
||
*[[Bazaar]] |
*[[Bazaar]] |
||
*[[BitKeeper]] - Git以前にLinuxカーネル開発で使用されていたバージョン管理システム。ライセンス発行に関わる問題によりGitが開発されることとなった。 |
*[[BitKeeper]] - Git以前にLinuxカーネル開発で使用されていたバージョン管理システム。ライセンス発行に関わる問題によりGitが開発されることとなった。 |
||
*[[Concurrent Versions System |
*[[Concurrent Versions System]] (CVS) |
||
*[[Mercurial]] - Gitとほぼ同時期に開発が開始された。 |
*[[Mercurial]] - Gitとほぼ同時期に開発が開始された。 |
||
*[[Subversion]] |
*[[Apache Subversion]] |
||
== 外部リンク == |
== 外部リンク == |
||
*{{official website|name=Git}} - 公式ウェブサイト{{en icon}} |
|||
*[https://git-scm.com/ Git - Fast Version Control System] - Gitの公式サイト。 |
|||
*[https://www.kernel.org/pub/software/scm/git/ Gitの配布ディレクトリ |
*[https://www.kernel.org/pub/software/scm/git/ Index of /pub/software/scm/git/] - Gitの配布ディレクトリ |
||
*[https:// |
*[https://gitforwindows.org Git for Windows] - Windows版Gitの配布サイト。{{en icon}} |
||
*[https://git-scm.com/book/en |
*[https://git-scm.com/book/en Pro Git book]{{en icon}} |
||
*[https://git-scm.com/book/ja |
*[https://git-scm.com/book/ja Pro Git book]{{ja icon}} |
||
{{バージョン管理システム}} |
{{バージョン管理システム}} |
||
{{authority control}} |
|||
{{FLOSS-stub}} |
{{FLOSS-stub}} |
||
{{DEFAULTSORT:きつと}} |
{{DEFAULTSORT:きつと}} |
||
[[Category:Git|*]] |
|||
[[Category:バージョン管理システム]] |
[[Category:バージョン管理システム]] |
||
[[Category:オープンソースソフトウェア]] |
[[Category:オープンソースソフトウェア]] |
||
[[Category:2005年のソフトウェア]] |
[[Category:2005年のソフトウェア]] |
||
[[Category:リーナス・トーバルズ]] |
2024年3月8日 (金) 12:58時点における版
![]() | |
![]() GitのWebインターフェース、gitweb | |
開発元 | 濱野純, リーナス・トーバルズ, ほか多数 |
---|---|
初版 | 2005年12月21日 |
最新版 |
2.46.0[1] ![]() |
リポジトリ | |
プログラミング 言語 | C, Bourne Shell, Tcl, Perl |
対応OS | Unix系、Linux、Windows、macOS |
種別 | バージョン管理ソフトウェア |
ライセンス | GNU General Public License バージョン2,GNU Lesser General Public License 2.1 |
公式サイト |
git-scm |
Git(ギット[2][3])は、プログラムのソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システムである。Linuxカーネルのソースコード管理に用いるためにリーナス・トーバルズによって開発され、それ以降ほかの多くのプロジェクトで採用されている。Linuxカーネルのような巨大プロジェクトにも対応できるように、動作速度に重点が置かれている。現在のメンテナは濱野純 (英語: Junio C Hamano) で、2005年7月から担当している。
Gitでは、各ユーザのワーキングディレクトリに、全履歴を含んだリポジトリの完全な複製が作られる。したがって、ネットワークにアクセスできないなどの理由で中心リポジトリにアクセスできない環境でも、履歴の調査や変更の記録といったほとんどの作業を行うことができる。これが「分散型」と呼ばれる理由である。
背景および概要
Linuxカーネルの開発では、Linux Kernel Mailing List[※ 1] に投稿される多数のパッチをメンテナーたちがソースコードに適用するという形式が採用されている。これらの作業を効率的に行うため、当初はBitKeeperというバージョン管理システムを用いていたが、このソフトウェアは商用ソフトウェアであった(クライアントはバイナリ版のみ無料で、サーバは商用だがBitMover社の厚意で無料で使えていた)。この状況を快く思わない人々がBitKeeperのクローンを実装したことから、この環境が使えなくなってしまい(BitKeeper#ライセンス問題やBitKeeper#価格変更を参照)、その代替として2005年にGitが開発された[4]。
Linuxカーネルの開発では、巨大なソースコードの集合を扱うため、変更点の抽出やリポジトリ操作ができるかぎり高速にできる必要がある。他の様々なバージョン管理システムをあたったが、満足のいくものがなかったため、Gitではこのような問題も出来る限り解決できるよう、いくつかのアイデアが導入されている(この部分は、他のバージョン管理システムにも同様の機能が導入されるようになった)。
作業の流れ
Gitは分散型のソースコード管理システムであるため、リモートサーバ等にある中心リポジトリの完全なコピーを手元(ローカル環境)に作成して、そのローカルリポジトリを使って作業を行う。
一般的な開発スタイルでは、大雑把に言えば、以下のようなステップの繰り返しで作業が行なわれる:
- リモートサーバ等にある中心リポジトリをローカルに複製する (git clone)。
- ローカルでコンテンツの修正・追加・削除を行い、ローカルリポジトリに変更履歴を記録する (git commit)。必要に応じて過去の状態の閲覧や復元などを行う。場合によってはこのステップを何度か繰り返す。
- ローカルの変更内容を中心リポジトリに反映させる (git push)。作業者ごとの変更内容が衝突することもある。Gitが自動で解決できる場合もあれば、手動での解決 (git merge)が必要なこともある。
- 更新された中心リポジトリ(他者の作業内容も統合されている)をローカルの複製にも反映する (git pull)。これによりローカル環境のコードも最新の内容になるので、改めてステップ2の作業を行う。
リポジトリ間の通信 (clone, pull, push) では以下のプロトコルが使用できる[5]。
以前はrsyncも使用できたが、2.8.0で廃止された[9]。
設計
Gitの設計はBitKeeperとMonotoneが元になっている[10][11]。元々のGitはローレベルなエンジンとして設計されていたが、これは、他の開発者がCogitoやStGITのようなフロントエンドを容易に開発できるようにすることを目的としていた[12]。現在では、Gitのコア自体もユーザから直接利用できるようになっている[13]。
Gitの設計には、リーナスが大規模プロジェクトのメンテナンスを行った経験や、ファイルシステムのパフォーマンスに関する深い知識、また実用性のあるシステムを短期間に作成しなければならないという差し迫った必要性(BitKeeperを参照)が反映されている。これらの影響は、以下のような形で実装に現れている。
- ノンリニアな開発スタイルに対する強力なサポート。Gitではブランチやマージが高速に行える。また、ノンリニアな開発の履歴を可視化・ナビゲートするための専用のツールを同梱している。また、ツリーに対する1回の変更に対して、複数回のマージが発生するという前提を置いているが、これは変更点が複数のレビュアーによってレビューされることを想定しているためである。
- 分散開発。他の分散型バージョン管理システム(Mercurial、BitKeeper、Darcs、Bazaar、SVK、Monotone)と同様に、Gitでも各々の開発者がリポジトリの完全なコピーをローカルに保持しており、各開発者の行った変更は他のリポジトリにコピーされる。これらの変更は新しい開発用ブランチとしてインポートされる。また、ローカルな開発用ブランチへのマージも可能である。
- HTTP、FTP、gitプロトコル(sshを利用したトンネリングも可能)を使用したリポジトリの配布が可能。また、CVSサーバのエミュレーション機能を使用すれば、既存のCVSクライアントやIDEのプラグインからGitリポジトリにアクセスできる。
- git-svnを使用すれば、Subversionおよびsvkのリポジトリを直接操作できる。
- 大きなプロジェクトにおける処理の効率化。Gitは非常に高速かつスケーラブルになるよう記述されている[14]。Mozillaによって行われたパフォーマンステストでは、他のリビジョンコントロールシステムと比較して10倍、処理によっては100倍高速に動作することが示された[15][16]。
- ツールキット化された設計。gitはC言語で書かれたプログラム一式と、それらのラッパーとなる何本かのシェルスクリプトで構成されている[17]。GitをWindowsに移植する過程で、シェルスクリプトのほとんどはC言語で書き直された。しかし、現在でも複数のコンポーネントを繋げることで複雑な処理を容易に行えるような設計になっている[18]。
- プラガブルなマージアルゴリズム。Gitでは不完全なマージに対する優れたモデル化が行われている。また、不完全なマージを補完するアルゴリズムも複数存在する。最終的に自動的なマージが行えなかった場合には、ユーザによる編集が必要である旨がユーザに通知される。
- ガベージコレクションは行われない。操作を中断したり変更の取り消しを行った場合、データベース中には不要なデータが残ったままになる。これらのデータは操作対象のオブジェクトの履歴に比例して大きくなる。
git-gc --prune
コマンドを使用して明示的にガベージコレクションを行うこともできるが、この処理には時間がかかる[19]。
Gitの特徴の一つとして、ディレクトリツリーに対するスナップショットを作成する点が挙げられる。初期のバージョン管理システム(SCCSやRCS)では、個々のファイルを処理の対象としており、直近のバージョンに対して差分符号化を行うことでリポジトリのサイズを縮小することに機能の重点が置かれていた。以降のバージョン管理システムでも、この「プロジェクト内の複数バージョンにまたがって一つのファイルを追跡できる」という概念が継承されていた。
一方、Gitではこのコンセプトを使用していない[20]。その結果として、Gitはソースコードツリー中のファイルのリビジョン間の関係性を記録しなくなっている。これにより、Gitは以下のような特徴をもつようになっている。
- プロジェクト全体の変更履歴を調べるよりも、一つのファイルの変更履歴を調べる方が時間がかかる[21]。特定のファイルの変更履歴を取得する場合、Gitはツリーの履歴全体を走査し、各リビジョンでそのファイルに変更があったかどうか調査する必要がある。ただしこの処理手順では、一つのファイルに対しても、任意のファイルの集合に対しても、ほぼ同じ時間で履歴の調査が行える。よく行われる処理としては、例えば「ソースツリー中のあるサブディレクトリと、それに関係するヘッダファイルの調査を行う」といったものがある。
- ファイル名の変更を明示的に扱わない。CVSに対してよく挙げられる不満として、ファイルのリネームや移動を行うと変更履歴が途切れてしまう問題がある。これは、変更履歴の識別にファイル名を使用しているためである。CVS以降に開発されたバージョン管理システムの多くでは、管理対象のファイルに対してファイル名より寿命の長い、内部的な名前(inode番号のようなもの)を付与することでこの問題を解決している。一方、Gitではそのような内部名を使用しておらず、その点が長所であるとしている[22][23]。プログラムのソースコードに対しては、リネームの他にも分割やマージといった処理が行われる[24]。これらの処理を単純にファイルのリネームとして十把一絡げに扱うと、実際にソースコードツリーに対して行われた処理が何であるか不明瞭なまま履歴に記録されてしまう。Gitでは、リネームの検出をスナップショット作成時ではなく履歴のブラウズの際に行うことでこの問題を解決している[25]。(単純に考えれば、リビジョンN中のあるファイルに対して、リビジョンN-1中に同じ名前のファイルがあれば、それが元ファイルと考えられる。しかし、リビジョンN-1中に似たような名前のファイルがない場合もある。この場合Gitは、リビジョンN-1のみに存在し、かつ似たような内容のファイルを検索する。)しかし、この処理は履歴の表示を行う度にCPUに負荷のかかる処理が必要となる。そのため、使用するヒューリスティックを選択するオプションが提供されている。
リポジトリの保存方法については批判もある。
- Gitは新しく作成されたオブジェクトを個別のファイルの形で保存する。各ファイルは圧縮されて保存されるが、そうであったとしてもこの方法は記録領域を大量に必要とするため非効率的である。Gitはこの問題を“pack”を使用することで解決している。複数のオブジェクトは一つのファイル(またはネットワークバイトストリーム)の形にパックされ、各pack間で差分圧縮が行われる。packの差分圧縮にはヒューリスティックが用いられる。例えば、同じ名前のファイルは似た内容である可能性が高いものとして処理される。ただし、リポジトリの正確性を保つため、ヒューリスティックに完全に依存することはない。現在のGitでも新しく作成されたオブジェクト(新しく加えられた履歴)はまず単一のファイルとして保存されるため、空間効率を高く保つためには定期的な再パックが要求される。Gitはこの定期的な再パックを自動的に行うが、
git gc
コマンドを使用することで手動で再パックを行うこともできる。
Gitは以下のマージアルゴリズムを実装している。アルゴリズムはマージ時に選択することができる[26]。
- resolve
- 従来通りの3-wayマージアルゴリズムを使用する。
- recursive
- 3-wayマージの変種を使用する。ブランチのmergeやpullを行う場合のデフォルトである。3-wayマージにおいて共通の祖先が複数ある場合、共通の祖先からのmerge treeを作成し、それをreference treeとして3-wayマージを行う。Linuxカーネル2.6の開発で行われたマージコミットの履歴から、このアルゴリズムを使用するとマージの衝突が少なく、マージ漏れもなかったことが報告されている。さらに、リネームを伴うマージに対しても検出および処理が可能である[27]。
- octopus
- 3つ以上のheadからのマージを行う場合のデフォルトである。
歴史
名前の由来
リーナス・トーバルズによれば[28]、
「 | 僕は自己中心的な奴だから、自分のプロジェクトには自分にちなんだ名前を付けるようにしているんだ。最初はLinuxで、今度はGitだ。 | 」 |
英語のスラングとして、Gitには「バカ」「間抜け」といった類の意味がある。この自虐ネタはもちろん皮肉で、これはリーナスがLinuxの名前を決める際に自身の名前にちなんだ名前を付けるよう強要されたことから来ている。(Linux#名前の由来を参照)
Gitのオフィシャルサイトのウィキでは、“Git”という名前に対して他にもいくつかの解釈がなされている。例としてはGlobal Information Trackerなどが挙げられる[29]。
開発初期の歴史
Gitの開発は、Linuxカーネルの開発者の多くがBitKeeperのシステムに対するアクセスを禁止されたことに端を発している(BitKeeper#価格変更を参照)。これは、アンドリュー・トリジェル (Andrew Tridgell) がプロプラエタリなソフトウェアであるBitKeeperのプロトコルをリバースエンジニアリングしたことに対し、BitKeeperの著作者であるラリー・マクボイがこれをライセンス違反であるとして、BitKeeperの無料提供を止めたためである。Linux.conf.au 2005のキーノートにおいて、トリジェルはこのリバースエンジニアリングの手順について説明を行ったが、内容はBitKeeperのサーバの適切なポートにtelnetでアクセスし“help”とタイプするだけという単純なものだった[30]。
リーナスはBitKeeperと同じように使える分散型バージョン管理システムを探していたが、無料のシステムで彼の要求(特に速度面での要求)に適合するものは見つからなかった。リーナスが書いたメールによると、2005年4月7日頃に最初のプロトタイプを作成していたようである[31]。
「 |
だけど、僕が見たSCMたちはそれ(bk pull相当のこと)をするのが大変だったんだ。僕がやろうとしていることの1つは(実はこれが一番なんだけど)その過程を十分効率的にすること。もし1つのパッチを適用してその変更の境界を記録するなどするのに30秒かかったとすると(正直、Linux規模のプロジェクトで30秒っていうのは大抵のSCMでは速いほうの見積りだけど)、250通(例えばAndrew[※ 2] と同期するときには決して珍しい量じゃない)のメールパッチを適用するのに2時間かかることになる。 BKはスピード狂ではなくて、(他のSCMと比較するとBKは1桁か2桁くらいは高速だけど)Andrew[※ 2]とマージをする時に1メールにつき約10-15秒かかっていた。だけど、BKではそれは大きな問題にならなかったんだ。BK⇔BK間のマージは簡単だから、僕は他の主要な開発者とは時間がかかるメールでのマージをしたことはなかったから。パッチアプリケーションに基づいたSCMにするなら、"マージ機能" をBKよりも速くしなければならなくなる。それは本当に本当に大変なこと。 だから、僕はいまスクリプトを書いていて、変更をずっと速く追跡できるようにしているんだ。最初の目標はパッチを適用するのと同じくらい高速にそれを行うこと。だけどはっきりいって、今のところできたのは多く見積もってもまだ半分くらいで、思わぬ障害にぶつかったら全然嘘になるかもしれないけど。いずれにせよ、僕がそれをすぐにできる理由は、僕のスクリプトがSCMではないからで、とても特別で "Linuxの状態を記録する" ようなものだからなんだ。それはリニアなパッチを十分効率的な時間でマージできるようになるだろう。 (パッチの適用が3秒でできるなら、大きな1つながりのパッチでも問題にはならない: 途中で失敗しても1分か2分で気がつくなら、それで十分で、手作業で修正することができる。待ち時間が重要な理由はそこにある。-- "オフライン" で効果的にそれができるなら、問題が起きた時に僕は定義どおりそれを修理できずにいるだろう) |
」 |
リーナスは以下のような原則に基づいて設計を行っている。
- CVSを「悪い見本」とする。設計上のことで確信が持てない場合は、CVSと逆の決断をする。リーナスは冗談めかして以下のように語っている。
- “カーネルメンテナンスの最初の10年間、僕らは文字通りtarボールとパッチを使っていた。CVSよりもずっと優れたソース管理システムさ。僕は営利企業(トランスメタ[32])でCVSを7年間使わされたことで、CVSを強烈に憎むようになった。CVSを強烈に憎んでいると言う時には、このことも言っておかなくちゃいけないね。観衆の中にSVN (Subversion) のユーザがいるなら、この場から去ったほうがいいかもしれない。僕がCVSを強烈に嫌悪しているということは、僕がSubversionが史上最大の無意味なプロジェクトであると思っていることも意味しているんだ。Subversionのしばらくのスローガンは‘ちゃんとCVSをやる’とかそんなものだったよね。そんなスローガンから始めたら、どこにも辿りつけないよ。CVSをちゃんとやるなんて不可能なのさ。”[33]
- 分散型の、BitKeeperのようなワークフローをサポートする。
- “BitKeeperだけが、「まあ使ってもいいかな」と最初に思わせてくれたSCMだというわけではないけれど、BitkeeperはSCMというものの存在意義と、実際にどう使うことができるのかを教えてくれた。だから、Gitは技術的な観点とかいろんなところでBitkeeperとは随分違うものになっているけど(それはもう一つの設計目標でもある。Bitkeeperのクローンではないことをはっきりさせたかったから)、Gitのワークフローの多くは、Bitkeeperが教えてくれたフローから直接きたものになっているんだ。”[33]
- データ破壊に対する強力な抑止機能。データ破壊は、偶然によるものと意図的なものの両方を想定している[34][33]。
- 非常に高い処理速度。
最初の3つの条件によって、既存のバージョン管理システムはMonotoneを除き全て選に漏れてしまい、4つ目の条件で該当するものがなくなってしまった[33]。そのため、Linuxカーネル2.6.12-rc2のリリース直後に[33]、リーナスは自分で開発を始めた[33]。
Gitの開発は2005年4月3日に開始された[35]。プロジェクトとしてのアナウンスは4月6日に行われ[36]、4月7日にはセルフホスティングされるようになった[35]。4月18日には複数のブランチからのマージが最初に行われた[37]。4月29日にはリーナスの目標としていた処理速度が実現された。Linuxのカーネルツリーにパッチを当てるベンチマークで、初期のGitでは毎秒6.7個のパッチを処理している[38]。6月6日には、GitによるLinuxカーネル2.6.12のリリースが行われた[39]。
BitKeeperからの影響で、リーナスは従来と同じようなアプローチを意図的に避けており、結果としてGitは非常にユニークな設計になっている[40]。技術に長けたユーザがGitを利用できるようになるレベルまではリーナスが開発を行っており、その後、2005年6月26日にはプロジェクトへの主要な貢献者であった濱野純 (Junio C Hamano) にメンテナンスが引き継がれた[41]。濱野は2005年12月21日にバージョン1.0のリリースを行い[42]、2021年5月現在も彼がメンテナンスを行っている。
ブランチモデル
ソフトウェア開発におけるGitブランチの作成・更新モデルをブランチモデルと呼ぶ。
GitHub flow
GitHub flowはブランチモデルの一種である[43]。GitHub flowの方針は「master
ブランチは常にデプロイ可能」である[44]。コードの変更を行う際にはトピックを名称とするブランチをmaster
からforkする。マージ時を含め他者からの意見募集・レビューを行う際にはpull request(merge request)を用いる。pull request時に自動化テスト(c.f. 継続的インテグレーション)をおこなうことでmergeの安全性を確保し、master
が常に正常 = デプロイ可能に保たれる。GitHub flowが有効な分野は継続的デリバリー・継続的デプロイメントが有効な分野、例えばWebサービスが挙げられる。
2011年の提唱時と比較して、GitHub社ではモデルの一部を変更している。オリジナルのGitHub flowでは更新がmaster
へマージされ、そこからデプロイされる。GitHub社ではレビュー後(CI後)のtopic branchが最終テストとしてプロダクション環境へデプロイされる。そこで問題がないと確認されたのちにmaster
へmergeされている[45]。このモデル変更により、CIで判明しなかったバグが発生した場合にmaster
のrevert commitではなくmaster
の再デプロイで対応できる。
マージ
Gitはブランチのマージ(merge)に対応している。
マージが行われるとマージコミット(英: merge commit)が生成される。コンフリクトが発生しない場合、git merge
がマージコミットを自動生成する[46]。コンフリクトが発生した場合、まず安全な範囲がマージされインデックスとワーキングツリーが更新される[47]。自動マージできないコンフリクト部は、ワーキングツリーに特定の記法で両方の変更が併記された状態になる[48]。ユーザーによるコンフリクト修正後git add
をおこない、git commit
あるいはgit merge --continue
をおこなってはじめてマージコミットが生成される[49]。
マージコミットの実体は2つ以上のparent属性を持つただのコミットオブジェクトである(特別なGitオブジェクトではない)[50]。通常のコミットオブジェクトと同様に変更後ファイルセットがtreeに記録され、更新の元となっている(複数の)コミットがparentに設定されているだけである。
注釈
- ^ LKML.ORG - the Linux Kernel Mailing List Archive
- ^ a b ここでは -mm ツリーメンテナのアンドリュー・モートンを指す。
出典
- ^ 濱野 純; "[ANNOUNCE Git v2.46.0"]; 出版日: 2024年7月29日; 閲覧日: 2024年7月29日.
- ^ Tech Talk: Linus Torvalds on git. 該当時間: 1分30秒. 2014年7月21日閲覧。
- ^ “Git - IT用語辞典e-words”. 2014年7月29日閲覧。
- ^ Scott Chacon「1.2 使い始める-Git略史」『Pro Git』 。2021年3月7日閲覧。
- ^ a b c d e Scott Chacon. “4.1 Git サーバー - プロトコル”. 2013年1月19日閲覧。
- ^ Scott Chacon; Ben Straub. “Pro Git 2nd Edition 4.6 Gitサーバー - Smart HTTP”. 2021年8月26日閲覧。
- ^ “Git - user-manual Documentation” (英語). 2021年8月26日閲覧。 “(See also setup-git-server-over-http for a slightly more sophisticated setup using WebDAV which also allows pushing over HTTP.)”
- ^ “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 (5 May 2006). "Re: [ANNOUNCE] Git wiki". linux-kernel (Mailing list). 2009年3月3日閲覧。 Gitの元となったプログラムに関する歴史的経緯
- ^ Linus Torvalds (7 April 2005). "Re: Kernel SCM saga". linux-kernel (Mailing list). 2009年3月3日閲覧。
- ^ Linus Torvalds (8 April 2005). "Re: Kernel SCM saga". linux-kernel (Mailing list). 2008年2月20日閲覧。
- ^ Linus Torvalds (23 March 2006). "Re: Errors GITtifying GCC and Binutils". Git (Mailing list). 2009年3月3日閲覧。
- ^ Linus Torvalds (19 October 2006). "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 (18 October 2006). "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 (10 April 2005). "Re: more git updates." linux-kernel (Mailing list). 2009年3月3日閲覧。
- ^ Bruno Haible (11 February 2007). "how to speed up "git log"?". Git (Mailing list). 2009年3月3日閲覧。
- ^ Linus Torvalds (1 March 2006). "Re: impure renames / history tracking". Git (Mailing list). 2009年3月3日閲覧。
- ^ Junio C Hamano (24 March 2006). "Re: Errors GITtifying GCC and Binutils". Git (Mailing list). 2009年3月3日閲覧。
- ^ Junio C Hamano (23 March 2006). "Re: Errors GITtifying GCC and Binutils". Git (Mailing list). 2009年3月3日閲覧。
- ^ Linus Torvalds (28 November 2006). "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日閲覧。
- ^ “After controversy, Torvalds begins work on git”. InfoWorld. (2005-04-19). ISSN 0199-6649 2008年2月20日閲覧。.
- ^ “GitFaq: Why the 'git' name?”. 2007年3月21日閲覧。
- ^ Jonathan Corbet (2005-04-20), “How Tridge reverse engineered BitKeeper”, Linux Weekly News 2009年3月26日閲覧。
- ^ Linus Torvalds (7 April 2005). "Re: Kernel SCM saga." linux-kernel (Mailing list). 2009年3月26日閲覧。
- ^ Linus Torvalds (31 October 2005). "Re: git versus CVS (versus bk)". Git (Mailing list). 2009年3月26日閲覧。
- ^ a b c d e f Linus Torvalds (3 May 2007). Google tech talk: Linus Torvalds on git. 該当時間: 02:30. 2007年5月16日閲覧。
- ^ Linus Torvalds (10 June 2007). "Re: fatal: serious inflate inconsistency". Git (Mailing list). 2009年3月26日閲覧。 Gitにおけるデータの完全性に関する設計目標に関する概要説明。
- ^ a b Linus Torvalds (27 February 2007). "Re: Trivia: When did git self-host?". Git (Mailing list). 2009年3月26日閲覧。
- ^ Linus Torvalds (6 April 2005). "Kernel SCM saga." linux-kernel (Mailing list). 2009年3月26日閲覧。
- ^ Linus Torvalds (17 April 2005). "First ever real kernel git merge!". Git (Mailing list). 2009年3月26日閲覧。
- ^ Matt Mackall (29 April 2005). "Mercurial 0.4b vs git patchbomb benchmark". Git (Mailing list). 2009年3月26日閲覧。
- ^ Linus Torvalds (17 June 2005). "Linux 2.6.12". git-commits-head (Mailing list). 2009年3月26日閲覧。
- ^ Linus Torvalds (20 October 2006). "Re: VCS comparison table". Git (Mailing list). 2009年3月26日閲覧。 Git vs. BitKeeperの議論
- ^ Linus Torvalds (27 July 2005). "Meet the new maintainer..." Git (Mailing list). 2009年3月26日閲覧。
- ^ 濱野純 (Junio C Hamano) (21 December 2005). "ANNOUNCE: GIT 1.0.0". Git (Mailing list). 2009年3月26日閲覧。
- ^ a b Scott Chacon (2011年8月31日). “GitHub Flow”. 2020年5月31日閲覧。
- ^ "#1 - anything in the master branch is deployable.
This is basically the only hard rule of the system."[43] - ^ “GitHub Guides”. 2020年5月31日閲覧。 “With GitHub, you can deploy from a branch for final testing in production before merging to master.”
- ^ "A merged version ... is committed, and your
HEAD
, index, and working tree are updated to it."[git 1] - ^ "Paths that merged cleanly are updated both in the index file and in your working tree."[git 1]
- ^ "When both sides made changes to the same area, however, Git cannot randomly pick one side over the other, and asks you to resolve it by leaving what both sides did to that area."[git 1]
- ^ "Edit the files into shape and git add them to the index. Use git commit or git merge --continue to seal the deal."[git 1]
- ^ "the branches to be merged must be tied together by a merge commit that has both of them as its parents."[git 1]
関連項目
- GitHub
- バージョン管理システム
- arch
- Bazaar
- BitKeeper - Git以前にLinuxカーネル開発で使用されていたバージョン管理システム。ライセンス発行に関わる問題によりGitが開発されることとなった。
- Concurrent Versions System (CVS)
- Mercurial - Gitとほぼ同時期に開発が開始された。
- Apache Subversion
外部リンク
- Git - 公式ウェブサイト
- Index of /pub/software/scm/git/ - Gitの配布ディレクトリ
- Git for Windows - Windows版Gitの配布サイト。
- Pro Git book
- Pro Git book