要するに:
1 つの解決策は、グラフトを使用して履歴を接続し、 を使用git filter-branch
してこれらのグラフトに従って履歴を書き換え、オプションでマージを実行することです。
元のリポジトリでの新しい開発の上に変更 (コミット) を再生するソリューション (リベースソリューション) は、別の実行可能なソリューションであることに注意してください。
より長いバージョン:
スナップショットをダウンロードしてローカル開発を開始したリポジトリのリビジョンを覚えているか、ソースを調べるか、git コマンドを使用して見つけることができると仮定しましょう。このリビジョンを START または A と呼びましょう。
ローカルの切断された履歴が元のリポジトリのクローンにあると仮定しましょう。これは、ローカルの切断された開発が、プロジェクトの完全な履歴と同じリポジトリにあることを意味します。ローカル ブランチがブランチ 'master' にあると仮定しましょう (簡単にするために、ブランチは 1 つだけです)。
ローカルの切断された作業でプロジェクトをリポジトリにフェッチしなかった場合は、次の方法でこれを行うことができます。
$ git remote add origin git://github.com/mojombo/mojombo.github.com.git
$ git fetch origin
履歴は次のようになります。
*---*---*---*---*---A---*---*---*---* <--- origin/master (リモート追跡ブランチ)
x---y---*---*---* <--- master (ローカル切断履歴)
上の図の A という名前のコミットは、スナップショットとしてダウンロードしてローカル開発を開始した START コミットです。
2 つの可能性があります。最初のコミット 'x' として 'A' のスナップショットをコミットしたか、作成した最初のコミットがローカルの変更でした。
最初のケース ('Initial commit' または 'Import' などの元の開始状態をコミットした場合) では、接続された履歴を次のようにする必要があります。
*---*---*---*---*---A---*---*---*---* <--- origin/master (リモート追跡ブランチ)
\
\-y---*---*---* <--- master (ローカル切断履歴)
つまり、最初の元のコミット 'y' は、'A' を親として持ちます。
2 番目のケース (変更をコミットした場合) では、接続された履歴を次のようにする必要があります。
*---*---*---*---*---A---*---*---*---* <--- origin/master (リモート追跡ブランチ)
\
\-x---y---*---*---* <--- master (ローカル切断履歴)
つまり、最初のコミット 'x' に 'A' を親として持たせたいとします。
どちらの場合も、コミット 'A' の完全な SHA-1 識別子と、コミット 'x' および 'y' の完全な SHA-1 識別子を見つけたいと考えています。
git rev-parseを使用して、コミット 'A' の SHA-1 を見つけることができます (まだ知らないと仮定します) 。
$ git rev-parse A # or A^{commit}
437b1b20df4b356c9342dac8d38849f24ef44f27
('^{commit}' サフィックスは、コミットSHA-1を見つけたことを確認するために必要になる場合があります。これは、たとえば、'v0.99' などのタグで 'A' を知っている場合に重要です; あなたの場合は問題のリポジトリはタグを使用しないため、必要ありません)。
git rev-listを使用して、コミット「x」および「y」の SHA-1 を見つけることができます(開発がブランチ「master」で行われたと仮定します)。
$ git rev-list --topo-order master | tail -2
8bc9a0c769ac1df7820f2dbf8f7b7d64835e3c68
e83c5163316f89bfbde7d9ab23ca2e25604af290
( " | tail -2
" は、生成されたリストで最後の 2 つのコミットを見つけるためにここにあります。持っていない場合は使用する必要はありません)。
注: 上記のすべての例で完全な SHA-1 は例であり、そのまま使用しないでください。
'A' (または 'START') を親として持つコミットに FIRST という名前を付けましょう (上記のように、ケースに応じて 'x' または 'y' になります) 。履歴を接続するには:
$ echo "<SHA-1 of FIRST> <SHA-1 of START>" > .git/info/grafts
git log --graph
次に、gitk、QGit、またはGitX などのグラフィカル履歴ブラウザを使用して、履歴が正しく接続 (結合) されているかどうかを確認する必要がありますgit show-branch
。
$ gitk master origin/master # or --all
(ここで gitk は単なる例です。" git show branch
" を使用する場合、常に ' --all
' オプションを使用できるとは限りません)。
最後に、おそらくこれらの変更を永続的なものにしたいので、リポジトリからフェッチする人は誰でも履歴を接続できます. git filter-branchを使用してこれを行うことができます:
$ git filter-branch master
「refs/original/master」に元の (切断された) 履歴があります。
これで、grafts ファイルを削除できます。
$ rm .git/info/grafts
これで、元のリポジトリの新しい開発にマージできるようになります。
$ git merge origin/master
ブランチごとの構成をセットアップするため、ブランチ 'master' で origin(al) リポジトリの変更をプル (マージ) するときに単に「git pull」を実行するだけで十分です。これは読者の演習として残されています... :- )
注:リベース ソリューションは、次の履歴になります (最初のコミットが単純なインポートである場合を想定しています)。
*---*---*---*---*---A---*---*---*---* <--- origin/master (リモート追跡ブランチ)
\
\-y'---*'---*'---*' <--- master (ローカル切断履歴)
(ここy'
で、コミットy
が変更されたことを意味します。ほぼ同じ変更セットである必要がありますが、コミットとは異なります)。