回答:
「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-found
かgit-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
呼ばれているtips
とbranches
されているbookmarks
水銀用語で代わりに。
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では簡単です。
ブランチの実際のコストはそれをマージすることです。Gitは、これを他のソース管理システムよりも簡単にします。Stack Overflowの質問を参照してください。どのように、および/またはなぜGitでのマージがSVNよりも良いのですか 。
Gitでは、ブランチはローカルリポジトリへのコミットへの単なる参照です。作成は非常に安価で、ネットワークはまったくありません。完全に無料ではありません(コマンドを入力する必要があります)が、近くにあります。
ブランチはSVNでは特に高価ではありません-それは単なるコピーであり、非常に安価なコミットです。SVNには中央リポジトリモデルがあるため、ネットワークアクセスですが、恐ろしいものではありません。
一方、由緒あるCVSでは、分岐は非常に高価です。基本的に、CVSブランチにはタグの追加が含まれますが、CVSでは、すべてのファイルが変更される必要があります。各ファイルは、新しいタグを含むように書き換えられます。それは恐ろしく高価です。また、リポジトリが大きい場合、恐ろしく遅くなります。実際、大規模なプロジェクトに参加している場合は、十分に遅いため、できる限りブランチを作成しない方もいます。
SVNの分岐は、Gitの分岐と同じくらい無料です。ブランチの開始位置を示すハウスキーピングデータのほんの一部であり、保存されたファイルは一切変更されません。SVNの「コピー」は、Unixディレクトリにシンボリックリンクを追加するようなものです。SVNブランチは、作業コピーの変更をコミットするまでネットワークトリップを必要としないことに注意してください(ただし、ある時点でローカル以外でコミットしない場合、SCMを使用する意味はあまりありません)。
Gitブランチには、そのタグを内部的に追加するようなハウスキーピングも含まれます。これは、コミット時にどこかに保存する必要があります。大したことではないので、「無料」と呼ばれています。
一部の古いバージョン管理システムでは、ブランチはその時点でコードの完全なコピーであったため、ブランチは多くの部分を占めていたため、「無料」ですスペースがあり、ソフトウェアの完全に完全なバージョンが多数存在することになり、管理が必要になりました。他ではコードの完全なコピーではありませんでしたが、タグごとにすべてのファイルを変更する必要があったため、時間がかかり、苦労しました(「コストのかかる」)。