Git:あるブランチから別のブランチの履歴に既存のコミットを挿入します

ブレイジネーター

あるブランチから別のブランチの履歴にいくつかのコミットを挿入したいので、次のようにします。

A - B - F - G - H - I - J  (branch working)
    \
      C - D - E            (old branch)

になる...

A - B - C - D - E - F - G - H - I - J (continue with branch working)

これまでに試したことは、複数の競合が発生して続行できなくなりましたが、後続のコミットの状態が同じである限り、それらについては気にしません。コミットFがコミットEの子になる方法を「知らない」という問題はありますか?

火曜日

あなたは文字通り行うことができないことをそれはいくつかのコミット既存変える伴うだろうので、。この場合、既存のコミットFBのハッシュIDを親として保存します。既存のコミットを変更することはできません。コミットは完全に読み取り専用です(実際、Gitの内部オブジェクトはすべて読み取り専用です)。

既存のコミットに関連付けられているスナップショットを変更せずに、代わりにのハッシュIDを親としてF格納するふりをしたいとしますEあなたこれ行うことができます、そしてあなたは多くの同様のことをすることができます。ただし、それらを見る前に、を見てみましょうgit rebase

使用に問題git rebaseここでは、することによって、そのリベース機能でコピーするかのように行われた各コピーで、(今のところすべてが順調と良いです)コミットを1使って、git cherry-pick(物事がうまく行くことを始めるところです)。1つのコミットを選択するために、Gitは次のことを行います。

  • コミットのスナップショットとコミットの親のスナップショットを比較します(例:Jvs I、またはFvs。)Bこれは、を実行git diff <hash1> <hash2>するか、より単純にを実行することで実行できますgit show <hash2>

  • ここに示されている差分を、親(<hash1>上記)から現在またはHEADコミットまでの差分とマージし、マージ結果を使用して新しいコミットを作成します。

  • 元のコミットのメッセージを新しいコミットにコピーします。

新しいコミットは、いつものように、現在のブランチに移動し、ブランチを1つのコミットより長くし、HEADコミットを変更して新しいコミットに名前を付けます。

マージステップに加えて、Gitがスナップショット(コミット)をチェンジセット(差分)に変換しているという事実は、最終的なチェリーピックの結果が元のスナップショットとは大きく異なる可能性があることを意味します。これは、すべてのどのように異なるに依存し<hash1>ているものは何でもからであるHEADあなたは、プロセスを起動したとき。

このgit rebaseコマンドは基本的に、一連のコミット全体を一度にチェリーピッキングするプロセスを自動化します。すべてのコピーの最後にgit rebase、ブランチラベルが最後にコピーされたコミットを指すように強制します。これは、あなたがコピーできるようになるF新にF'その親されE、そのコピーGの新しいにG'その親であるF'、というように:

A--B--F--G--H--I--J   <-- (original)
    \
     C--D--E   <-- (target of rebase)
            \
             F'-G'-H'-I'-J'   <-- branch

1git rebase文字通り実行されることもgit cherry-pickあれば、通常は同じ結果を生成するはずのメソッドを使用することもありますが、奇妙な場合にはそうではありません。


ここで、これらすべての代わりに、Gitが使用しようとしているときはいつでもGitが「脇を見る」ことができるGitオブジェクトを作成するとしますFこの置換Fは、次のようにグラフに入ります。

A--B--F--G--H--I--J   <-- branch
    \
     C--D--E   <-- some_name
            \
             Frepl   <-- refs/replace/<hash>

私たちは、のためにコミットメッセージをコピーするFためのものにFreplし、コミットのツリーオブジェクトの内部GitのハッシュIDを含め、同様に他の分野のほとんどをコピーします。しかし、その代わりにコミットするポインティングB、コミットFreplコミットするポイントをE

なんらかの理由でcommitを使用FするFreplたびに、Gitが「目を向ける」必要がありますFそして、それを行う方法があります。Frepl特別な名前を付けます。ここで、はcommitの実際のハッシュIDですrefs/replace/big-ugly-hash-idbig-ugly-hash-idF

置換を行うGitコマンドはgit replaceです。ルックアサイドは自動的に行われgit --no-replace-objectsます。実行しない限り、Gitは常にそれを実行します。これはすべて既存のGitオブジェクト変更せずに実行されるため、リポジトリに追加するだけです。

置換オブジェクトの最大の欠点は、git cloneデフォルトで置換オブジェクトをコピーしないことです(オブジェクトも名前もフェッチしません)。これは、クローンに置換が表示されておらず、それを無視することがないことを意味します。フェッチrefspecに置換を明示的に追加して取得することはできますが、少し面倒です。git push操作は、いずれかのデフォルトでは、それらを転送しません。

大きな利点は、新しく改善されたコミットを優先して、元のコミットの使用を停止する必要がないことです。ただし、全員に切り替えてもらうことできればgit rebase多くのコミットをコピーしてブランチラベルを移動するために使用できますまたは、git replace最初にを使用して置換オブジェクトを作成し、次にgit filter-branchフィルターなしで実行して、置換が発生するブランチをフィルター処理するように指示することもできます。

どのようなgit filter-branch行いは、コピーすることで、すべてが(それはフィルターに言われていますのブランチに)コミット。それ—少なくとも論理的には; 多くの最適化があります。各コミットを抽出し、最も古いコミットから最新のコミット、一時ディレクトリに移動し、すべてのフィルターをある順序で適用してから、フィルターが行ったことを使用して新しいコミットを作成します。新しいコミットが元のコミットとビットごとに同一である場合、2つのコミットは実際には1つのコミットにすぎません。それ以外の場合、コピーは新しく異なるコミットです。新しい各コピーのデフォルトの親は、親の以前のコピーで行われたコミットです(ただし、--parent-filter変更できるようにするためのがあります!)。これはすべて、交換用のルックアサイドギミックが発生することで実行されます2。したがって、Gitがコピーを実行するとF、実際にコピーされます。Frepl代わりに、にFrepl戻りEます。私たちは、このフィルタに名前を持っている場合branch、結果はそのGitのコピーA、そしてB、そしてC、そしてD、そしてE、そしてFrepl、そしてG、そしてH、そしてI、そしてJ、与えます:

A--B--F--G--H--I--J   <-- refs/original/refs/heads/branch
    \
     C--D--E   <-- some_name
            \
             Frepl   <-- refs/replace/<hash>
                \
                 G'-H'-I'-J'   <-- branch

親がであるがツリー(スナップショット)が。のツリー(スナップショット)と同じであるbranchcommit指すことに注意してくださいポイントをにコミット、ポイントをに戻し、ポイントをに戻します(実行時に作成したコピー:フィルタリング中は変更されませんでした)。この点に戻り、バックにポイントする、(自身の変わらないコピーである)の背中にそう、とJ'I'JI'H'G'Freplgit replaceEDA

最終的な効果は、のrefs/original/ようなすべての名前を捨てた場合refs/original/refs/heads/branch、置換コミットを「所定の位置に固定」することです。その後、のrefs/replace/名前を削除FreplするA-B-C-D-E-Frepl-G'-H'-I'-J'と、リポジトリにコミットしかなかったかのように見えます。多くのコミットハッシュIDが変更されたため、このリポジトリは元のリポジトリと互換性がなくなりました。しかし、名前から始めるとbranch、すべての適切な場所に、光沢のある新しくコピーされたコミットのみが表示されます。


2もちろん、を実行git --no-replace-objects filter-branchすると、置換ルックアサイドが無効になります。これを行う理由はおそらくありません。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

git move / migrateはあるブランチから別のブランチにコミットします

分類Dev

コミットをブランチから別のブランチに分割する方法をGITしますか?

分類Dev

GitHubのあるブランチから別のブランチにコミットを移動しますか?

分類Dev

コマンド「gitreset--hard <commit>」は別のブランチのコミット履歴を削除しますか?

分類Dev

いくつかのブランチを持つgit履歴の特定のコミットを削除しますか?

分類Dev

gitマージ後、ブランチのコミット履歴をgitロググラフに保持します

分類Dev

ブランチ履歴を保持しながら、以前にマージされたブランチからの過去のコミットを修正します

分類Dev

プッシュされたコミットをあるブランチから別の既存のブランチに移動できますか?

分類Dev

コミットを保持しながら、残りの履歴を集約しながら、ブランチを別のリポジトリに移動します

分類Dev

リモートブランチからローカルの孤立したブランチへの完全なコミット履歴を取得します

分類Dev

コミット履歴から孤立したブランチを削除します

分類Dev

あるブランチから別のブランチにコミットをコピーする方法は?

分類Dev

あるブランチから別のブランチにコミットをコピーする方法

分類Dev

ブランチ間のマージの競合を回避しながらコミット履歴を操作する

分類Dev

Pycharmの単一ブランチのコミット履歴をどのように表示できますか?

分類Dev

Git:ブランチの途中にあるGitコミットから変更を削除します

分類Dev

ブランチからコミットを選択し、後でブランチ全体をマージすると、git履歴はどうなりますか?

分類Dev

ブランチからコミットを削除し、別のブランチに配置します

分類Dev

gitはコミットを別のブランチからのコミットに置き換えます

分類Dev

Gitは変更をあるブランチから別のブランチにコピーします

分類Dev

初期コミットをマスターからGitの別のブランチに移動します

分類Dev

GIT-同じブランチからのプルリクエストはコミットの履歴を持ち込みます

分類Dev

Gitコミットを別のブランチに移動して元のブランチから削除するにはどうすればよいですか?

分類Dev

git履歴のブランチに関係なく、最新のコミットを確認するにはどうすればよいですか?

分類Dev

Gitのブランチからコミットを削除する

分類Dev

Git:1つのブランチから別のブランチに複数のコミットをマージします

分類Dev

マスターブランチへのコミットの長い履歴をリベースするための高速な方法はありますか?

分類Dev

Bitbucketを使用して、あるブランチから別のブランチにコミットを取得するにはどうすればよいですか?

分類Dev

gitでコミットする前に別のブランチにある場合は、ブランチを自動作成します

Related 関連記事

  1. 1

    git move / migrateはあるブランチから別のブランチにコミットします

  2. 2

    コミットをブランチから別のブランチに分割する方法をGITしますか?

  3. 3

    GitHubのあるブランチから別のブランチにコミットを移動しますか?

  4. 4

    コマンド「gitreset--hard <commit>」は別のブランチのコミット履歴を削除しますか?

  5. 5

    いくつかのブランチを持つgit履歴の特定のコミットを削除しますか?

  6. 6

    gitマージ後、ブランチのコミット履歴をgitロググラフに保持します

  7. 7

    ブランチ履歴を保持しながら、以前にマージされたブランチからの過去のコミットを修正します

  8. 8

    プッシュされたコミットをあるブランチから別の既存のブランチに移動できますか?

  9. 9

    コミットを保持しながら、残りの履歴を集約しながら、ブランチを別のリポジトリに移動します

  10. 10

    リモートブランチからローカルの孤立したブランチへの完全なコミット履歴を取得します

  11. 11

    コミット履歴から孤立したブランチを削除します

  12. 12

    あるブランチから別のブランチにコミットをコピーする方法は?

  13. 13

    あるブランチから別のブランチにコミットをコピーする方法

  14. 14

    ブランチ間のマージの競合を回避しながらコミット履歴を操作する

  15. 15

    Pycharmの単一ブランチのコミット履歴をどのように表示できますか?

  16. 16

    Git:ブランチの途中にあるGitコミットから変更を削除します

  17. 17

    ブランチからコミットを選択し、後でブランチ全体をマージすると、git履歴はどうなりますか?

  18. 18

    ブランチからコミットを削除し、別のブランチに配置します

  19. 19

    gitはコミットを別のブランチからのコミットに置き換えます

  20. 20

    Gitは変更をあるブランチから別のブランチにコピーします

  21. 21

    初期コミットをマスターからGitの別のブランチに移動します

  22. 22

    GIT-同じブランチからのプルリクエストはコミットの履歴を持ち込みます

  23. 23

    Gitコミットを別のブランチに移動して元のブランチから削除するにはどうすればよいですか?

  24. 24

    git履歴のブランチに関係なく、最新のコミットを確認するにはどうすればよいですか?

  25. 25

    Gitのブランチからコミットを削除する

  26. 26

    Git:1つのブランチから別のブランチに複数のコミットをマージします

  27. 27

    マスターブランチへのコミットの長い履歴をリベースするための高速な方法はありますか?

  28. 28

    Bitbucketを使用して、あるブランチから別のブランチにコミットを取得するにはどうすればよいですか?

  29. 29

    gitでコミットする前に別のブランチにある場合は、ブランチを自動作成します

ホットタグ

アーカイブ