Iあなたがコミットを追加したいが、それがソースに何の影響も与えないようにしたいなら、対話型のリベースとは異なるパスが必要です。
あり、特にこのために設計されたものは何もありませんが、それはgit replace
で行うことは比較的簡単です:
は
- チェックアウトデタッチHEADとして(
A
をコミットするか、新しいブランチに、新しい枝はすぐになります役に立たない):git checkout <hash-of-A>
。
- コミットを
X
にします(ただし、表示します)。
- 実行
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
をコピーすることを意味します。 A
、X
、およびB'
のコピーは、元のビットと同じビットであるため、実際には元のものを再利用します。 C
のコピーは若干異なります:B'
を実際の親として使用し、代替グラフト親としては使用しません。したがってコミットC
は新しいコミットC'
にコピーされ、分岐名は何でも新しいコピーを指すようになります。
このフィルタブランチはA
にX
にB'
て戻って横断実際(単にグラフトされていない)の歴史を持っているので、あなたは、フィルタリングリポジトリのクローンを作成する場合は、今、クローンで見られる歴史は同様に、C'
から開始し、その動作します方法はB'
からX
からA
に戻る。