2026/06/19(金)異なるGitリポジトリの履歴を連結する方法

投稿日:

あるリポジトリのファイルだけを抜いてきて新たにgit管理していたが、元々のリポジトリの履歴と繋げたくなったのでやった内容。

リベースやマージを経ないためコンフリクト解消が不要でお手軽。とにかく履歴さえくっつけばいい場合に向く。

確認環境

MSYS2上のGitで確認している

Env Ver
OS Windows 11 Pro
Gitの動作環境 msys2-x86_64-20260322
Git 2.53.0

前提

  • 元となったリポジトリをA、リポジトリAの履歴を捨てて新しく作ったリポジトリをBとする
  • どちらにもmainブランチしかないものとする

手順

  1. 事故が起きると面倒なため、まず作業用フォルダを作る
  2. リポジトリAをgit cloneする
  3. 最新のコミットハッシュを取得する
    git rev-parse HEAD
    
  4. この状態でリポジトリBをリモートリポジトリに追加する
    git remote add new リポジトリB
    
  5. リポジトリBを別ブランチにチェックアウトする
  6. チェックアウトしたブランチで最古のコミットハッシュを取得する。過去に連結歴のあるリポジトリでやると複数出るので注意
    git rev-list --max-parents=0 HEAD
    
  7. メインブランチに戻る
  8. 元となったリポジトリAに、新しいリポジトリBを繋ぎこむ。
    この時、リポジトリB側のコミットハッシュはすべて変更され、署名も消える
    git replace --graft リポジトリBの最古のコミットハッシュ リポジトリAの最新コミットハッシュ
    

一括でやるコマンド

上に書いたことをコマンドに落としただけのもの。動作確認はしていない。

$new_repo=/path/to/.git
BASE_END=$(git rev-parse HEAD)
git remote add dest $new_repo
git fetch new
git checkout -b new dest/main
NEW_START=$(git rev-list --max-parents=0 HEAD)
git replace --graft $NEW_START $BASE_END

あとがき

リベースもマージもgit mvも何もせず、異なるリポジトリを無理やり繋げたのにも拘らず、ファイル名の変更が繋がってるのが凄いと思った。

恐らくAとBで同じパスのファイルがあれば、それは同じものとして繋げてくれていると思うのだが、これは便利だ。

これによってリポジトリを分離する前の履歴が見れるようになり、過去の経緯が追えるようになったので助かった。

あとMSYS2のGitは非常にパフォーマンスが悪く重いので、こういう作業で使うと非常に遅かった。