概要
以下の問題を単純化した場合に解いてみた。
- あるソースツリーを取り込んで新しいリポジトリを育てていた。
- 後からそれ以前の履歴を持ったリポジトリが発見された。
- 新旧リポジトリの履歴を繋いで一つにするにはどうすればよいか?
準備
歴史が断絶された2つのリポジトリを作る
- repo_new リポジトリにはある時点以降の変更の履歴がある
- repo_old リポジトリにはそれ以前の変更の履歴がある。
~$ mkdir repo_old
~$ cd repo_old
~/repo_old$ git init
~/repo_old(master)$ echo aaa > old.txt
~/repo_old(master)$ git commit -m "aaa"
~/repo_old(master)$ echo bbb >> old.txt
~/repo_old(master)$ git commit -a -m "bbb"
~/repo_old(master)$ git log --oneline
6933cc5 bbb
fdd1f1e aaa
repo_old(master)$ cd ..
~$ mkdir repo_new
~$ cp repo_old/old.txt repo_new/new.txt
~$ cd repo_new
~/repo_new$ echo ccc >> new.txt
~/repo_new$ git init
~/repo_new(master)$ git add new.txt
~/repo_new(master)$ git commit -m "import text with modification"
~/repo_new(master)$ echo ddd >> new.txt
~/repo_new(master)$ git commit -a -m "ddd"
~/repo_new(master)$ echo eee >> new.txt
~/repo_new(master)$ git commit -a -m "eee"
新しいリポジトリには repo_old 時代の履歴は入っていない。
~/repo_new(master)$ git log --oneline
9cb1b71 eee
98c48a9 ddd
aa294ea import text with modification
~/repo_new(master)$ git blame -s new.txt
^aa294ea 1) aaa
^aa294ea 2) bbb
^aa294ea 3) ccc
98c48a9e 4) ddd
9cb1b71d 5) eee
手順
remote として旧リポジトリを追加する
repo_new(master)$ git remote add old ../repo_old
repo_new(master)$ git fetch old
新リポジトリの最初のコミットをチェックアウトしておき、旧リポジトリの master ブランチを別ディレクトリにチェックアウトする
~/repo_new(master)$ git checkout aa294ea
~/repo_new((aa294ea...))$ git worktree add ../old_master old/master -b old_master
まずファイル配置をあわせるためのコミットをして、次に新リポジトリの最初のコミットを取り込む。
~/repo_new((aa294ea...))$ cd ../old_master
~/old_master(old_master)$ git mv old.txt new.txt
~/old_master(old_master)$ git commit -m "rename along new repository"
~/old_master(old_master)$ cp ../repo_new/new.txt new.txt
~/old_master(old_master)$ git commit -a -m "$(git log --pretty=format:%B aa294ea)"
rebase 実行すると新リポジトリの最初のコミットは既に取り込み済みとしてスキップされ、以降のコミットが積まれる。
~/old_master(old_master)$ cd ../repo_new
~/repo_new((aa294ea...))$ git checkout -b new_master master
~/repo_new(new_master)$ git rebase old_master
First, rewinding head to replay your work on top of it...
Applying: import text with modification
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
No changes -- Patch already applied.
Applying: ddd
Applying: eee
repo_old 時代の履歴が繋がった!
~/repo_new(new_master)$ git log --oneline
e347437 eee
c30cf35 ddd
a87e845 import text with modification
38edb59 rename along new repository
6933cc5 bbb
fdd1f1e aaa
~/repo_new(new_master)$ git blame -s new.txt
^fdd1f1e old.txt 1) aaa
6933cc54 old.txt 2) bbb
a87e8459 new.txt 3) ccc
c30cf35b new.txt 4) ddd
e3474370 new.txt 5) eee