web-dev-qa-db-ja.com

新しいブランチが作成されたときのベースブランチは何ですか?

ブランチを作成するとき、仮定を確認/修正する必要があります。私がマスターブランチにいる場合、次のことをした後:

git checkout -b some_branch

マスターから新しいブランチを開始したことを意味します。

一方、別のブランチをチェックアウトして、そこにブランチを作成すると:

git checkout some_branch
git checkout -b other_branch

これは、some_branchからコミットされた現在のコードをすべて使用してother_branchを作成したことを意味します。

そして、現在のブランチに関係なく、これが行われる場合:

git branch branch_2 branch_1

次に、branch_1をベースとしてbranch_2が作成されます。これらの仮定は正しいですか?

12

Gitには、ブランチのbase branchのようなものはありません。代わりに、Gitがブランチのヒントと呼ぶcurrent commitのみがあります。

グラフを描く

これを視覚的に理解するには、Gitのcommit graphから(少なくとも一部を)描画することから始めます。コミットが3つしかない小さなリポジトリの例を次に示します。

A <-B <-C   <--master

特定のコミットの「本当の名前」は、これらの大きないハッシュID、c0ffeeface1deadbead...などの1つです。このハッシュIDは、特定のコミットを一意に識別し、実際にはmadeは、そのコミットのcontentsをハッシュすることにより(したがって、「ハッシュID」という名前です)。それらはランダムに見え、覚えることができないため、ここでは単一の大文字を使用します。

Gitがグラフを「見る」方法は、masterなどのブランチ名を読み取ることから開始することです。このブランチ名には、CのようなコミットのハッシュIDが含まれます。 masterpoints to commit Cと言います。

一方、コミットC自体には、以前の(またはparent)コミットBのハッシュIDが含まれています。したがって、CBmasterを指すのと同じように、Cを指すと言います。

同様に、コミットBAを指します。 Aはこれまでで初めてのコミットであるため、それを指す場所がどこにもないので、そうではありません。 A a root commitを呼び出すと、逆方向での作業を停止できます(Git)。

これらの内部矢印は描画するのが面倒で、BのハッシュIDは実際にはの一部Cであるため、変更することはできません(Cのこの部分を変更しようとすると、新しい、different commit)。したがって、わざわざ描画をやめ、代わりに次のように記述できます。

A--B--C   <-- master

ブランチ名から出てくる矢印はnot定数であり、それがtip commitの考え方全体の由来です。

masterに新しいコミットを追加するとします。 Gitが必要とする通常のセットアップをすべて行い(いくつかのファイルを追加または変更し、git addを使用)、git commitを実行します。ギット:

  • 新しいコミットD(新しい一意のハッシュIDを取得)を書き出します。この新しいコミットはCを指し示しています。

    A--B--C     <-- master
           \
            D
    
  • 次に、changesmaster(より正確には、保存されたハッシュID)を作成して、作成したばかりの新しいコミットを指すようにします。

    A--B--C
           \
            D   <-- master
    

    そしてもちろん、このキンクを図面に保持する理由はもうありません。

    A--B--C--D   <-- master
    

Gitでは、これがブランチの成長方法です。

newブランチを作成するには、Gitは単にブランチ名を作成します既存のコミットを指す

A
 \
  B
   \
    C
     \
      D   <-- master

これらのコミットのいずれかを選択して、そこに新しいブランチ名を指定できます。 Bを選択して、newbrがそこを指すようにします。

A
 \
  B   <-- newbr
   \
    C
     \
      D   <-- master

これはgit branch newbr <thing-that-finds-B>で行います。

しかし、どのようにしてコミットを見つけるのでしょうか?

Bを見つける方法1つの方法は、git logを実行し、ハッシュIDをカットアンドペーストすることです。しかし、別の方法はブランチ名を使用することです。名前newbrBを指すようになりました。 Bもコミットする別の分岐点を作成する場合:

git branch thirdbr newbr

これにより、Gitはnewbrを参照するBを検索し、thirdbrを指す新しい名前Bを作成します。

A--B   <-- newbr, thirdbr
    \
     C--D  <-- master

これが、Gitでブランチを作成するのが非常に速い理由です。ほとんど何もしません。既存のコミットを指すラベルを作成するだけです。

一部のブランチ名が指すコミットは、そのブランチのtip commitと呼ばれます。 1つのコミットが同時に複数のブランチの先端になる可能性があることに注意してください。これはGitの大きな部分の一部です。一部のコミットはmanyブランチですべて同時に実行されます。たとえば、Aのコミット(ルートコミット)はeveryブランチにあります。 (リポジトリには複数のルートコミットを設定することができますが、少し注意が必要です。これについて心配する必要はありません。ここまでに示したコマンドでは実行できません。)

ブランチ名を特別にするもの

ただし、ブランチラベルの特別なプロパティは、moveです。彼らは動くだけでなく、動く自動的に

新しいコミットDを作成したときに、すでにこれを確認しました。 Gitは新しいコミットのIDをmasterに書き込みました。しかし:Gitはどのようにmasterを使用することを知っていましたか?それに関して、GitはどのようにしてDの親をCにすることを知っていましたか?

もちろん、その時点でブランチは1つしかありませんでしたが、新しいコミットを作成しましょうnow、3つのラベルmasternewbr、およびthirdbrがあります。ただし、最初にgit checkout thirdbrを実行して、結果を描画します。

A--B   <-- newbr, thirdbr (HEAD)
    \
     C--D  <-- master

図面に実際に変更はありませんが、1 ここでWord HEADを追加したことを除きます。 HEADは、Gitがどのブランチとコミットがcurrentブランチとコミットであるかを知る方法です。

そこで、通常の一部変更ファイル、git add、およびgit commitを実行します。 Gitは新しいコミットを書き出し、その親はBをコミットするように設定します。 Gitはcurrentブランチがthirdbrであり、thirdbrBを指しているため、現在のcommitBであると認識します。新しいコミットEを描画しましょう:

     E
    /
A--B   <-- newbr
    \
     C--D  <-- master

残っているのは、現在のブランチnamethirdbrを移動して、新しいコミットEを指すようにすることだけです。

     E   <-- thirdbr (HEAD)
    /
A--B   <-- newbr
    \
     C--D  <-- master

そして、すべて完了しました。ブランチthirdbrに新しいコミットを追加しました(これはまだHEADであり、現在のブランチのままですが、現在はEが現在のコミットです)。

現在のブランチにコミットを追加すると、現在のコミットが何であり、新しいコミットがどこに行くかを示すHEADです。 HEADは通常名前を含みますそれはgit checkoutが行うことです。特定のコミット(通常、既存のブランチのチップコミット)をチェックアウトし、ファイルHEADをセットアップしてnameを記憶しますブランチ。 tip commitを覚えているのはブランチ名そのものです。

git checkout -b newnamecommitの使用は、「指定されたcommitをチェックアウトし、そのブランチを指す新しいブランチ名を作成しますnewnameそのコミットをポイントし、HEADその新しい名前に。」 commit部分を省略すると、デフォルトではHEADが使用されます。 HEAD is(常に)現在のコミットなので、Gitは「チェックアウト」部分をスキップして新しいブランチ名を作成し、HEADファイルに保存します。


1graphでは何も変更されていませんが、Gitはワークツリーとindexを更新する必要があったため、コミット時のファイルを保持できましたB

20
torek