🪞

UnrealEngineのリポジトリをGitHubにミラーリングする

2024/08/01に公開

概要

UnrealEngineのソースコードを別Organizationや個人アカウントのリポジトリにミラーリングした際に取った手順。
本当は変更を加えたいときはUEの本家をForkしてPullRequest出すのがいいと思いますが、手元で管理したいときに不向き。

なぜ必要になったか

ご存じの通りUnrealEngineには多くの歴史があり、その歴史がGitHubに刻まれています。
その歴史ごとミラーリングしようとすると、GitHubの1Pushを2GB以内に収めないといけない制限に引っかかってしまいPushに失敗します。
source:2 GB のプッシュ制限のトラブルシューティング - GitHub Docs

今現在(2024/05/19)時点の最新の5.4.1版では引っかかってしまったので今後もおそらく引っかかり続けると思います。
その2GB制限に引っかからないようにミラーリングするのに結構手間取ったので、その方法の共有です。

⚠️こうするべき!という手順ではなく、こうしたら成功したよ!の共有です。その点ご承知おきください⚠️

手順

Clone

まずは普通にCloneしてきます。
--mirror付けてもいいかもしれません。

git clone {UnrealEngineのクローン元URL} UnrealEngine

UnrealEngineフォルダ以下にクローンされているはずです。

Remoteの変更

Cloneしただけのリポジトリは当然Fetch元とPush先がEpicのUEのリポジトリを向いているので、リモートを変更します。
(当然ですがリモート先のリポジトリはあらかじめ用意してください)

git remote set-url origin {new-url}

下記コマンドでちゃんとリモートが変わっているかを確認します。

git remote -v

TagのPush

UnrealEngineにはPreviewやRelease単位でタグが付けられているので、まずこれらをPushします。
タグ全てをまとめてPushすると、2GB制限に引っ掛かるので1つずつTagをPushしていきます。

下記のようなShellScriptを用意し、クローンしたUnrealEngineフォルダに置いておきます。
適当にtag-push.shという名前にしておきました。

#!/bin/bash

tags=$(git tag)

for tag in $tags
do
    echo "Pushing tag $tag"
    git push origin $tag
    echo "Tag $tag pushed successfully"
done

用意したスクリプトを実行します。

sh tag-push.sh

TagのPushに成功したら、5.2.1-releaseからmainブランチを生やしてPushしておきましょう。
おそらくそれ以降は失敗しているはずです。

5.2.1-Release以降のTagのPush

5.2.1-Releaseの次は現時点(2024/05/19)では5.3.0-releaseです。
5.3.0-ReleaseのTagをPushしようとすると、例の2GB制限に引っかかります。

そのため、ここからは細かいコミット単位でPushしていきます。
先ほどと同じようにCloneしたリポジトリの直下に下記のようなスクリプトを置いておきます。
適当にsmall-commit-push.shという名前にしておきました。

start_tag=$1
end_tag=$2

# 開始タグと終了タグの間のコミットを取得します
commits=$(git log --reverse --pretty=format:'%H' $start_tag..$end_tag)

# 開始タグと終了タグの間のコミットを取得します
readarray -t commits < <(git log --reverse --pretty=format:'%H' $start_tag..$end_tag)

chunk=()
count=0

for commit in "${commits[@]}"; do
    chunk+=("$commit")
    ((count++))

    if (( count % 2000 == 0 )); then
        echo "Creating branch with 2000 commits"
        git checkout -b temp_branch "${chunk[0]}"
        git push -f origin temp_branch
        git checkout main
        git branch -D temp_branch
        echo "Branch with 2000 commits created successfully"
        chunk=()
    fi
done

# 最後のチャンクを処理します
if (( ${#chunk[@]} > 0 )); then
    echo "Creating branch with remaining commits"
    git checkout -b temp_branch "${chunk[0]}"
    git push -f origin temp_branch
    git checkout main
    git branch -D temp_branch
    echo "Branch with remaining commits created successfully"
fi

このスクリプトを下記のような形で使用します。

sh small-commit-push.sh 5.2.1-release 5.3.0-release

これで5.3.0-releaseまでのTagまでのコミットがPushされているはずです。
終わったら5.3.0-releaseのTagをPushします。

これを必要なTag分繰り返します。5.4.1-releaseまで必要なら打たれているTag分行ってください。

本当はここもスクリプト作って自動化した方がいいと思うんですが、大した量がないので手作業でやりました。
回数が多くなったりタグが多くなったりしたら自動化した方がいいと思います。

branchのPush

最後に必要なタグの場所をチェックアウトし、そこからブランチを生やしてPushして完了です。
5.4.1-releaseが必要ならそこから、5.3.2-releaseが必要ならそこから生やしてください。

ブランチが1つとTagがPushされたリポジトリが出来上がっているはずです。
temp_branchが居るかもしれませんが、文字通りtempなので消しちゃっていいでしょう。

おしまい。

GitHubで編集を提案

Discussion