🐈‍⬛

別リポジトリのPRを新しいリポジトリに移行する

に公開
2025/12/23

概要

別のリポジトリで作業していたPRを、新しいリポジトリ構造に移行する際の手順をまとめます。
リポジトリの移行や統合により、ディレクトリ構造が変わった場合に有効です。

想定するケース

  • 別リポジトリで作業していたPRがある
  • リポジトリの移行作業が先に進み、新しい構造に変更された
  • 既存のPRを新しいリポジトリ構造に適用する必要があった
  • ディレクトリ構造は変わったが、ファイルの内容はほぼ同じ

手順

1. 変更内容の確認

まず、以前のリポジトリで変更内容を確認します。

# 以前のリポジトリに移動
cd /path/to/old-repo

# 変更されたファイル一覧を確認
git diff main..feature/your-branch-name --name-status

# 変更の統計を確認
git diff main..feature/your-branch-name --stat

# コミット履歴を確認
git log main..feature/your-branch-name --oneline

2. パッチファイルの作成

変更内容をパッチファイルとして出力します。

# パッチファイルを作成
git format-patch main..feature/your-branch-name --stdout > /tmp/migration.patch

# または、個別のパッチファイルとして作成(複数コミットがある場合)
git format-patch main..feature/your-branch-name -o /tmp/patches/

3. パスの調整が必要な場合

リポジトリ構造が変わっている場合(例:src/ → src/apps/app-name/)、パッチファイルのパスを調整する必要があります。

方法A: sedで一括置換(シンプル)

# パスを置換(例:src/ → src/apps/app-name/)
sed 's|^--- a/src/|--- a/src/apps/app-name/|g; \
     s|^+++ b/src/|+++ b/src/apps/app-name/|g; \
     s|^diff --git a/src/|diff --git a/src/apps/app-name/|g; \
     s| b/src/| b/src/apps/app-name/|g' \
     /tmp/migration.patch > /tmp/migration-adjusted.patch

注意
リネーム操作(R)や削除操作(D)がある場合、sedでの置換だけでは不十分な場合があります。

方法B: 直接ファイルをコピー(推奨)

パッチが複雑な場合や、パス調整が難しい場合は、変更されたファイルを直接コピーする方が確実です。

#!/bin/bash
OLD_REPO="/path/to/old-repo"
NEW_REPO="/path/to/new-repo"
BRANCH="feature/your-branch-name"
BASE_BRANCH="main"

cd "$OLD_REPO"
git diff $BASE_BRANCH..$BRANCH --name-status | while read status file; do
  if [[ "$status" == "D" ]]; then
    # 削除されたファイル
    new_file="$NEW_REPO/src/apps/app-name/${file#src/}"
    if [ -f "$new_file" ]; then
      echo "削除: $new_file"
      # rm "$new_file"  # 実際に削除する場合はコメントを外す
    fi
  elif [[ "$status" == "R"* ]]; then
    # リネームされたファイル
    old_file=$(echo "$file" | cut -f1)
    new_file=$(echo "$file" | cut -f2)
    old_path="$NEW_REPO/src/apps/app-name/${old_file#src/}"
    new_path="$NEW_REPO/src/apps/app-name/${new_file#src/}"
    if [ -f "$old_path" ]; then
      echo "リネーム: $old_path -> $new_path"
      # git mv "$old_path" "$new_path"  # 実際にリネームする場合はコメントを外す
    fi
  elif [[ "$status" == "A" ]]; then
    # 追加されたファイル
    src_file="$OLD_REPO/$file"
    dst_file="$NEW_REPO/src/apps/app-name/${file#src/}"
    mkdir -p "$(dirname "$dst_file")"
    if [ -f "$src_file" ]; then
      cp "$src_file" "$dst_file"
      echo "追加: $file -> $dst_file"
    fi
  elif [[ "$status" == "M" ]]; then
    # 変更されたファイル
    src_file="$OLD_REPO/$file"
    dst_file="$NEW_REPO/src/apps/app-name/${file#src/}"
    if [ -f "$src_file" ]; then
      cp "$src_file" "$dst_file"
      echo "更新: $file -> $dst_file"
    fi
  fi
done

実際は、パス調整があったので方法Bで作業しました。

4. 新しいリポジトリでブランチを作成

# 新しいリポジトリに移動
cd /path/to/new-repo

# 新しいブランチを作成
git checkout -b feature/your-branch-name

# または、既存のブランチがある場合は切り替え
git checkout feature/your-branch-name

5. パッチの適用

パッチファイルを使用する場合

# パッチが適用可能かチェック
git apply --check /tmp/migration-adjusted.patch

# 問題がなければ適用
git apply /tmp/migration-adjusted.patch

# または、コミット情報も含めて適用
git am /tmp/migration-adjusted.patch

6. 手動での調整

パッチやファイルコピーだけでは解決できない場合に確認するおおまかな変更点

  • インポートパスの変更
  • 設定ファイルの差分
    • package.json、tsconfig.jsonなど
  • 削除された依存関係
    • 古い型定義ファイルなど
  • リネーム操作
    • ファイル名の変更(大文字/小文字など)

Discussion