2017-06-12 5 views
4

だから、ブランチ内の他のコミットがマージする準備ができていないため、branchAからの特定のコミットだけが必要な状況があります。だから、もし私がbranchAからmasterにcommitXを選んだら、後でbranchAをmasterにマージすると(その間にいくつかのコミットがあります)、gitの履歴に関するcommitXはどうなりますか?すでにマスターに存在するので無視されるのですか、何らかの重複が発生しますか?私はブランチからコミットを選んだ後、ブランチ全体をマージしてからgitの履歴に何が起こるのですか?

答えて

3

git merge操作は、「マージパス」に沿って個々のコミットを見ていません。代わりに、開始スナップショットと終了スナップショットだけが表示されます。 端のスナップショット(一のスタート)があること、しかし、注意:ここ

...--o--B--o--...--o--L 
     \ 
      o--...--o--R 

Bマージベースがコミットされ、LRが残っている(または、ローカルまたは--ours)と右(またはリモート、または--theirs)がそれぞれコミットします。一方、各ラウンドoは、Gitが見ていないコミットを表しています。 Gitは単に効果で、行います。これはあなたのgit cherry-pickするための手段は何

git diff --find-renames B L # figure out what we did 
git diff --find-renames B R # figure out what they did 

は、「彼らが何をしたか」同じ変更の一部が含まれる可能性がある「私たちがやった」ということで、同じファイルですが、これらの2つのファイルを取得した後にが実行するステップはになります。の変更をマージの左右の両方のサイドに表示される変更。

あなたはチェリー選ぶ例えば、コミットして、一つの経路に沿って、再びそれを元に戻すことは、しかし、と仮定します。

...--o--B--X'--!X'--L 
     \ 
      X--o--R 

X'は目盛りを持っている理由は、それがコミットのコピーだということですX:コミットをチェリーすると、新しいコピーは別のハッシュIDを取得します。

ここでは、ブランチ(グラフの下の行)にコミットを書き、メインにチェリーピックしましたライン(上のライン)は、準備ができていなかったか、 に戻し(!X'を追加)、メインラインに最終コミットLを作成しました。今すぐマージすると、Xのコピーが入ってからもう一度出てしまったという事実は見えません。ギフトはBLを比較し、X'--!X'シークエンスには何も表示されません。したがって、依然としてコミットXによって導入された変更のコピーが1つ必要です。

Rで終わるブランチでコミットXが準備完了になった場合、これが正しい動作です。

コミットXが依然として壊れている場合、これは間違った処置ですが、合併する前にブランチのXを元に戻すことをお勧めします。Bを見つけるため除き


、それは次のようになります。GitはLRの両方で開始し、マージベースを検索し、グラフを逆方向に働かなければなりません。これは、Gitが他の面白いコミットノードのいくつかを横断しなければならないことを意味します。特に

+0

元のコミットはチェリーピックドのものと全く異なるコミットです。 –

+0

@ChrisRasysこれは私が疑問に思っていたものです。コミットIDが異なる場合、gitの履歴は実際には同じ変更である2つのコミットで構成されます。 1つはチェリーピックされたコミット、その後は後でマージされるオリジナルのコミットです。 – sreya

+0

@ChrisRasys:done。 @sreya:はい。これは、同じ変更を再度行うなど、他の手段でコミットをコピーした場合にも発生します。コミットをグラフの行に沿って表示するビューア( 'gitk'のように、ほとんどのGUIはそうですが、私が上で行ったことです)は、2つのコミットが後でマージされる異なる開発行にあったことを示します。 – torek

1

何も起こりませんが、のは、それを打破しましょう。

  M 
-o---o---o master 
    \ 
    \----o--o--o branchA 
      X 

あなたはあなたのチェリーピックをします。次に、状況は次のとおりです。

  M MX 
-o---o---o--o master 
    \ 
    \----o--o--o branchA 
      X 

これまでのところとても良いです。そして、あなたはいくつかのより多くのコミット...今

  M MX 
-o---o---o---o---o---o---o master 
    \ 
    \----o---o---o---o---o---o branchA 
      X 

マージ...

  M MX 
-o---o---o---o---o---o---o-----o master 
    \       /
    \----o---o---o---o---o---o branchA 
      X 

を行い、このすべてがいつものようにちょうどビジネスです。 Gitはコミットがチェリーピックの結果であるという事実を保存しておらず、必要もありません。チェリーピック操作が選んだのXと新しいコミットMXをコミットすることで、マージとは異なり全く、互いに無関係にあります。 (マージして)、「親子」の関係は終わりにmasterbranchAのすべて歴史は、ない唯一の変更は、単一のコミット導入含まれていることを意味上の持っているので、彼らは、いずれか、することはできません。あなたがそれらを手動で編集されたかのよう

実際の変更は、ファイルレベルで、ちょうど仕事します。つまり、チェリーピックによって導入された変更がmasterにある場合、gitは気付くでしょう(簡単な例では、関連する行のマージ中に違いを気付かずに)、物事がマージされます。

編集:コメント欄でご質問については...

は私commitXがメッセージ "Foobarbaz" を持っていたと言うことができます。シナリオを考えると、私はコミットメッセージ「Foorbarbaz」または単に1

各コミットと私のマスターブランチに今2つのコミットをしていますコミットレベルでメッセージおよびファイルレベルでいくつかコンテンツを持っています。チェリーピックはのみコンテンツレベルで動作します。つまり、あるコミットからファイルの変更を受け取り、現在の作業ディレクトリにあるものに適用します。紛らわしいのは、実際にはコマンドgit cherry-pickがその変更を適用した後に新しいコミットを作成するということです(この例ではMX)。これは、新しいコミット単なる古いとはいえ、コミットされて - それは決して元に関連している利便性などgit cherry-pickコピー(編集可能)古いコミットメッセージを除いて、Xをコミットします。

git cherry-pick -nを実行してgitをコミットすることを避けることができます。これにより、チェリーピックが行ったことを自分でコミットする前に編集することができます。

したがって、チェリーピックは文字通り、あなた自身の変更を編集して自分でコミットした場合のように機能する便利なメソッドです。新しいコミットメッセージが古いものと似ているかもしれないという事実は、後でマージする際にgitには関係ありません。

+0

は、ファイルレベルの変更に同意した、それは多くの意味があります。しかし、私のコミットXには "Foobarbaz"というメッセージがありました。このシナリオを考えると、マスターブランチにコミットメッセージ "Foorbarbaz"またはちょうど1つのコミットが2つありますか?私は少なくとも機能的には、私が提案していることは何の害も生じませんが、私はまだ興味があることを認識しています歴史はどのように見えますか。あなたのダイアグラムからは、マスターには1つのコミットしか存在しないようです。 – sreya

+0

@sreya:ブランチの "in"コミットはブランチ名から到達可能なものです。コミットに達することができるかどうかを確認するには、各マージコミットのすべての親を追跡する必要があります。したがって、 'master'からは、(その方向でのマージからの接続のために)トップラインのコミットと(そこの2番目のコネクションのため)ボトムラインを見直します。したがって、MXとXの両方が 'master'に含まれていることがわかります。これにより、Gitは他の多くのVCSとは根本的に異なります。ここでは、コミットは元々Gitで行ったブランチ上だけであり、コミットを含むブランチのセットは変更されます* – torek

関連する問題