私たちの Git リポジトリは、次のように個々のプロジェクトごとに独自のツリーを持つ単一の巨大な SVN リポジトリの一部として始まりました。
project1/branches
/tags
/trunk
project2/branches
/tags
/trunk
明らかに、 を使用すると、ファイルを から別の へ移動するのは非常に簡単です。しかし、Git では、各プロジェクトは独自のリポジトリにあり、今日、サブディレクトリをからsvn mv
に移動するように求められました。私は次のようにしました。project2
project1
$ git clone project2
$ cd project2
$ git filter-branch --subdirectory-filter deeply/buried/java/source/directory/A -- --all
$ git remote rm origin # so I don't accidentally overwrite the repo ;-)
$ mkdir -p deeply/buried/different/java/source/directory/B
$ for f in *.java; do
> git mv $f deeply/buried/different/java/source/directory/B
> done
$ git commit -m "moved files to new subdirectory"
$ cd ..
$
$ git clone project1
$ cd project1
$ git remote add p2 ../project2
$ git fetch p2
$ git branch p2 remotes/p2/master
$ git merge p2 # --allow-unrelated-histories for git 2.9+
$ git remote rm p2
$ git push
しかし、それはかなり複雑に思えます。一般的に、この種のことを行うより良い方法はあるのでしょうか? それとも、私が採用したアプローチは正しいのでしょうか?
これは、単に別のリポジトリの一部から新しいスタンドアロンリポジトリを作成するのではなく、既存のリポジトリに履歴をマージすることに注意してください(前の質問のように)。
ベストアンサー1
履歴が正常であれば、コミットをパッチとして取り出し、新しいリポジトリに適用できます。
cd repository
git log \
--pretty=email \
--patch-with-stat \
--reverse \
--full-index \
--binary \
-m \
--first-parent \
-- path/to/file_or_folder \
> patch
cd ../another_repository
git am --committer-date-is-author-date < ../repository/patch
あるいは一行で
git log --pretty=email --patch-with-stat --reverse --full-index --binary -m --first-parent -- path/to/file_or_folder | (cd /path/to/new_repository && git am --committer-date-is-author-date)
ヒント: ソース プロジェクトのサブディレクトリ内のコミットを新しいリポジトリ ルート ディレクトリに抽出する必要がある場合は、パッチから余分なディレクトリを削除するgit am
などの引数を指定できます。-p2
(出典:Exherbo のドキュメント)