46

単一のファイル (foo.txt と呼びます) をあるリポジトリから別の (関連のない) リポジトリに移動し、その履歴を保持しようとしています。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

私のフィルター コマンドのロジックは、git rmfoo.txt 以外のすべてのファイルに対するものです。をコマンドに追加し|| trueて、filter-branch を満たすためにゼロの戻り値を強制しました。

私の意図は、source-repo-copy をターゲット リポジトリ (target-repo) のリモートとして設定しgit filter-branch、foo.txt 以外のすべてを除外すると仮定して、source-repo-copy をフェッチして target-repo にマージすることでした。残念ながら、git filter-branchコマンドは効果がないように見えました。エラーなしで実行され、source-repo の 600 以上のコミットをすり抜けたように見えましたが、終了するgit logと、source-repo-copy のファイルとファイルは同じように見えました。foo.txt 以外のすべてのファイルが欠落していて、それに触れていないすべてのコミットがログから削除されるべきではありませんか?

この時点で、私は続行する方法がわかりません。助言がありますか?

4

1 に答える 1

37

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

ここに示すように

~$ 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

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

于 2012-05-09T21:57:07.583 に答える