web-dev-qa-db-ja.com

Git LFS追跡ファイルを通常のGitの下に移動する

Git LFSでビデオファイルを保存するプロジェクトがあります。今では、Git LFSをまだサポートしていないビルドサーバーでいくつかの問題が発生しました。外部サービスであるため、ビルドプロセスに実際に影響を与えることはできません。したがって、Git LFSの下のファイルを「通常の」Gitに戻したいと思います。 git lfs untrack '<file-type>'でファイルタイプを追跡できましたが、git lfs ls-filesは以前に追加したファイルのリストを表示します。

ファイルを削除し、変更をプッシュしてから手動で再追加できると思いますが、これは本当に推奨される方法ですか?

49
Olli Niskanen

私は最近、この問題に遭遇しました。この問題は、あるはずのブランチのgit-lfsに誤ってアセットが追加されたためです。私の解決策は:

git lfs untrack '<file-type>'
git rm --cached '<file-type>'
git add '<file-type>'
git commit -m "restore '<file-type>' to git from lfs"

その結果、git-lfs oid sha256ポインターが標準ファイルの内容に書き換えられます。


(2019-03を編集):受け入れられた回答は、より単純なケースに簡単なソリューションを提供するために変更されました。より複雑なケースが手元にある場合の代替ソリューションについては、 VonCによる回答の編集 も参照してください。

56
mred

Issue 641 は同じ問題に言及しています。

Git LFSの使用をやめようとしましたが、git lfs uninitgit lfs untrackgit rm...を使用して以前のトラックされたポインターファイルを元に戻す方法が見つかりませんでした。 git lfs ls-filesを使用してGit LFSによって追跡されますが、どのようにレポジトリからGit LFS全体をオプトアウトできますか?

答えは:

  1. すべてのfilter.lfs。* git configエントリをgit lfs uninitで削除します。
  2. .gitattributesでlfsフィルターを使用するすべての属性を、ファイルタイプごとにgit lfs untrackを実行するか、LFSだけを使用した場合は.gitattributesを削除してクリアします。

この後、追加されたファイルはすべてgitに直接送られます。

しかし、これはそれほど単純ではありませんでした。

後で作業ディレクトリにLFSポインターファイルを作成し、それらのポインターに手動で保存されたsha1ハッシュを使用して、.git/lfsからすべての写真を復元する必要があります。


2016年3月の更新、 issue 957 は、 tstephens619 で可能な解決策を示しています。

git lfs追跡リストにいくつかの小さなグラフィック形式を含めるという同じ間違いを犯しました。
次の操作を行うことで、このファイルをgitに戻すことができました。

  • git-lfsによって現在追跡されているすべてのファイルのリストを作成し、*.gzおよび*.rpmを除外します(git-lfsでこれらの拡張子を追跡します)

    git lfs ls-files | grep -vE "\.gz|\.rpm$" | cut -d ' ' -f 3 > ~/temp/lfs-files.txt
    
  • 小さなグラフィックファイルの追跡を停止する

    git lfs untrack "*.tts"
    git lfs untrack "*.bfx"
    git lfs untrack "*.ttf"
    git lfs untrack "*.xcf"
    git lfs untrack "*.pkm"
    git lfs untrack "*.png"
    
  • 一時的にuninit git-lfs

    git lfs uninit
    # Git LFS 2.x+
    git lfs uninstall
    
  • ファイルリストを使用して、各ファイルをタッチします。

    cat ~/temp/lfs-files.txt | xargs touch
    

git statusに各ファイルが変更されたように表示されるようになりました

  • Gitインデックスに変更を追加します(git guiを使用してこれを行いました)

  • 変更をコミットしてからgit-lfsを再起動します

    git commit
    git lfs init
    

maintainer ttaylorr を追加:

これを行う1つの方法は次のとおりです。

for file in $FILES_TO_REVERT; do
  git lfs untrack "$file";
  git rm --cached "$file";
  git add --force "$file";
done

git commit -m "..."

私の好みは、GitとGit LFSが提供する磁器コマンドでさまざまな方法で可能であるため、Git LFSに上記の効果にコマンドを追加しないことです。

30
VonC

Git 2.16現在 (2018年1月17日リリース)、これは--renormalizegit addフラグを使用して簡単に実行できます。

git lfs untrack '<pattern>'
git add --renormalize .
git commit -m 'Restore file contents that were previously in LFS'

Gitのドキュメント から:

-renormalize:すべての追跡対象ファイルに「クリーン」プロセスを新たに適用して、強制的にインデックスに再度追加します。これは、core.autocrlf構成またはtext属性を変更した後に、間違ったCRLF/LF行終端で追加されたファイルを修正するために役立ちます。このオプションは、-uを意味します。

ここで重要なのは、「すべての追跡ファイル」です。通常、フィルターは、Git操作が作業ツリー内のファイルを変更したときにのみ実行されます。 .gitattributesのLFSホワイトリストの変更はGit操作ではないため、git lfs untrackを実行した後、インデックスは一貫性のない状態になります。 git add --renormalize .を実行すると、リポジトリ内のすべてのファイルでフィルターを再実行するようにGitに指示されます。

9
Tom Hebb

Windowsで手順を実行する際に問題が発生しました。すべてのgit lfs追跡ファイルを削除して元のファイルを復元するには、git bashで次の操作を行いました。

  1. .gitattributesを削除しました

  2. git lfs ls-files | cut -d ' ' -f 3 > lfs-files.txt

  3. 次のスニペットを実行します。

スニペット:

while read file; do
  git lfs untrack "$file";
  git rm --cached "$file";
  git add --force "$file";
done <lfs-files.txt
1
Joker