web-dev-qa-db-ja.com

履歴を保持しながら、あるgitリポジトリから別のgitリポジトリにファイルを移動する方法

1つのリポジトリ(foo.txtという名前)を1つのリポジトリから別の(無関係な)リポジトリに移動し、その履歴を保持しようとしています。 ebneterの質問 は、サブディレクトリに対してこれを行う方法を示しています。 tawの質問 にはいくつかのヒントと提案がありますが、従うべき段階的な手順はありません。 jkeatingの質問 は有望に見えましたが、うまくいきませんでした。この特定のユースケースでは、Google検索が空になりました。私が探しているのは、これを実現するための明確な一連のコマンドです。

私が従い始めたコマンドのシーケンスはこれでした:

$ git clone source-repo/ source-repo-copy
$ cd source-repo-copy
$ git filter-branch --tree-filter 'test ! "$@" = "foo.txt" && \
  git rm --cached --ignore-unmatch $@ || true' --Prune-empty

私のフィルターコマンドのロジックは、foo.txt以外のすべてのファイルをgit rmすることです。 || trueをコマンドに追加して、フィルターブランチを満たすために戻り値がゼロになるように強制しました。

私の目的は、source-repo-copyをターゲットリポジトリ(target-repo)のリモートとして設定し、git filter-branchがfoo.txt以外のすべてを除外し、source-repo-copyをフェッチしてtarget-repoにマージすることを想定していた。残念ながら、git filter-branchコマンドは効果がないようです。エラーなしで実行され、source-repoの600以上のコミットを介してGrindに表示されましたが、終了すると、git logとsource-repo-copyのファイルは同じに見えました。 foo.txt以外のすべてのファイルが欠落しているとは限らず、それに影響を与えなかったすべてのコミットがログから削除されますか?

この時点では、どうすればよいかわかりません。助言がありますか?

45
Randall Cook

これは私にとってはうまくいきましたが、ディレクトリ全体で。

示されているように ここ

~$ cd neu
~/neu$ git filter-branch --subdirectory-filter FooBar HEAD
~/neu$ git reset --hard
~/neu$ git remote rm Origin
~/neu$ rm -r .git/refs/original/
~/neu$ git reflog expire --expire=now --all
~/neu$ git gc --aggressive
~/neu$ git Prune
~/neu$ git remote add Origin git://github.com/FooBar/neu.git

編集:単一ファイルの場合:

最初にディレクトリをフィルタリングします。

 git filter-branch --Prune-empty --subdirectory-filter myDirectory -- --all

単一のファイルをフィルタリングします。

 git filter-branch -f --Prune-empty --index-filter "git rm --cached --ignore-unmatch $(git ls-files | grep -v 'keepthisfile.txt')"

いくつかのクリーンアップを行います:

 git reset --hard
 git gc --aggressive
 git Prune

これでうまくいくはずです。

36
blang