8

マスターブランチのGitリポジトリfooの構造

foo/refs/a.txt  
foo/bar/refs/b.txt  

他の支店refs/では他の多くの場所にあるかもしれません

ゴール

ディレクトリref(およびそのコンテンツ)のすべてのインスタンスをGit(履歴)環境から削除するには:GitBashを使用するWindows7

参照の削除(Gitは関与していません。これを試して、それ自体が機能することを確認しました)

find . -name refs -depth -exec rm -rf {} \;

成功すると、すべてrefs/とそのコンテンツが削除されます(を使用しない場合-depth、findは、正しく削除されたにもかかわらず、dirが存在しないというエラーを報告します)。

Gitからの参照の削除

git filter-branch --index-filter \
'find . -name refs -depth -exec git rm -rf --cached --ignore-unmatch {} \;' \
--prune-empty --tag-name-filter cat -- --all

Gitの履歴を書き換えて、Gitからディレクトリ参照を削除する

temp/a写真( asと考えてください)に見られるようにtemp/foo、コマンドは実行され、すべてのコミットを書き換えますが、refs/削除されないため、検索の出力がfilter-branch --index-filter期待どおりに返されません。

同様のことが他の人にも役立つようです。
私は何が欠けていますか?

PS。はい、私はこれについて何時間も何百もの投稿や記事などを読んだことがありますが、とにかくうまくいきません。

4

1 に答える 1

6

アップデート

私の古い回答は、元の投稿者が彼の問題を部分的に解決するのに役立ったようですが、Git コマンドでのみ動作するというのは実際には正しくないよう--index-filterです。 Git コマンドに加えて、シェル コマンド:git filter-branch

git filter-branch --index-filter \
        'git ls-files -s | sed "s-\t\"*-&newsubdir/-" |
                GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
                        git update-index --index-info &&
         mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD

上記のドキュメントの例に示すように、 Git 以外のコマンドを で使用する場合は--index-filterリポジトリのインデックスを操作する必要がある場合があります。

基本的に、元の投稿者の元のインデックス フィルターが機能しなかった理由はわかりませんが、インデックス フィルターがアクセスを許可していないリポジトリの一部にアクセスしようとしていた可能性があります。彼が使用していた Git 以外のコマンドは、実際にはインデックスを変更しませんでした。

また、コメントで指摘したように、

Git は実際にはすべての参照を.git/refs/作業コピーのルートにある非裸のリポジトリに保存します...そのため、コマンドfind . -name refs -depthは実際にそれらのディレクトリも掘り下げます。

それで、フィルター分岐中に何かがひどく間違っている可能性がありますか?

古い回答

filter-branch --index-filter問題は、オプションの代わりにオプションでGit以外のシェルツールを使用しようとしている可能性があると思い--tree-filterます:

git filter-branch --index-filter \
'find . -name refs -depth -exec git rm -rf --cached --ignore-unmatch {} \;' \
--prune-empty --tag-name-filter cat -- --all

--tree-filterコミットごとに新しい作業ディレクトリをチェックアウトし、渡されたシェル スクリプトを実行する とは異なり、 --index-filterGit リポジトリ自体のインデックス ファイルのみを操作します (作業コピーをチェックアウトして操作することはありません)... Git コマンドのみが動作します。

Git コマンドを に渡したので、おそらくこれで運が良かったのでしょうfilter-branch --index-filter

git filter-branch --index-filter \
'git rm -f --cached --ignore-unmatch *.zip && \
 git rm -rf --cached --ignore-unmatch refs' \
--prune-empty --tag-name-filter cat -- --all

これはgit-filter-branch(1) のドキュメントです--tree-filter:

これは、ツリーとその内容を書き換えるためのフィルターです。引数は、チェックアウトされたツリーのルートに設定された作業ディレクトリを使用して、シェルで評価されます。

--index-filterそして、これは(強調鉱山)のドキュメントです:

これは、インデックスを書き換えるためのフィルターです。これは tree フィルタに似ていますが、 tree をチェックアウトしないため、はるかに高速になります。でよく使用されgit rm --cached --ignore-unmatch ...ます。以下の例を参照してください。複雑なケースについては、git-update-index(1)を参照してください。

于 2013-07-07T23:18:45.400 に答える