3

git checkout <hash> <directory>リポジトリ内のディレクトリの以前のリビジョンをチェックアウトするために使用しようとしています。これは、ディレクトリ内のファイルを以前の状態に復元するために機能します。唯一の問題は、チェックアウトしたリビジョン以降に追加されたサブディレクトリが消えないことです。

たとえば、私のディレクトリ構造が次の場合:

HEAD:
thing/dir1/
thing/dir2/

HEAD^:
thing/dir1/

そうするとgit checkout <hash>、切り離されたHEADモードになり、すべてが正常に一致します。代わりに私がそうするgit checkout <hash> thing/と、の内容thing/dir1/は元に戻りますが、そのthing/dir2/ままになります。

実行するとgit status、からのファイル変更が表示されますthing/dir1/が、は言及されていませんthing/dir2/。これは奇妙なことです。なぜなら、HEAD ^のコンテキストでは、thing/dir2/存在すべきではなく、したがって消滅するはずだからです。 git clean追跡されていないものとして表示されないため、役に立ちません。

作業ツリー全体をチェックアウトすることなく、完全に一致するディレクトリの以前のリビジョンをチェックアウトする方法はありますか?

アップデート:

これが機能するように見えます:

git reset <hash> thing/
git checkout <hash> thing/
git clean -fd thing/

これにより、作業ツリーとインデックスが奇妙な状態になりますが、目的の効果が得られます。

4

2 に答える 2

1

すでに述べgit checkout <hash>たように、gitはデタッチドヘッドモードになります。特定のファイルをチェックアウトするとき、実際にはファイルだけが作業ディレクトリにコピーされ、他のすべては変更されません。

したがって、のファイルは現在の状態であるため表示されthing/dir2/ませんが、変更されたファイルが表示されます。git statusHEADthing/dir1

前回のリビジョンのようにフォルダ全体を本当に残したい場合は、thing/前に削除してみませんか?

rm thing/
git checkout <hash> thing/

それがあなたのニーズに合っているかどうかはわかりません。注意して使用してください!(ただし、ローカルのコミットされていない変更がない場合は、すべてを復元可能にする必要があります。)

于 2011-05-02T17:10:16.400 に答える
1

http://git-scm.com/docs/git-checkoutから:

作業ツリー内のファイルを更新して、インデックスまたは指定されたツリー内のバージョンと一致させます。パスが指定されていない場合、git checkoutはHEADを更新して、指定されたブランチを現在のブランチとして設定します。

さらにその下には、次のようにも書かれています。

<paths>または--patchが指定されている場合、gitcheckoutはブランチを切り替えません。作業ツリー内の名前付きパスをインデックスファイルまたは名前付き(ほとんどの場合コミット)から更新します。この場合、-bオプションと--trackオプションは無意味であり、どちらかを指定するとエラーが発生します。引数を使用して、作業ツリーを更新する前に、特定のツリー風(commit、tag、またはtree)を指定して、指定されたパスのインデックスを更新できます。

つまり、ブランチを切り替えていないため、作業ディレクトリにはHEADポインタへの変更は反映されませんが、ツリー風のファイル(この場合はHEAD ^)が表示されます。

things / dir2がまだディスクに残っている理由は、それがまだ現在のHEADに属しており(HEADは移動されないことを忘れないでください)、ツリーっぽいものに3つ(この場合はthing /)から欠落している情報がないためです。 dir2)。つまり、実際には、HEAD^ハッシュの状態を反映するためにthing/ dir1がチェックアウトされており、HEADに属しているため、ディスク上のthing/dir2もチェックアウトされています。

于 2011-05-02T17:18:11.990 に答える