Gitでは「ブランチングは無料」とはどういう意味ですか?


27

Gitでは「ブランチングは無料」とはどういう意味ですか?

他のバージョン管理システムと比較してGitが言及されるたびに、これをよく耳にします。

他の人(SVNなど)に対処する機会がありません(?)。

回答:


28

「gitでの分岐は無料」という主張は、それ自体が「無料」ではないため、事実の単純化です。内部を見ると、ブランチは基本的にコミットへの参照であるため、ブランチは代わりに非常に安価であると言う方が正しいでしょう。ここでは、オーバーヘッドが少ないほど安くなるように「安さ」を定義します。

Gitがどのようなオーバーヘッドを持っているかを調べて、Gitがそれほど「安い」理由を掘り下げてみましょう。

gitではブランチはどのように実装されていますか?

gitリポジトリは、.git主にgitが使用するメタデータを含むファイルを含むディレクトリで構成されています。たとえばgitでブランチを作成するたびgit branch {name_of_branch}に、いくつかのことが起こります。

  • 次の場所にあるローカルブランチへの参照が作成されます。 .git/refs/heads/{name_of_branch}
  • 次の場所にあるローカルブランチの履歴ログが作成されます。 .git/logs/refs/heads/{name_of_branch}

基本的にはこれで、テキストファイルがいくつか作成されます。参照をテキストファイルとして開くと、内容はブランチが指しているコミットのid-shaになります。注意分岐がコミットをするためにあなたを必要としない、彼らはオブジェクトの別の種類だと。ブランチとコミットはどちらもgitの「第一級市民」であり、1つの方法はブランチとコミットの関係を構成ではなく集約として考えることです。ブランチを削除しても、コミットは「ダングリング」として残ります。あなたが誤ってブランチを削除した場合、あなたはいつもとコミット見つけることを試みることgit-lost-foundgit-fsck --lost-found、あなたは(限り、Gitはまだガベージコレクションを行っていなかったとして)左ぶら下げを見つけるSHA-IDにブランチを作成します。

では、gitはどのブランチで作業しているかをどのように追跡しますか?答えは.git/HEADファイルにありますmaster。ブランチにいる場合は、このように見えます。

ref: refs/heads/master

ブランチを切り替えると、.git/HEADファイル内の参照が変更されるだけで、コミットで定義されたものでワークスペースの内容が変更されます。

これは他のバージョン管理システムと比較してどうですか?

ではSubversionの枝は、リポジトリ内の仮想ディレクトリです。したがって、最も簡単な分岐方法は、ワンライナーでリモートで実行することsvn copy {trunk-url} {branch-url} -m "Branched it!"です。SVNが行うことは次のとおりです。

  • たとえばtrunk、ソースディレクトリをターゲットディレクトリにコピーします。
  • 変更をコミットして、コピーアクションを完了します。

このコピーをローカルで作成することは、ファイルがコピーおよびシンボリックリンクされる線形時間操作であるため、このアクションをサーバー上でリモートで実行する必要があります。これは非常に遅い操作ですが、サーバー上でそれを行うことは一定時間の操作です。サーバーでブランチを実行する場合でも、gitがブランチを実行していないときにサブバージョンがコミットする必要があることに注意してください。これは重要な違いです。これは、SVNをGitよりもわずかに安くするオーバーヘッドの一種です。

SVNブランチ切り替えるためのコマンド、つまりsvn switch、は実際にsvn updateは変装しています。仮想ディレクトリの概念のおかげで、コマンドはgitよりもsvnの方が少し柔軟です。ワークスペースのサブディレクトリを切り替えて、別のリポジトリのURLをミラー化できます。最も近いものはgit-submodule使用することですが、それを使用することは分岐とは意味的にまったく異なります。残念ながら、これはミラーリングしているリモートURLのすべてのワークスペースディレクトリをチェックする必要があるため、GitよりもSVNでの切り替えを少し遅くする設計上の決定でもあります。私の経験では、GitはSVNよりもブランチの切り替えが速いです。

SVNの分岐には、ファイルをコピーするため、常に公開される必要があるため、コストがかかります。gitでは、上記で説明したように、ブランチは「単なる参照」であり、ローカルリポジトリに保持し、自由裁量で公開できます。ただし、私の経験では、SVNはClearCaseなどよりもはるかに安価でパフォーマンスが高いです。

SVNが分散化されていないのは残念です。いくつかのソースリポジトリにミラーリングされた複数のリポジトリを持つことができますが、SVNにはコミットの一意の識別子がないため、複数のSVNリポジトリの異なる変更を同期することはできません(gitはコミットの内容に基づいたハッシュ識別子を持っています)。私が個人的にSVNでgitを使い始めた理由は、リポジトリの開始がgitで非常に簡単で安価だからです。概念的にソフトウェア構成管理の観点から見ると、プロジェクトの異なるコピー(クローン、フォーク、ワークスペースなど)はそれぞれ「ブランチ」であり、この用語ではSVNで新しいコピーを作成することはGitほど安くはありません。 「ビルトイン」ブランチ。

別の例として、Mercurialでは、分岐はDVCSとは少し異なり、名前付き分岐の作成/破棄には個別のコミットが必要でした。Mercurialの開発者は、開発の後半で実装ブックマークしかし模倣のgitの同じ分岐モデルにheads呼ばれているtipsbranchesされているbookmarks水銀用語で代わりに。


ワオ。「高価な」説明に感謝します。
laggingreflex

2
独自のソースから:This command causes a near-instantaneous commit in the repository, creating a new directory in revision 341. The new directory is a copy of /calc/trunk.-ブランチの作成は、すべてのファイルのコピーを明示的に作成している場合を除き、SVNでは簡単です。
ボブソン

@Bobson私はそれについて多くの手を振っているので、分岐のビットを書き直すことを考えていましたが、Gitではブランチを作成するためコミットが必要であるという私の立場はまだ立っています。私の謙虚な経験では、SVNでのブランチの切り替えはGitでの切り替えよりも遅いと感じていますが、具体的な理由を指摘することはできません。
スポイケ

2
@Spoike-切り替え、確かに。そして、コミットが必ず必要です。問題が発生した部分を明確にするために編集しました。必要に応じて、元に戻してください。
ボブソン


10

Gitでは、ブランチはローカルリポジトリへのコミットへの単なる参照です。作成は非常に安価で、ネットワークはまったくありません。完全に無料ではありません(コマンドを入力する必要があります)が、近くにあります。

ブランチはSVNでは特に高価ではありません-それは単なるコピーであり、非常に安価なコミットです。SVNには中央リポジトリモデルがあるため、ネットワークアクセスですが、恐ろしいものではありません。

一方、由緒あるCVSでは、分岐は非常に高価です。基本的に、CVSブランチにはタグの追加が含まれますが、CVSでは、すべてのファイルが変更される必要があります。各ファイルは、新しいタグを含むように書き換えられます。それは恐ろしく高価です。また、リポジトリが大きい場合、恐ろしく遅くなります。実際、大規模なプロジェクトに参加している場合は、十分に遅いため、できる限りブランチを作成しない方もいます。


4
Gitを使用すると、コミットよりもさらに少なくなります。ブランチは単なるラベルです。SVNはすべてのファイルをコピーするため、CVSと同じくらい高価です。
イズカタ

8
@Izkata:ユーザーの観点から見ると-はい、すべてのファイルが実装(およびパフォーマンス)の観点からコピーされます-いいえ、コピーに関するレコードのみが追加されます。
maxim1000

@Izkataコメントが多すぎます-私の答えをご覧ください。
gbjbaanb

6
@Izkata SVNはポインターと参照を作成しますが、すべてをコピーするわけではありません。
アーロンマクアイバー

2
Gitブランチはコミットではなく、他のコミットに自由に移動できるコミットへの単なる参照です。Gitリポジトリは単なるコミットのツリーであり、ブランチはそのツリー上の別のコミットに自由に移動できる付箋として考えてください。
40XUserNotFound

5

SVNの分岐は、Gitの分岐と同じくらい無料です。ブランチの開始位置を示すハウスキーピングデータのほんの一部であり、保存されたファイルは一切変更されません。SVNの「コピー」は、Unixディレクトリにシンボリックリンクを追加するようなものです。SVNブランチは、作業コピーの変更をコミットするまでネットワークトリップを必要としないことに注意してください(ただし、ある時点でローカル以外でコミットしない場合、SCMを使用する意味はあまりありません)。

Gitブランチには、そのタグを内部的に追加するようなハウスキーピングも含まれます。これは、コミット時にどこかに保存する必要があります。大したことではないので、「無料」と呼ばれています。


5

一部の古いバージョン管理システムでは、ブランチはその時点でコードの完全なコピーであったため、ブランチは多くの部分を占めていたため、「無料」ですスペースがあり、ソフトウェアの完全に完全なバージョンが多数存在することになり、管理が必要になりました。他ではコードの完全なコピーではありませんでしたが、タグごとにすべてのファイルを変更する必要があったため、時間がかかり、苦労しました(「コストのかかる」)。

gitのブランチは基本的にコミットを指すラベルであり、したがって上記の問題を回避します。


1

「無料/安価/高価」のもう1つの側面は、分岐のダウンストリームの結果に対処するために開発者のリソースの観点からコストがいくらになるかということです。すなわち、ブランチからの変更をマージするプロセス。

そして、ここで、GitやMercurialのようなDVCSシステムのブランチをマージすることは、古いシステムよりも簡単です... つまり、以前の分岐でマージが発生した場所。これにより、マージがより正確になり、不必要な競合が減り、関係する開発者にとって主観的に「簡単」または「怖くない」マージが行われます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.