パブリックリポジトリを使用して、マスターブランチを過去の特定のコミットに戻したいと思います。オプションを確認しましたが、目的のコミットを簡単にチェックアウトしてから、マスターブランチにコミットするのが最善の方法です。ただし、チェックアウトを実行しても、指定されたコミットハッシュの後にマスターに追加された一部のファイルは削除されません。
たとえば、コミットに戻りたい場合は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
git checkout aaa1 .
を使用したとき、Gitにaaa1
をコミットに変換し、そのコミット(より正確にはそのツリー)を見つけて、そのコミット内のすべてのファイルをインデックス/ステージング領域にコピーして作業するように指示しました-木。
議論のために、master
とREADME
の2つのファイルを含むhello
で開始するとします。
$ git checkout master
[output snipped]
$ ls
README hello
$ cat README
Yay, you read me!
$ cat hello
world
$
さらに、commit aaa1
が存在し、その中にREADME
とaddendum
の2つのファイルがあるとします。そのREADME
はThank you for reading.
と言っています。チェックアウトをしましょう。
$ git checkout aaa1 -- .
[output snipped]
$ ls
README addendum hello
(--
を追加しました。ここでは実際には必要ありませんが、良い習慣です。)README
の内容は更新されたREADME
です。ファイルaddendum
も抽出されました。ファイルhello
はnot削除され、master
にあるバージョンから変更されません。更新されたREADME
とhello
がステージングされます。
$ 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
とまったく同じツリーになります。
(これが良いアイデアであるかどうかはまったく別のことですが、目的の状態が得られます。)
リポジトリをその状態にロールバックしますか?それとも、ローカルリポジトリをそのように見せたいだけですか?
Gitのリセットについては、 https://git-scm.com/docs/git-reset を参照してください。
ケース1:
git reset --hard [commit hash]
それはあなたのローカルコードとローカル履歴をそのコミット時と同じようにします。しかし、これを新しい歴史を持つ他の誰かにプッシュしたい場合、失敗します。
ケース2:
git reset --soft [commit hash]
ローカルファイルは当時と同じように変更されますが、履歴などは同じままになります。
Gitチェックアウト 前回のコミット以降に追加されたファイルは削除されません 。これを行うには、git revert
が必要です。
ただし、git checkout thehash .
の方がはるかに使いやすく、そのハッシュ以降に追加されたファイルを確認するのはそれほど難しくありません。
git diff --name-status HEAD thehash
git stashは、作業ツリーをクリーンアップする最も簡単な方法かもしれません。次にgit checkout -b $ newbranch $ commit-sha1-you-wantを使用して、操作するブランチを作成します。すべての作業が完了したら、git stash pop作業ツリーを復元します。