別のブランチの特定のコミットからブランチを作成する方法


102

私はマスターブランチでいくつかのコミットを行い、それらをdevブランチにマージしました。

最初にマスターブランチでコミットされたdevブランチの特定のコミットからブランチを作成したいと思います。

私はコマンドを使用しました:

git checkout dev
git branch  <branch name> <commit id>

ただし、これにより、予想したdevブランチではなく、masterブランチからブランチが作成されます。コミットIDはマスターブランチと開発ブランチで同じです。では、異なるブランチで同じコミットIDをどのように区別できますか?

PS:私はここでgithubで例を作りましたhttps://github.com/RolandXu/test_for_branch

私はコマンドを使用しました:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8

私が期待しているのは、テストブランチにaa.txt bb.txt cc.txtが含まれていることです。ただし、テストブランチにはaa.txtとcc.txtのみが含まれています。ほとんどの場合、マスターブランチからブランチを作成しました。

回答:


145

この形式のbranchコマンド(開始点を含む)を使用している場合は、どこにあってもかまいませんHEAD

何をしているの:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8
  • まず、あなたHEADをブランチに設定しますdev

  • 次に、commit時に新しいブランチを開始します07aeec98。このコミットにはbb.txtがありません(githubリポジトリによると)。

チェックアウトした場所で新しいブランチを開始する場合は、開始ポイントなしでブランチを実行することができます。

git branch test

または、他の人が答えたように、1つの操作でそこで分岐してチェックアウトします。

git checkout -b test

07aeec98ブランチの一部であるという事実に混乱するかもしれませんdev。このコミットがの祖先であることは事実でありdev、その変更はの最新のコミットに到達するために必要ですdev。ただし、それらは最新に到達するために必要な他のコミットでありdev、これらは必ずしもの履歴にあるわけではありません07aeec98

8480e8ae(bb.txtを追加した場所)は、たとえばの履歴にはありません07aeec98。から分岐した場合07aeec98、によって導入された変更を取得できません8480e8ae

つまり、ブランチAとブランチBをブランチCにマージし、Aのコミット時に新しいブランチを作成すると、Bに導入された変更が反映されません。

ここでも同じですが、2つの並列ブランチmasterとdevがあり、それらをdevにマージしました。masterのコミット(マージより古い)からブランチアウトしても、devの変更は提供されません。


masterからの変更を機能ブランチに永続的に統合する場合は、masterそれらにマージして続行する必要があります。ただし、これにより機能ブランチにマージコミットが作成されます。

機能ブランチを公開していない場合は、更新したマスターに基づいてそれらをリベースすることもできます:git rebase master featureA。起こり得る対立を解決する準備をしてください。

マージコミットのない機能ブランチで作業しながら、マスターの新しい変更と統合できるワークフローが必要な場合は、以下をお勧めします。

  • すべての新機能ブランチをマスターのコミットに基づいて
  • devマスターのコミットでブランチを作成する
  • 機能ブランチがマスターの新しい変更とどのように統合されるかを確認する必要がある場合は、マスターブランチと機能ブランチの両方をにマージしdevます。

dev直接コミットせず、他のブランチをマージするためにのみ使用してください。

たとえば、機能AとBで作業している場合:

a---b---c---d---e---f---g -master
    \       \
     \       \-x -featureB
      \
       \-j---k -featureA

ブランチをブランチにマージdevして、新しいマスターでうまく機能するかどうかを確認します。

a---b---c---d---e---f---g -master
    \       \            \
     \       \            \--x'---k' -dev
      \       \             /    /   
       \       \-x----------    /    -featureB
        \                      /
         \-j---k--------------- -featureA

機能ブランチでの作業を継続し、マスターブランチと機能ブランチの両方からの新しい変更をdev定期的にマージし続けることができます。

a---b---c---d---e---f---g---h---i----- -master
    \       \            \            \
     \       \            \--x'---k'---i'---l' -dev
      \       \             /    /         /
       \       \-x----------    /         /  -featureB
        \                      /         /  
         \-j---k-----------------l------ -featureA

新しい機能を統合するときが来たら、(dev!ではなく)機能ブランチをマスターにマージします。


ありがとう。あなたは私の質問に答えます。gitブランチモードの理解が間違っています。そして、あなたは私の問題について何か提案がありますか?私は他の人からのタイムリーなコミットが多いマスターブランチを持っています(perforceと同期)。私は個人的な仕事をしている開発ブランチを持っています。マスターブランチと開発ブランチからのすべてのコミットを含むブランチが必要です。このブランチに基づいて簡単にブランチを作成し、特定の作業を開始できます。
RolandXu

コメントで答えることができなかったので、提案されたワークフローで答えを更新します。
Gauthier

ねえ-素晴らしくて徹底的な答えをありがとう!好奇心旺盛:結局、なぜそうすべきなのかmerge the feature branches (not dev!) into master
cassi.lup 2014年

devブランチには実際に新しい開発はありません。ブランチの機能を特定しておく必要があります。devマージコミットのみが含まれます。すべての新しい機能を直接masterマージする方が、機能をマージしてから結果をマージするよりも理にかなっていますmaster
Gauthier

@Gauthierなぜかという質問には答えませんでした。私にはそれが合併のように聞こえるdevだけの機能とA BしてCにそれに統合されmaster、個別にマージと同じであるA BCmaster。そうでなければ、それはgitがどのように機能するかについての私の理解に挑戦します、そして私はその理由について非常に興味があります!
Steven Lu

53

引数の順序が間違っています:

git branch <branch-name> <commit>

そのため、どのブランチがチェックアウトされているかは関係ありません。それはあなたが言うことをします。(commit引数を省略すると、デフォルトで現在のブランチと同じ場所にブランチが作成されます。)

新しいブランチを作成するときにチェックアウトする場合:

git checkout -b <branch> <commit>

commit引数を省略した場合も同じ動作になります。


22

誰もが使用して述べたように、これをローカルで行うことができます

git checkout -b <branch-name> <sha1-of-commit>

または、github自体でこれを行うことができます。手順は次のとおりです。

1-リポジトリで、をクリックしますCommits

2-分岐元のコミットで、をクリックし<>て履歴のこの時点でリポジトリを参照します。

コミット履歴

3- tree: xxxxxx左上のをクリックします。新しいブランチ名を入力するだけで、Create branch xxx以下に示すようにクリックします。

新しいブランチを作成する

これで、そのブランチから変更をローカルにフェッチして、そこから続行できます。


これは私が必要としたものです。Webサイトでそれを行う方法
eharo2

知らなかった。これだよ。GUIの機能は素晴らしく、CLIから離れたいと思っていました。
Rohit Gupta

10

試す

git checkout <commit hash>
git checkout -b new_branch

コミットはツリーに1つだけ存在し、2つの別々のブランチに存在するべきではありません。

これにより、その特定のコミットをチェックアウトして、名前を付けることができます。


こんにちは、私はgit log devとgit log masterを試しましたが、コミットハッシュIDがマスターブランチからdevブランチにマージするコミットと同じであることがわかりました
RolandXu

gitkログを視覚化するようなものを使用すると役立つ場合があります
ZMorek

githubに例を追加しました。そして、Gauthierはすでにgitブランチモードを誤解しているという私の質問に答えています。ありがとう:)
RolandXu

これは実際に答えだと思います。ありがとう
virusss8

9

あなたはしなければならない:

git branch <branch_name> <commit>

(ブランチ名とコミットを交換していた)

またはあなたがすることができます:

git checkout -b <branch_name> <commit>

代わりにブランチ名を使用すると、ブランチの先端からブランチが取得されます。


それがHEAD意味することではありません。代わりに、「ブランチの先端」または「ブランチが指すコミット」と言うことができます。
Cascabel 2011

@Jefromi-純粋なことを言えば、枝自体は枝の先端へのポインタなので、枝だけを言うことができます。
manojlds 2011
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.