2017-10-11 5 views
1

私は私の地元の専用ブランチで次のバージョン履歴があるとします。過去に任意の2つのバージョン間にバージョンを挿入する方法はありますか?

A -- B -- C 

バージョン履歴は次のようになりますように、私は、AとBの間の新しいバージョンXを挿入するにはどうすればよい:

A -- X -- B -- C 

how to insert a commit in the pastについても同様の質問がありますが、私の場合は少し異なります.Xで導入された変更はBに伝播せず、AとBの間にXが挿入された後でも変わりません。

答えて

2

Iあなたがコミットを追加したいが、それがソースに何の影響も与えないようにしたいなら、対話型のリベースとは異なるパスが必要です。

あり、特にこのために設計されたものは何もありませんが、それはgit replaceで行うことは比較的簡単です:

  1. チェックアウトデタッチHEADとして(Aをコミットするか、新しいブランチに、新しい枝はすぐになります役に立たない):git checkout <hash-of-A>
  2. コミットをXにします(ただし、表示します)。
  3. 実行git replace --graft <hash-of-B> HEAD

    X--B' <-- refs/replace/<hash-of-B> 
    /
    A--B--C <-- whatever-branch-this-is 
    

    これらの「置換」のオブジェクトに関する特別な何Gitは、ほぼすべてのオブジェクトを含む何のためにコミットを使用する」とほとんど何でもしようとしている時はいつでもということです:あなたは今、この実際の歴史がいる

例えば、Gitは、オブジェクトのハッシュIDを持つrefs/replace/という名前があるかどうかを調べます。 Bの代わりにですので、GitはB'の代わりになります。したがって、git logおよびその他のGitのコマンドは、歴史があるかのように動作します。しかし

A--X--B'--C 

注意を、実際の歴史はまだこのリポジトリに存在していること。代理履歴は、refs/replace/という名前がリポジトリにある場合にのみ使用されます。もちろん、こののリポジトリに置き換えられます(デフォルトでは)。しかし、このリポジトリを他の場所で複製またはプッシュすると、フェッチまたはプッシュプロセスは通常refs/replace/という名前を転送しません。このリポジトリのクローンは古い履歴に戻ります。

git filter-branchを実行すると、単にコミットをコピーできるようになりました。元の履歴を表示するには、git --no-replace-objects log ...を使用してください。デフォルトではgit filter-branchが置換ルールに従います。これはブランチ上のコミットをコピーするときにAで始まり、次にXをコピーしてからB'をコピーしてB'を指すCをコピーすることを意味します。 AX、およびB'のコピーは、元のビットと同じビットであるため、実際には元のものを再利用します。 Cのコピーは若干異なります:B'を実際の親として使用し、代替グラフト親としては使用しません。したがってコミットCは新しいコミットC'にコピーされ、分岐名は何でも新しいコピーを指すようになります。

このフィルタブランチはAXB'て戻って横断実際(単にグラフトされていない)の歴史を持っているので、あなたは、フィルタリングリポジトリのクローンを作成する場合は、今、クローンで見られる歴史は同様に、C'から開始し、その動作します方法はB'からXからAに戻る。

関連する問題