回答:
チェリーピックは基本的にコミットなので、元に戻したい場合はコミットを取り消すだけです。
他の地域の変更があるとき
現在の変更を隠しておくと、コミットをリセットした後で再適用できます。
$ git stash
$ git reset --hard HEAD^
$ git stash pop # or `git stash apply`, if you want to keep the changeset in the stash
他にローカルな変更がない場合
$ git reset --hard HEAD^
最後のコミットを取り消すには、単にを実行しますgit reset --hard HEAD~
。
編集:この回答は、ローカルの変更の保持について言及していなかった以前のバージョンの質問に適用されました。ティムから受け入れられた答えは確かに正しいものです。頭を上げてくれたqwertzguyに感謝します。
HEAD
)の方が堅牢ですhead
。は、既存の参照の名前がであるという不幸なケースを考慮してください。
可能であれば、ハードリセットを避けてください。ハードリセットは、gitで非常に少数の破壊的な操作の1つです。幸いにも、リセットせずにチェリーピックを取り消すことができ、破壊的なものを回避できます。
取り消したいチェリーピックのハッシュに注意してください${bad_cherrypick}
。を行いますgit revert ${bad_cherrypick}
。これで、作業ツリーの内容は、悪いチェリーピックの前と同じです。
を繰り返しgit cherry-pick ${wanted_commit}
、新しいチェリーピックに満足したら、を実行しgit rebase -i ${bad_cherrypick}~1
ます。リベース中に、両方${bad_cherrypick}
とそれに対応する復帰を削除します。
あなたが取り組んでいるブランチは、良いチェリーピックしかありません。リセットは必要ありません!
git reflog
あなたの助けに来ることができます。
コンソールに入力すると、git履歴のリストとSHA-1が表示されます。
元に戻したいSHA-1をチェックアウトするだけです
答える前に、背景を追加し、これが何であるかを説明しましょうHEAD
。
First of all what is HEAD?
HEAD
現在のブランチ上の現在のコミット(最新)への参照です。
一度に存在できるのは1つだけHEAD
です。(除くgit worktree
)
の内容HEAD
は内部に格納され.git/HEAD
、現在のコミットの40バイトのSHA-1が含まれています。
detached HEAD
あなたが最新のコミットをしていない場合-それHEAD
は、それが呼び出された履歴内の以前のコミットを指していることを意味しdetached HEAD
ます。
コマンドラインでHEAD
は、は現在のブランチの先端を指していないため、ブランチ名の代わりにSHA-1のようになります。
git checkout
git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back
これにより、目的のコミットを指す新しいブランチがチェックアウトされます。
このコマンドは、指定されたコミットにチェックアウトします。
この時点で、ブランチを作成して、この時点から作業を開始できます。
# Checkout a given commit.
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>
# create a new branch forked to the given commit
git checkout -b <branch name>
git reflog
いつでも使用できreflog
ます。
git reflog
更新された変更が表示さHEAD
れ、目的のreflogエントリをチェックアウトすると、HEAD
このコミットに戻ります。
HEADが変更されるたびに、新しいエントリが reflog
git reflog
git checkout HEAD@{...}
これにより、目的のコミットに戻ります
git reset --hard <commit_id>
HEADを目的のコミットに「移動」します。
# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32
# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
git rebase --no-autostash
ます。git revert <sha-1>
指定されたコミットまたはコミット範囲を「元に戻す」。
リセットコマンドは、指定されたコミットで行われた変更を「取り消し」ます。
元に戻すコミットを含む新しいコミットはコミットされますが、元のコミットも履歴に残ります。
# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>
このスキーマは、どのコマンドが何を実行するかを示しています。
ご覧のとおり、をreset && checkout
変更しHEAD
ます。
git reset --hard
これと同じ問題に直面し、チェリーピックが成功してからコミットまたはリモートにプッシュしたことがあり、それを削除したい場合は、次のコマンドを実行してチェリーピックのSHAを見つけることができます。
git log --graph --decorate --oneline
次に、(:wq
ログの終了に使用した後)を使用してチェリーピックを削除できます
git rebase -p --onto YOUR_SHA_HERE^ YOUR_SHA_HERE
ここでYOUR_SHA_HERE
、厳選されたコミットの40文字または省略された7文字のSHAと同じです。
最初は、リモートリポジトリとローカルリポジトリのコミット履歴が異なるため、変更をプッシュすることはできません。次のコマンドを使用して、ローカルコミットを強制してリモートの内容を置き換えることができます
git push --force origin YOUR_REPO_NAME
(私はSeth Robertsonからこのソリューションを採用しました:「コミット全体の削除」を参照してください。)
1つのコマンドで破壊的なコマンドを使用しないgit reset
:
GIT_SEQUENCE_EDITOR="sed -i 's/pick/d/'" git rebase -i HEAD~ --autostash
それは単にコミットをドロップし、ローカルで変更があったとしてもチェリーピックの前の状態に正確に戻します。
git reset HEAD^
か
git reset
は、変更を削除せずにコミットアクションを取り消します。git-scm.com/docs/git-resetを読むことをお勧めします。OPからの質問は、チェリーピックを元に戻すことです。両方のコマンドを試してください。私の場合は、チェリーピックの前の状態に戻ります。git reset
チェリーピックされた変更を残し、既存のローカル変更と区別がつかなくなると、作業ツリーがめちゃくちゃになります。
reset --hard
。変更はありません
git reset --hard
は、関連のないローカル変更も削除し、回復不能な方法で削除する破壊的なコマンドです!したがって、それはOPが要求したものではありません。
sed
コマンドが何をしているか、それを手動で行うのとどのように違うのか、そして何をするのかを説明した方がはるかに役立ちます--autostash
。