(Go: >> BACK << -|- >> HOME <<)

コンテンツにスキップ

「Git」の版間の差分

出典: フリー百科事典『ウィキペディア(Wikipedia)』
削除された内容 追加された内容
編集の要約なし
14行目: 14行目:
| frequently updated = yes <!-- バージョン情報は[[Template:Latest stable software release/Git]]。 -->
| frequently updated = yes <!-- バージョン情報は[[Template:Latest stable software release/Git]]。 -->
}}
}}
'''Git'''(ギット<ref>[https://www.youtube.com/watch?feature=player_detailpage&v=4XpnKHJAok8#t=88 Tech Talk: Linus Torvalds on git (1分30秒の発音)]</ref><ref>[http://e-words.jp/w/Git.html Git - IT用語辞典e-words]</ref><ref>[http://it-words.jp/w/Git.html Git - IT用語辞典 - 日立ソリューションズ]</ref><!-- ジットと読む場合も → ジットが正しくないことは[2]で明らか -->)は、[[プログラム (コンピュータ)|プログラム]]の[[ソースコード]]などの変更履歴を記録・追跡するための分散型[[バージョン管理システム]]である。[[Linuxカーネル]]のソースコード管理に用いるために[[リーナス・トーバルズ]]によって開発され、それ以降ほかの多くのプロジェクトで採用されている。Linuxカーネルのような巨大プロジェクトにも対応できるように、動作速度に重点が置かれている。現在のメンテナは[[濱野純]] ({{Lang-en|Junio C Hamano}}) で、2005年7月から担当している。
'''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><ref>{{Cite web|url=http://it-words.jp/w/Git.html |title=Git - IT用語辞典 - 日立ソリューションズ |accessdate=2014-07-29 |deadlinkdate=2020-05-26 |archiveurl=https://web.archive.org/web/20141211120908/http://it-words.jp/w/Git.html |archivedate=2014-12-11}}</ref>)は、[[プログラム (コンピュータ)|プログラム]]の[[ソースコード]]などの変更履歴を記録・追跡するための分散型[[バージョン管理システム]]である。[[Linuxカーネル]]のソースコード管理に用いるために[[リーナス・トーバルズ]]によって開発され、それ以降ほかの多くのプロジェクトで採用されている。Linuxカーネルのような巨大プロジェクトにも対応できるように、動作速度に重点が置かれている。現在のメンテナは[[濱野純]] ({{Lang-en|Junio C Hamano}}) で、2005年7月から担当している。


Gitでは、各ユーザのワーキングディレクトリに、全履歴を含んだ[[リポジトリ]]の完全な複製が作られる。したがって、[[コンピュータネットワーク|ネットワーク]]にアクセスできないなどの理由で中心リポジトリにアクセスできない環境でも、履歴の調査や変更の記録といったほとんどの作業を行うことができる。これが「分散型」と呼ばれる理由である。
Gitでは、各ユーザのワーキングディレクトリに、全履歴を含んだ[[リポジトリ]]の完全な複製が作られる。したがって、[[コンピュータネットワーク|ネットワーク]]にアクセスできないなどの理由で中心リポジトリにアクセスできない環境でも、履歴の調査や変更の記録といったほとんどの作業を行うことができる。これが「分散型」と呼ばれる理由である。


== 背景および概要 ==
== 背景および概要 ==
Linuxカーネルの開発では、[https://lkml.org/ Linux Kernel Mailing List]に投稿される多数のパッチをメンテナーたちがソースコードに適用するという形式が採用されている。これらの作業を効率的に行うため、当初は[[BitKeeper]]というバージョン管理システムを用いていたが、このソフトウェアは[[プロプライエタリ・ソフトウェア|商用ソフトウェア]]であった([[クライアント (コンピュータ)|クライアント]]はバイナリ版のみ無料で、[[サーバ]]は商用だがBitMover社の厚意で無料で使えていた)。この状況を快く思わない人々がBitKeeperのクローンを実装したことから、この環境が使えなくなってしまい([[BitKeeper#ライセンス問題]]や[[BitKeeper#価格変更]]を参照)、その代替として2005年にGitが開発された。<ref>「[http://git-scm.com/book/ja/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-Git%E7%95%A5%E5%8F%B2 使い始める-Git略史]」『Git Pro Git --distributed-is-the-new-centralized</ref>
Linuxカーネルの開発では、[https://lkml.org/ Linux Kernel Mailing List]に投稿される多数のパッチをメンテナーたちがソースコードに適用するという形式が採用されている。これらの作業を効率的に行うため、当初は[[BitKeeper]]というバージョン管理システムを用いていたが、このソフトウェアは[[プロプライエタリ・ソフトウェア|商用ソフトウェア]]であった([[クライアント (コンピュータ)|クライアント]]はバイナリ版のみ無料で、[[サーバ]]は商用だがBitMover社の厚意で無料で使えていた)。この状況を快く思わない人々がBitKeeperのクローンを実装したことから、この環境が使えなくなってしまい([[BitKeeper#ライセンス問題]]や[[BitKeeper#価格変更]]を参照)、その代替として2005年にGitが開発された。<ref>{{Cite book|和書|url=http://git-scm.com/book/ja/%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=2012-12-08}}</ref>


Linuxカーネルの開発では、巨大なソースコードの集合を扱うため、変更点の抽出やリポジトリ操作ができるかぎり高速にできる必要がある。他の様々なバージョン管理システムをあたったが、満足のいくものがなかったため、Gitではこのような問題も出来る限り解決できるよう、いくつかのアイデアが導入されている(この部分は、他のバージョン管理システムにも同様の機能が導入されるようになった)。
Linuxカーネルの開発では、巨大なソースコードの集合を扱うため、変更点の抽出やリポジトリ操作ができるかぎり高速にできる必要がある。他の様々なバージョン管理システムをあたったが、満足のいくものがなかったため、Gitではこのような問題も出来る限り解決できるよう、いくつかのアイデアが導入されている(この部分は、他のバージョン管理システムにも同様の機能が導入されるようになった)。
174行目: 174行目:
リポジトリの保存方法については批判もある。
リポジトリの保存方法については批判もある。


* Gitは新しく作成されたオブジェクトを個別のファイルの形で保存する。各ファイルは圧縮されて保存されるが、そうであったとしてもこの方法は記録領域を大量に必要とするため非効率的である。Gitはこの問題を“pack”を使用することで解決している。複数のオブジェクトは一つのファイル(またはネットワークバイトストリーム)の形にパックされ、各pack間で差分圧縮が行われる。packの差分圧縮には[[ヒューリスティック]]が用いられる。例えば、同じ名前のファイルは似た内容である可能性が高いものとして処理される。ただし、リポジトリの正確性を保つため、ヒューリスティックに完全に依存することはない。現在のGitでも新しく作成されたオブジェクト(新しく加えられた履歴)はまず単一のファイルとして保存されるため、空間効率を高く保つためには定期的な再パックが要求される。Gitはこの定期的な再パックを自動的に行うが、<tt>git gc</tt>コマンドを使用することで手動で再パックを行うこともできる。
* Gitは新しく作成されたオブジェクトを個別のファイルの形で保存する。各ファイルは圧縮されて保存されるが、そうであったとしてもこの方法は記録領域を大量に必要とするため非効率的である。Gitはこの問題を“pack”を使用することで解決している。複数のオブジェクトは一つのファイル(またはネットワークバイトストリーム)の形にパックされ、各pack間で差分圧縮が行われる。packの差分圧縮には[[ヒューリスティック]]が用いられる。例えば、同じ名前のファイルは似た内容である可能性が高いものとして処理される。ただし、リポジトリの正確性を保つため、ヒューリスティックに完全に依存することはない。現在のGitでも新しく作成されたオブジェクト(新しく加えられた履歴)はまず単一のファイルとして保存されるため、空間効率を高く保つためには定期的な再パックが要求される。Gitはこの定期的な再パックを自動的に行うが、<code>git gc</code>コマンドを使用することで手動で再パックを行うこともできる。


Gitは以下のマージアルゴリズムを実装している。アルゴリズムはマージ時に選択することができる<ref>{{cite web
Gitは以下のマージアルゴリズムを実装している。アルゴリズムはマージ時に選択することができる<ref>{{cite web
199行目: 199行目:
英語のスラングとして、Gitには「バカ」「間抜け」といった類の意味がある。この自虐ネタはもちろん皮肉で、これはリーナスがLinuxの名前を決める際に自身の名前にちなんだ名前を付けるよう強要されたことから来ている。([[Linux#名前の由来]]を参照)
英語のスラングとして、Gitには「バカ」「間抜け」といった類の意味がある。この自虐ネタはもちろん皮肉で、これはリーナスがLinuxの名前を決める際に自身の名前にちなんだ名前を付けるよう強要されたことから来ている。([[Linux#名前の由来]]を参照)


Gitのオフィシャルサイトの[[ウィキ]]では、“Git”という名前に対して他にもいくつかの解釈がなされている。例としては''Global Information Tracker''などが挙げられる<ref>[http://git.or.cz/gitwiki/GitFaq#head-90fa13ebe170116f1586156e73b549cc2135b784 GitFaq: Why the 'git' name?]</ref>。
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>。


=== 開発初期の歴史 ===
=== 開発初期の歴史 ===
223行目: 223行目:
だけど、僕が見た[[バージョン管理システム|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 name="andrews">ここでは [[mmツリー|-mm ツリー]]メンテナの[[アンドリュー・モートン]]を指す。</ref> と同期するときには決して珍しい量じゃない)のメールパッチを適用するのに2時間かかることになる。


BKはスピード狂ではなくて、(他のSCMと比較するとBKは1桁か2桁くらいは高速だけど)Andrew<ref name="andrews"></ref>とマージをする時に1メールにつき約10-15秒かかっていた。だけど、BKではそれは大きな問題にならなかったんだ。BK⇔BK間のマージは簡単だから、僕は他の主要な開発者とは時間がかかるメールでのマージをしたことはなかったから。パッチアプリケーションに基づいたSCMにするなら、"マージ機能" をBKよりも''速く''しなければならなくなる。それは本当に本当に大変なこと。
BKはスピード狂ではなくて、(他のSCMと比較するとBKは1桁か2桁くらいは高速だけど)Andrew<ref name="andrews" />とマージをする時に1メールにつき約10-15秒かかっていた。だけど、BKではそれは大きな問題にならなかったんだ。BK⇔BK間のマージは簡単だから、僕は他の主要な開発者とは時間がかかるメールでのマージをしたことはなかったから。パッチアプリケーションに基づいたSCMにするなら、"マージ機能" をBKよりも''速く''しなければならなくなる。それは本当に本当に大変なこと。


だから、僕はいまスクリプトを書いていて、変更をずっと速く追跡できるようにしているんだ。最初の目標はパッチを適用するのと同じくらい高速にそれを行うこと。だけどはっきりいって、今のところできたのは多く見積もってもまだ半分くらいで、思わぬ障害にぶつかったら全然嘘になるかもしれないけど。いずれにせよ、僕がそれをすぐにできる理由は、僕のスクリプトがSCMではないからで、とても特別で "Linuxの状態を記録する" ようなものだからなんだ。それはリニアなパッチを十分効率的な時間でマージできるようになるだろう。
だから、僕はいまスクリプトを書いていて、変更をずっと速く追跡できるようにしているんだ。最初の目標はパッチを適用するのと同じくらい高速にそれを行うこと。だけどはっきりいって、今のところできたのは多く見積もってもまだ半分くらいで、思わぬ障害にぶつかったら全然嘘になるかもしれないけど。いずれにせよ、僕がそれをすぐにできる理由は、僕のスクリプトがSCMではないからで、とても特別で "Linuxの状態を記録する" ようなものだからなんだ。それはリニアなパッチを十分効率的な時間でマージできるようになるだろう。
326行目: 326行目:


=== GitHub flow ===
=== GitHub flow ===
GitHub flowはブランチモデルの一種である<ref>[http://scottchacon.com/2011/08/31/github-flow.html SCOTT CHACON (2011-08-31) "GitHub Flow"]</ref>。GitHub flowの方針は「<code>master</code>ブランチは常にデプロイ可能」である<ref>#1 - anything in the master branch is deployable. This is basically the only hard ''rule'' of the system. [http://scottchacon.com/2011/08/31/github-flow.html SCOTT CHACON (2011-08-31) "GitHub Flow"]</ref>。コードの変更を行う際にはトピックを名称とするブランチを<code>master</code>からforkする。マージ時を含め他者からの意見募集・レビューを行う際にはpull request(merge request)を用いる。pull request時に自動化テスト(c.f. [[継続的インテグレーション]])をおこなうことでmergeの安全性を確保し、<code>master</code>が常に正常 = デプロイ可能に保たれる。GitHub flowが有効な分野は[[継続的デリバリー]]・[[継続的デプロイメント]]が有効な分野、例えばWebサービスが挙げられる。
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>With GitHub, you can deploy from a branch for final testing in production before merging to master. [https://guides.github.com/introduction/flow/ GitHub Guides]</ref>。このモデル変更により、CIで判明しなかったバグが発生した場合に<code>master</code>のrevert commitではなく<code>master</code>の再デプロイで対応できる。
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>の再デプロイで対応できる。


== 脚注 ==
== 脚注 ==
{{reflist|2}}
{{reflist|2}}

^ Git - IT用語辞典 - 日立ソリューションズのページはリンク切れている。修正を求む


== 関連項目 ==
== 関連項目 ==

2020年10月31日 (土) 18:45時点における版

Git
git logo
GitのWebインターフェース、gitweb
開発元 濱野純, リーナス・トーバルズ, ほか多数
初版 2005年12月21日 (18年前) (2005-12-21)
最新版 2.45.2[1] ウィキデータを編集 - 2024年5月31日 (38日前) [±]
リポジトリ ウィキデータを編集
プログラミング
言語
C, Bourne Shell, Tcl, Perl
対応OS Unix系LinuxWindowsmacOS
種別 バージョン管理ソフトウェア
ライセンス GNU General Public License バージョン2,GNU Lesser General Public License 2.1
公式サイト git-scm.com ウィキデータを編集
テンプレートを表示

Git(ギット[2][3][4])は、プログラムソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システムである。Linuxカーネルのソースコード管理に用いるためにリーナス・トーバルズによって開発され、それ以降ほかの多くのプロジェクトで採用されている。Linuxカーネルのような巨大プロジェクトにも対応できるように、動作速度に重点が置かれている。現在のメンテナは濱野純 (英語: Junio C Hamano) で、2005年7月から担当している。

Gitでは、各ユーザのワーキングディレクトリに、全履歴を含んだリポジトリの完全な複製が作られる。したがって、ネットワークにアクセスできないなどの理由で中心リポジトリにアクセスできない環境でも、履歴の調査や変更の記録といったほとんどの作業を行うことができる。これが「分散型」と呼ばれる理由である。

背景および概要

Linuxカーネルの開発では、Linux Kernel Mailing Listに投稿される多数のパッチをメンテナーたちがソースコードに適用するという形式が採用されている。これらの作業を効率的に行うため、当初はBitKeeperというバージョン管理システムを用いていたが、このソフトウェアは商用ソフトウェアであった(クライアントはバイナリ版のみ無料で、サーバは商用だがBitMover社の厚意で無料で使えていた)。この状況を快く思わない人々がBitKeeperのクローンを実装したことから、この環境が使えなくなってしまい(BitKeeper#ライセンス問題BitKeeper#価格変更を参照)、その代替として2005年にGitが開発された。[5]

Linuxカーネルの開発では、巨大なソースコードの集合を扱うため、変更点の抽出やリポジトリ操作ができるかぎり高速にできる必要がある。他の様々なバージョン管理システムをあたったが、満足のいくものがなかったため、Gitではこのような問題も出来る限り解決できるよう、いくつかのアイデアが導入されている(この部分は、他のバージョン管理システムにも同様の機能が導入されるようになった)。

作業の流れ

Gitは分散型のソースコード管理システムであるため、リモートサーバ等にある中心リポジトリの完全なコピーを手元(ローカル環境)に作成して、そのローカルリポジトリを使って作業を行う。

一般的な開発スタイルでは、大雑把に言えば、以下のようなステップの繰り返しで作業が行なわれる:

  1. リモートサーバ等にある中心リポジトリをローカルに複製する (git clone)。
  2. ローカルでコンテンツの修正・追加・削除を行い、ローカルリポジトリに変更履歴を記録する (git commit)。必要に応じて過去の状態の閲覧や復元などを行う。場合によってはこのステップを何度か繰り返す。
  3. ローカルの変更内容を中心リポジトリに反映させる (git push)。作業者ごとの変更内容が衝突することもある。Gitが自動で解決できる場合もあれば、手動での解決 (git merge)が必要なこともある。
  4. 更新された中心リポジトリ(他者の作業内容も統合されている)をローカルの複製にも反映する (git pull)。これによりローカル環境のコードも最新の内容になるので、改めてステップ2の作業を行う。

リポジトリ間の通信 (clone, pull, push) では以下のプロトコルが使用できる[6]

以前はrsyncも使用できたが、2.8.0で廃止された[8]

設計

Gitの設計はBitKeeperMonotoneが元になっている[9][10]。元々のGitはローレベルなエンジンとして設計されていたが、これは、他の開発者がCogitoStGITのようなフロントエンドを容易に開発できるようにすることを目的としていた[11]。現在では、Gitのコア自体もユーザから直接利用できるようになっている[12]

Gitの設計には、リーナスが大規模プロジェクトのメンテナンスを行った経験や、ファイルシステムのパフォーマンスに関する深い知識、また実用性のあるシステムを短期間に作成しなければならないという差し迫った必要性(BitKeeperを参照)が反映されている。これらの影響は、以下のような形で実装に現れている。

  • ノンリニアな開発スタイルに対する強力なサポート。Gitではブランチやマージが高速に行える。また、ノンリニアな開発の履歴を可視化・ナビゲートするための専用のツールを同梱している。また、ツリーに対する1回の変更に対して、複数回のマージが発生するという前提を置いているが、これは変更点が複数のレビュアーによってレビューされることを想定しているためである。
  • 分散開発。他の分散型バージョン管理システム(MercurialBitKeeperDarcsBazaarSVKMonotone)と同様に、Gitでも各々の開発者がリポジトリの完全なコピーをローカルに保持しており、各開発者の行った変更は他のリポジトリにコピーされる。これらの変更は新しい開発用ブランチとしてインポートされる。また、ローカルな開発用ブランチへのマージも可能である。
  • HTTPFTP、gitプロトコル(sshを利用したトンネリングも可能)を使用したリポジトリの配布が可能。また、CVSサーバのエミュレーション機能を使用すれば、既存のCVSクライアントやIDEのプラグインからGitリポジトリにアクセスできる。
  • git-svnを使用すれば、Subversionおよびsvkのリポジトリを直接操作できる。
  • 大きなプロジェクトにおける処理の効率化。Gitは非常に高速かつスケーラブルになるよう記述されている[13]Mozillaによって行われたパフォーマンステストでは、他のリビジョンコントロールシステムと比較して10倍、処理によっては100倍高速に動作することが示された[14][15]
  • ツールキット化された設計。gitはC言語で書かれたプログラム一式と、それらのラッパーとなる何本かのシェルスクリプトで構成されている[16]。GitをWindowsに移植する過程で、シェルスクリプトのほとんどはC言語で書き直された。しかし、現在でも複数のコンポーネントを繋げることで複雑な処理を容易に行えるような設計になっている[17]
  • プラガブルなマージアルゴリズム。Gitでは不完全なマージに対する優れたモデル化が行われている。また、不完全なマージを補完するアルゴリズムも複数存在する。最終的に自動的なマージが行えなかった場合には、ユーザによる編集が必要である旨がユーザに通知される。
  • ガベージコレクションは行われない。操作を中断したり変更の取り消しを行った場合、データベース中には不要なデータが残ったままになる。これらのデータは操作対象のオブジェクトの履歴に比例して大きくなる。git-gc --pruneコマンドを使用して明示的にガベージコレクションを行うこともできるが、この処理には時間がかかる[18]

Gitの特徴の一つとして、ディレクトリツリーに対するスナップショットを作成する点が挙げられる。初期のバージョン管理システム(SCCSRCS)では、個々のファイルを処理の対象としており、直近のバージョンに対して差分符号化を行うことでリポジトリのサイズを縮小することに機能の重点が置かれていた。以降のバージョン管理システムでも、この「プロジェクト内の複数バージョンにまたがって一つのファイルを追跡できる」という概念が継承されていた。

一方、Gitではこのコンセプトを使用していない[19]。その結果として、Gitはソースコードツリー中のファイルのリビジョン間の関係性を記録しなくなっている。これにより、Gitは以下のような特徴をもつようになっている。

  • プロジェクト全体の変更履歴を調べるよりも、一つのファイルの変更履歴を調べる方が時間がかかる[20]。特定のファイルの変更履歴を取得する場合、Gitはツリーの履歴全体を走査し、各リビジョンでそのファイルに変更があったかどうか調査する必要がある。ただしこの処理手順では、一つのファイルに対しても、任意のファイルの集合に対しても、ほぼ同じ時間で履歴の調査が行える。よく行われる処理としては、例えば「ソースツリー中のあるサブディレクトリと、それに関係するヘッダファイルの調査を行う」といったものがある。
  • ファイル名の変更を明示的に扱わない。CVSに対してよく挙げられる不満として、ファイルのリネームや移動を行うと変更履歴が途切れてしまう問題がある。これは、変更履歴の識別にファイル名を使用しているためである。CVS以降に開発されたバージョン管理システムの多くでは、管理対象のファイルに対してファイル名より寿命の長い、内部的な名前(inode番号のようなもの)を付与することでこの問題を解決している。一方、Gitではそのような内部名を使用しておらず、その点が長所であるとしている[21][22]。プログラムのソースコードに対しては、リネームの他にも分割やマージといった処理が行われる[23]。これらの処理を単純にファイルのリネームとして十把一絡げに扱うと、実際にソースコードツリーに対して行われた処理が何であるか不明瞭なまま履歴に記録されてしまう。Gitでは、リネームの検出をスナップショット作成時ではなく履歴のブラウズの際に行うことでこの問題を解決している[24]。(単純に考えれば、リビジョンN中のあるファイルに対して、リビジョンN-1中に同じ名前のファイルがあれば、それが元ファイルと考えられる。しかし、リビジョンN-1中に似たような名前のファイルがない場合もある。この場合Gitは、リビジョンN-1のみに存在し、かつ似たような内容のファイルを検索する。)しかし、この処理は履歴の表示を行う度にCPUに負荷のかかる処理が必要となる。そのため、使用するヒューリスティックを選択するオプションが提供されている。

リポジトリの保存方法については批判もある。

  • Gitは新しく作成されたオブジェクトを個別のファイルの形で保存する。各ファイルは圧縮されて保存されるが、そうであったとしてもこの方法は記録領域を大量に必要とするため非効率的である。Gitはこの問題を“pack”を使用することで解決している。複数のオブジェクトは一つのファイル(またはネットワークバイトストリーム)の形にパックされ、各pack間で差分圧縮が行われる。packの差分圧縮にはヒューリスティックが用いられる。例えば、同じ名前のファイルは似た内容である可能性が高いものとして処理される。ただし、リポジトリの正確性を保つため、ヒューリスティックに完全に依存することはない。現在のGitでも新しく作成されたオブジェクト(新しく加えられた履歴)はまず単一のファイルとして保存されるため、空間効率を高く保つためには定期的な再パックが要求される。Gitはこの定期的な再パックを自動的に行うが、git gcコマンドを使用することで手動で再パックを行うこともできる。

Gitは以下のマージアルゴリズムを実装している。アルゴリズムはマージ時に選択することができる[25]

resolve
従来通りの3-wayマージアルゴリズムを使用する。
recursive
3-wayマージの変種を使用する。ブランチのmergeやpullを行う場合のデフォルトである。3-wayマージにおいて共通の祖先が複数ある場合、共通の祖先からのmerge treeを作成し、それをreference treeとして3-wayマージを行う。Linuxカーネル2.6の開発で行われたマージコミットの履歴から、このアルゴリズムを使用するとマージの衝突が少なく、マージ漏れもなかったことが報告されている。さらに、リネームを伴うマージに対しても検出および処理が可能である[26]
octopus
3つ以上のheadからのマージを行う場合のデフォルトである。

歴史

名前の由来

リーナス・トーバルズによれば[27]

僕は自己中心的な奴だから、自分のプロジェクトには自分にちなんだ名前を付けるようにしているんだ。最初はLinuxで、今度はGitだ。

英語のスラングとして、Gitには「バカ」「間抜け」といった類の意味がある。この自虐ネタはもちろん皮肉で、これはリーナスがLinuxの名前を決める際に自身の名前にちなんだ名前を付けるよう強要されたことから来ている。(Linux#名前の由来を参照)

Gitのオフィシャルサイトのウィキでは、“Git”という名前に対して他にもいくつかの解釈がなされている。例としてはGlobal Information Trackerなどが挙げられる[28]

開発初期の歴史

Gitの開発は、Linuxカーネルの開発者の多くがBitKeeperのシステムに対するアクセスを禁止されたことに端を発している(BitKeeper#価格変更を参照)。これは、アンドリュー・トリジェル (Andrew Tridgell) がプロプラエタリなソフトウェアであるBitKeeperのプロトコルをリバースエンジニアリングしたことに対し、BitKeeperの著作者であるラリー・マクボイがこれをライセンス違反であるとして、BitKeeperの無料提供を止めたためである。Linux.conf.au 2005のキーノートにおいて、Tridgellはこのリバースエンジニアリングの手順について説明を行ったが、内容はBitKeeperのサーバの適切なポートにtelnetでアクセスし“help”とタイプするだけという単純なものだった[29]

リーナスはBitKeeperと同じように使える分散型バージョン管理システムを探していたが、無料のシステムで彼の要求(特に速度面での要求)に適合するものは見つからなかった。リーナスが書いたメールによると、2005年4月7日頃に最初のプロトタイプを作成していたようである[30]

だけど、僕が見たSCMたちはそれ(bk pull相当のこと)をするのが大変だったんだ。僕がやろうとしていることの1つは(実はこれが一番なんだけど)その過程を十分効率的にすること。もし1つのパッチを適用してその変更の境界を記録するなどするのに30秒かかったとすると(正直、Linux規模のプロジェクトで30秒っていうのは大抵のSCMでは速いほうの見積りだけど)、250通(例えばAndrew[31] と同期するときには決して珍しい量じゃない)のメールパッチを適用するのに2時間かかることになる。

BKはスピード狂ではなくて、(他のSCMと比較するとBKは1桁か2桁くらいは高速だけど)Andrew[31]とマージをする時に1メールにつき約10-15秒かかっていた。だけど、BKではそれは大きな問題にならなかったんだ。BK⇔BK間のマージは簡単だから、僕は他の主要な開発者とは時間がかかるメールでのマージをしたことはなかったから。パッチアプリケーションに基づいたSCMにするなら、"マージ機能" をBKよりも速くしなければならなくなる。それは本当に本当に大変なこと。

だから、僕はいまスクリプトを書いていて、変更をずっと速く追跡できるようにしているんだ。最初の目標はパッチを適用するのと同じくらい高速にそれを行うこと。だけどはっきりいって、今のところできたのは多く見積もってもまだ半分くらいで、思わぬ障害にぶつかったら全然嘘になるかもしれないけど。いずれにせよ、僕がそれをすぐにできる理由は、僕のスクリプトがSCMではないからで、とても特別で "Linuxの状態を記録する" ようなものだからなんだ。それはリニアなパッチを十分効率的な時間でマージできるようになるだろう。

(パッチの適用が3秒でできるなら、大きな1つながりのパッチでも問題にはならない: 途中で失敗しても1分か2分で気がつくなら、それで十分で、手作業で修正することができる。待ち時間が重要な理由はそこにある。-- "オフライン" で効果的にそれができるなら、問題が起きた時に僕は定義どおりそれを修理できずにいるだろう)

リーナスは以下のような原則に基づいて設計を行っている。

  1. CVSを「悪い見本」とする。設計上のことで確信が持てない場合は、CVSと逆の決断をする。リーナスは冗談めかして以下のように語っている。
    “カーネルメンテナンスの最初の10年間、僕らは文字通りtarボールとパッチを使っていた。CVSよりもずっと優れたソース管理システムさ。僕は営利企業(トランスメタ[32])でCVSを7年間使わされたことで、CVSを強烈に憎むようになった。CVSを強烈に憎んでいると言う時には、このことも言っておかなくちゃいけないね。観衆の中にSVN (Subversion) のユーザがいるなら、この場から去ったほうがいいかもしれない。僕がCVSを強烈に嫌悪しているということは、僕がSubversionが史上最大の無意味なプロジェクトであると思っていることも意味しているんだ。Subversionのしばらくのスローガンは‘ちゃんとCVSをやる’とかそんなものだったよね。そんなスローガンから始めたら、どこにも辿りつけないよ。CVSをちゃんとやるなんて不可能なのさ。”[33]
  2. 分散型の、BitKeeperのようなワークフローをサポートする。
    “BitKeeperだけが、「まあ使ってもいいかな」と最初に思わせてくれたSCMだというわけではないけれど、BitkeeperはSCMというものの存在意義と、実際にどう使うことができるのかを教えてくれた。だから、Gitは技術的な観点とかいろんなところでBitkeeperとは随分違うものになっているけど(それはもう一つの設計目標でもある。Bitkeeperのクローンではないことをはっきりさせたかったから)、Gitのワークフローの多くは、Bitkeeperが教えてくれたフローから直接きたものになっているんだ。”[33]
  3. データ破壊に対する強力な抑止機能。データ破壊は、偶然によるものと意図的なものの両方を想定している[34][33]
  4. 非常に高い処理速度。

最初の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]。Hamanoは2005年12月21日にバージョン1.0のリリースを行い[42]、2009年3月現在も彼がメンテナンスを行っている。

ブランチモデル

ソフトウェア開発における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の再デプロイで対応できる。

脚注

  1. ^ 濱野 純; "[ANNOUNCE Git v2.45.2 and friends to unbreak "git lfs" and others"]; 出版日: 2024年5月31日; 閲覧日: 2024年5月31日.
  2. ^ Tech Talk: Linus Torvalds on git. 該当時間: 1分30秒. 2014年7月21日閲覧
  3. ^ Git - IT用語辞典e-words”. 2014年7月29日閲覧。
  4. ^ Git - IT用語辞典 - 日立ソリューションズ”. 2014年12月11日時点のオリジナルよりアーカイブ。2014年7月29日閲覧。
  5. ^ Scott Chacon「1.2 使い始める-Git略史」『Pro Git』http://git-scm.com/book/ja/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-Git%E7%95%A5%E5%8F%B22012年12月8日閲覧 
  6. ^ a b c d e Scott Chacon. “4.1 Git サーバー - プロトコル”. 2013年1月19日閲覧。
  7. ^ 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”
  8. ^ Documentation/RelNotes/2.8.0.txt” (英語). 2017年6月14日閲覧。 “The rsync:// transport has been removed.”
  9. ^ Linus Torvalds (5 May 2006). "Re: [ANNOUNCE] Git wiki". linux-kernel (Mailing list). 2009年3月3日閲覧 Gitの元となったプログラムに関する歴史的経緯
  10. ^ Linus Torvalds (7 April 2005). "Re: Kernel SCM saga". linux-kernel (Mailing list). 2009年3月3日閲覧
  11. ^ Linus Torvalds (8 April 2005). "Re: Kernel SCM saga". linux-kernel (Mailing list). 2008年2月20日閲覧
  12. ^ Linus Torvalds (23 March 2006). "Re: Errors GITtifying GCC and Binutils". Git (Mailing list). 2009年3月3日閲覧
  13. ^ Linus Torvalds (19 October 2006). "Re: VCS comparison table". Git (Mailing list). 2009年3月3日閲覧
  14. ^ 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倍以上になる。
  15. ^ Roland Dreier (2006年11月13日). “Oh what a relief it is”. 2009年3月3日閲覧。, "git log"は"svn log"と比較して100倍以上高速だが、これは後者はリモートのサーバにアクセスする必要があるためである。
  16. ^ Linus Torvalds (18 October 2006). "Re: VCS comparison table". Git (Mailing list). 2009年3月3日閲覧, Gitのスクリプト指向デザインについて
  17. ^ iabervon (2005年12月22日). “Git rocks!”. 2009年3月3日閲覧。, Gitを使ったスクリプトの書きやすさに関する賞賛
  18. ^ Git User's Manual” (2007年8月5日). 2009年3月3日閲覧。
  19. ^ Linus Torvalds (10 April 2005). "Re: more git updates." linux-kernel (Mailing list). 2009年3月3日閲覧
  20. ^ Bruno Haible (11 February 2007). "how to speed up "git log"?". Git (Mailing list). 2009年3月3日閲覧
  21. ^ Linus Torvalds (1 March 2006). "Re: impure renames / history tracking". Git (Mailing list). 2009年3月3日閲覧
  22. ^ Junio C Hamano (24 March 2006). "Re: Errors GITtifying GCC and Binutils". Git (Mailing list). 2009年3月3日閲覧
  23. ^ Junio C Hamano (23 March 2006). "Re: Errors GITtifying GCC and Binutils". Git (Mailing list). 2009年3月3日閲覧
  24. ^ Linus Torvalds (28 November 2006). "Re: git and bzr". Git (Mailing list). 2009年3月3日閲覧, git-blameコマンドを使用したソースファイル間のコードの移動の調査について
  25. ^ Linus Torvalds (2007年7月18日). “git-merge(1)”. 2009年3月4日閲覧。
  26. ^ Linus Torvalds (2007年7月18日). “CrissCrossMerge”. 2009年3月4日閲覧。
  27. ^ “After controversy, Torvalds begins work on git”. InfoWorld. (2005-04-19). ISSN 0199-6649. http://www.infoworld.com/article/05/04/19/HNtorvaldswork_1.html 2008年2月20日閲覧。. 
  28. ^ GitFaq: Why the 'git' name?”. 2007年3月21日閲覧。
  29. ^ Jonathan Corbet (2005-04-20), “How Tridge reverse engineered BitKeeper”, Linux Weekly News, http://lwn.net/Articles/132938/ 2009年3月26日閲覧。 
  30. ^ Linus Torvalds (7 April 2005). "Re: Kernel SCM saga." linux-kernel (Mailing list). 2009年3月26日閲覧
  31. ^ a b ここでは -mm ツリーメンテナのアンドリュー・モートンを指す。
  32. ^ Linus Torvalds (31 October 2005). "Re: git versus CVS (versus bk)". Git (Mailing list). 2009年3月26日閲覧
  33. ^ a b c d e f Linus Torvalds (05-03). Google tech talk: Linus Torvalds on git. 該当時間: 02:30. 2007-05-16閲覧 {{cite AV media}}: |date=|year=|date=の日付が不正です。 (説明)
  34. ^ Linus Torvalds (10 June 2007). "Re: fatal: serious inflate inconsistency". Git (Mailing list). 2009年3月26日閲覧 Gitにおけるデータの完全性に関する設計目標に関する概要説明。
  35. ^ a b Linus Torvalds (27 February 2007). "Re: Trivia: When did git self-host?". Git (Mailing list). 2009年3月26日閲覧
  36. ^ Linus Torvalds (6 April 2005). "Kernel SCM saga." linux-kernel (Mailing list). 2009年3月26日閲覧
  37. ^ Linus Torvalds (17 April 2005). "First ever real kernel git merge!". Git (Mailing list). 2009年3月26日閲覧
  38. ^ Matt Mackall (29 April 2005). "Mercurial 0.4b vs git patchbomb benchmark". Git (Mailing list). 2009年3月26日閲覧
  39. ^ Linus Torvalds (17 June 2005). "Linux 2.6.12". git-commits-head (Mailing list). 2009年3月26日閲覧
  40. ^ Linus Torvalds (20 October 2006). "Re: VCS comparison table". Git (Mailing list). 2009年3月26日閲覧 Git vs. BitKeeperの議論
  41. ^ Linus Torvalds (27 July 2005). "Meet the new maintainer..." Git (Mailing list). 2009年3月26日閲覧
  42. ^ Junio C Hamano (21 December 2005). "ANNOUNCE: GIT 1.0.0". Git (Mailing list). 2009年3月26日閲覧
  43. ^ a b Scott Chacon (2011年8月31日). “GitHub Flow”. 2020年5月31日閲覧。
  44. ^ "#1 - anything in the master branch is deployable.
    This is basically the only hard rule of the system."[43]
  45. ^ GitHub Guides”. 2020年5月31日閲覧。 “With GitHub, you can deploy from a branch for final testing in production before merging to master.”

関連項目

外部リンク