11

分散バージョン管理のビッグスリー(Git、Bazaar、およびMercurial)は、それぞれかなり異なる方法で分岐を扱います。たとえば、Bazaarでは、ブランチは個別のリポジトリ(実際には、親リポジトリの分岐コピー)です。ファイルシステムでは、さまざまなブランチがさまざまなディレクトリに存在します。一方、Gitでは、同じリポジトリに(したがって、ファイルシステムの同じディレクトリに)複数のブランチを存在させることができます。Mercurialは両方の動作をサポートし、後者は名前付きブランチを使用します。

これらの異なる分岐モデルに関連する長所と短所は何ですか?私の考えでは、Bazaarの1つのブランチ、1つのリポジトリのアプローチは、Gitのアプローチよりもブランチを苦痛にします(たとえば、Bazaarでブランチを使用するには、最初にブランチを作成し、次に現在の作業コピーからcdアウトして、チェックアウトする必要があります) SVNの場合と同様に、新しいブランチ)。

4

2 に答える 2

10

バザールでは、説明どおりに作業する必要はありません。私は実際に2日前にそれについてのブログ投稿を書きました。作業ツリーを離れることなく、さまざまなブランチを切り替えたり、新しいブランチを作成したりして、1つの作業ツリーだけでほとんど作業できます。このための便利なコマンドは次のとおりです。checkout、、。Bazaarのワークフロードキュメントを確認してください。ほぼすべての方法で構成できることがわかります。switchbranch --switch

于 2009-10-31T18:53:39.207 に答える
6

Git 以外の VCS での分岐モデルについてはよくわかりません。どの DVCS でも、複製によって分岐を実装できると思います (複製を実行して分岐を作成します)。Mercurial のいわゆる「名前付きブランチ」は (私が理解していることから) 実際にはコミット ラベルはブランチとしてのみ解釈され、あいまいさを解決するためにリビジョンのローカル番号付けが必要になる場合があります。Mercurial の「ブックマーク」は、Git ブランチに非常に似ていると思います。分岐の概念が大きく異なる2 つの DVCSはMonotoneDarcsです。プロジェクト名とブランチ名を慣習的に分けるSubversionの「コピーによる分岐」は間違っていると思います。


Git リビジョンでは、コミットの有向非巡回グラフ (DAG) が形成されます。コミットには親があるため、それは指示されています。これは非常に重要な問題です。コミットの DAG のエッジは、コミットからその親 (または、マージ コミットの場合は、2 つ以上の親) です。コミットのグラフは非循環的です。つまり、同じオブジェクトで開始および終了するチェーン (パス) はありません。

Git 用語集では、「ブランチ」をアクティブな開発ラインと定義しています。このアイデアは、Git でのブランチの実装の背後にあります。

ブランチの最新のコミットは、そのブランチの先端と呼ばれます。ブランチの先端は、このコミットの単なる象徴的な名前であるブランチ ヘッドによって参照されます。その「緩い」形式では、そのようなブランチ ヘッド (たとえば、「マスター」という名前のブランチ) は、refs/heads/git リポジトリ内のディレクトリ ( .gitdir 内) のどこかにある単なるファイルであり、ブランチの現在の先端への参照が含まれています: の SHA-1 識別子commit (16 進文字列として)。

Git で新しいコミットを作成すると、現在チェックアウトされているブランチの先端が前方に移動します。言い換えると、新しいコミットは現在のブランチの先端に作成され、ブランチ ヘッドは新しいコミットに進みます (スタックの先頭へのポインタが進む方法と多少似ています)。

単一の git リポジトリは任意の数のブランチを追跡できますが、作業ツリー (存在する場合) はそのうちの 1 つ (「現在の」または「チェックアウトされた」ブランチ) にのみ関連付けられます。現在のブランチは、HEAD ポインターによって指定されます。HEAD は (通常) 現在チェックアウトされているブランチ (ブランチ ヘッド名) へのポインタであり、ブランチ ヘッドがブランチの先端へのポインタであるのと同じです。

たとえば、現在チェックアウトされているブランチが「マスター」である場合、.git/HEADファイル (HEAD を表す) にはref: refs/heads/master(へのシンボリック参照refs/heads/master) を持つ単一の LF で終了する行が含まれ、.git/refs/heads/master(「マスター」ブランチのヘッド) には、たとえば LF で終了する行が含まれます0b127cb8ab975e43398a2b449563ccb78c437255。 「マスター」ブランチの先端への SHA-1 識別子です (つまり、現在のブランチが「パック」されていない場合: を確認する必要があります.git/packed-refs)。

「git commit」や「git reset」など、Git の一部のコマンドは、ブランチ ヘッドを操作/変更します。「git checkout」などのその他の操作/HEAD(現在のブランチへのシンボリック参照)の変更。

" " コマンドは、ブランチの先端から到達可能なすべてのコミットを表示します。これは、ブランチの先端、その親、その親コミットの親 (または親) などを意味します。コミットの DAG の一部を表示します。git log branch

Git では、ブランチの削除は単にブランチ ヘッドを削除することを意味します。これは、一部のコミットが「不可視」で到達不能な freom ref (ブランチとタグ) になることを意味する可能性があります。これは、ある時点で、これらのコミットがガベージ コレクションされ、リポジトリから削除される可能性があることを意味します。しかし、「git branch -d <branchname>」でブランチを削除できる場合、それはコミットが失われないことを意味します。「git branch -D <branchname>」でブランチの削除を強制できます。ブランチの名前を変更することは、ブランチ ヘッド、つまりブランチ チップのシンボリック リファレンス (シンボリック名) の名前を変更するだけです。ブランチ名はコミット オブジェクトのどこにも保存されません。


Git にはreflogsの概念もあります。これは、ブランチの先端がどこを (いつ) 指したかのローカル履歴です。たとえば、「git commit --amend」でコミットを修正すると、ブランチ ヒントは修正されたコミットに置き換えられ、HEAD^ は修正前と修正後のコミットの親になりますが、修正前と修正前のバージョンの reflog にはエントリがあります。修正後。「git reset」を使用して履歴を巻き戻すと、巻き戻す前の古いブランチ ヒントの情報が reflog に含まれます。

要するに、reflog は追加の安全性と git コマンドへの簡単な回復を提供します。

于 2009-11-01T22:28:20.803 に答える