148
151

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

履歴を残したまま複数のgitリポジトリを統合する

Last updated at Posted at 2014-03-25

半年ほど前のことでうろ覚えなのですが、pixivで複数のリポジトリを統合したときの方法を紹介します。

AAAAAリポジトリとBBBBBリポジトリを統合し、ZZZZZという大きなリポジトリを作成します。もちろんコミットログを統合前まで遡れるようにするのが絶対条件です。

最終形↓

  • ZZZZZ
    • .git
    • AAAAA
    • BBBBB

filter-branch

まず、新しくgit clone AAAAAしてきます。(なぜなら、このディレクトリはこの後使い捨てられるので、pushされてないbranchとがあると困るからです)

次にcd AAAAAして、次のコマンドを実行します。

git filter-branch --index-filter \
  'git ls-files -s | sed "s@\t\"*@&AAAAA/@" |
      GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
        git update-index --index-info &&
  mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE || true' -- --all

(「全てのブランチ」である必要がないなら "-- --all" を "HEAD" に変えればよいです)

git filter-branchで履歴をごっそり書き換えます。どのように書き換えるかというと、git ls-filesで全てのファイルを列挙し、それに"AAAAA/"というプレフィックスを付けてmvするというようにです。

つまり、このリポジトリの中のファイルは全部AAAAAというディレクトリの中のファイルだったことにします。2万コミットほどあったpixivでは30分ぐらいかかっていた記憶があります。

この段階で

  • AAAAA
    • AAAAA
    • .git

というディレクトリ構造になっているはずです。

ローカルディレクトリをgit remote add

これをBBBBBのほうにも適用し、例えばBBBBBのほうのディレクトリに入って、

git remote add localAAAAA /path/to/the/AAAAA

のようにします。(/path/to/the/AAAAAは先ほどの.gitがあるディレクトリです)

git fetch localAAAAA
git merge --allow-unrelated-histories localAAAAA/main

とすると、AAAAAのmainだったブランチがBBBBBに統合され、

  • BBBBB
    • BBBBB
    • AAAAA
    • .git

のようになるはずです。あとはこの新しいBBBBBをZZZZZリポジトリにpushするだけです。

制約

filter-branchではコミットログは残りますが、コミットハッシュは変わってしまいます。

main以外のブランチを持ってくる場合はそれぞれmergeする必要があります。全てのブランチの場合は簡単な方法があるんでしょうか?

148
151
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
148
151

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?