web-dev-qa-db-ja.com

git checkoutは、必要なファイルを削除していません

パブリックリポジトリを使用して、マスターブランチを過去の特定のコミットに戻したいと思います。オプションを確認しましたが、目的のコミットを簡単にチェックアウトしてから、マスターブランチにコミットするのが最善の方法です。ただし、チェックアウトを実行しても、指定されたコミットハッシュの後にマスターに追加された一部のファイルは削除されません。

たとえば、コミットに戻りたい場合はaaa1

$ cd working-copy-top-dir
$ git checkout master
$ git checkout -- .
$ git clean -fd
$ git checkout aaa1 .
$ git clean -fd

ただし、この時点で、aaa1の後に追加されたいくつかのファイルはまだ作業コピーにあります。作業コピーを取得するためのcheckoutコマンドとは何ですかdataaaa1の状態に戻しますか?

$ git --version
git version 2.7.2.windows.1
9
mulllhausen

TL; DR:最初にすべてを削除します

git checkout aaa1 .を使用したとき、Gitにaaa1をコミットに変換し、そのコミット(より正確にはそのツリー)を見つけて、そのコミット内のすべてのファイルをインデックス/ステージング領域にコピーして作業するように指示しました-木。

議論のために、masterREADMEの2つのファイルを含むhelloで開始するとします。

$ git checkout master
[output snipped]
$ ls
README   hello
$ cat README
Yay, you read me!
$ cat hello
world
$ 

さらに、commit aaa1が存在し、その中にREADMEaddendumの2つのファイルがあるとします。そのREADMEThank you for reading.と言っています。チェックアウトをしましょう。

$ git checkout aaa1 -- .
[output snipped]
$ ls
README    addendum  hello

--を追加しました。ここでは実際には必要ありませんが、良い習慣です。)READMEの内容は更新されたREADMEです。ファイルaddendumも抽出されました。ファイルhellonot削除され、masterにあるバージョンから変更されません。更新されたREADMEhelloがステージングされます。

$ git status --short
M  README
A  addendum

ただし、helloは削除されません:

$ git ls-files --stage
100644 ac6f2cf1acbe1b6f11c7be2288fbae72b982823c 0   README
100644 7ddf1d71e0209a8512fe4862b4689d6ff542bf99 0   addendum
100644 cc628ccd10742baea8241c5924df992b5c019f71 0   hello

git cleanを使用しても、-xを使用しても効果はありません。クリーニングは必要ありません。ステージングされていないファイルはありません(helloはステージングされていますが、変更済みではありません)。


具体的には、ワークツリーをコミットaaa1、バイトごとに一致させる必要がありました。これを行うには、現在インデックスにあるがaaa1にないファイルを見つけて、それらを削除する必要があります。

ただし、もっと簡単な方法があります。すべてを削除するだけです。次に、git checkout aaa1 -- .を使用して、aaa1からすべてを抽出します。これにより、aaa1からインデックスとワークツリーが入力されます。削除する前の状態に復元する必要があるファイルはすべて、(aaa1の状態に復元されます。つまり、- 同じHEADの場合と同じ)。 aaa1の状態に一致するように変更する必要のあるファイルはすべて復元されます(aaa1の状態(異なる)に復元されます)。

$ git rm -rf .
rm 'README'
rm 'addendum'
rm 'hello'
$ git checkout aaa1 -- .
$ git ls-files --stage
100644 ac6f2cf1acbe1b6f11c7be2288fbae72b982823c 0   README
100644 7ddf1d71e0209a8512fe4862b4689d6ff542bf99 0   addendum
$ git status --short
M  README
A  addendum
D  hello

これでコミットできるようになり、masterに新しいコミットが作成されます。これは、以前に何があったかに関係なく、aaa1とまったく同じツリーになります。

(これが良いアイデアであるかどうかはまったく別のことですが、目的の状態が得られます。)

9
torek

リポジトリをその状態にロールバックしますか?それとも、ローカルリポジトリをそのように見せたいだけですか?

Gitのリセットについては、 https://git-scm.com/docs/git-reset を参照してください。

ケース1:

git reset --hard [commit hash]

それはあなたのローカルコードとローカル履歴をそのコミット時と同じようにします。しかし、これを新しい歴史を持つ他の誰かにプッシュしたい場合、失敗します。

ケース2:

git reset --soft [commit hash]

ローカルファイルは当時と同じように変更されますが、履歴などは同じままになります。

私は答えを見つけました ここ 。また、関連する回答を見ることができます ここ

3
pRaNaY

Gitチェックアウト 前回のコミット以降に追加されたファイルは削除されません 。これを行うには、git revertが必要です。

ただし、git checkout thehash .の方がはるかに使いやすく、そのハッシュ以降に追加されたファイルを確認するのはそれほど難しくありません。

git diff --name-status HEAD thehash
0
mulllhausen

git stashは、作業ツリーをクリーンアップする最も簡単な方法かもしれません。次にgit checkout -b $ newbranch $ commit-sha1-you-wantを使用して、操作するブランチを作成します。すべての作業が完了したら、git stash pop作業ツリーを復元します。

0
ElpieKay