HEADを以前の場所に戻すにはどうすればよいですか?(切り離されたヘッド)&コミットの取り消し

git git-checkout git-reset git-revert git-reflog


Gitでは、別のブランチにマージしてから HEAD を前の場所にリセットすることで、 squash commit を実行しようとしました。

git reset origin/master

でも、ここから抜け出したい。HEADを元の位置に戻すにはどうすればいいのでしょうか?

移動先のコミットのSHA-1フラグメント( 23b6772 )があります。このコミットに戻すにはどうすればよいですか?




Answer 1 CodeWizard


答える前に、この HEAD が何であるかを説明する背景を追加しましょう。

First of all what is HEAD?

HEAD は、現在のブランチの現在のコミット(最新)への参照です。
一度に存在できる HEAD は1つだけです( git worktree を除く)。

HEAD の内容は .git/HEAD 内に格納され、現在のコミットの40バイトのSHA-1が含まれています。


detached HEAD

最新のコミットではない場合、つまり、 HEAD が履歴内の前のコミットを指している場合は、 detached HEAD と呼ばます。

Enter image description here

コマンドラインでは、 HEAD は現在のブランチの先端を指していないため、ブランチ名の代わりにSHA-1のようになります。

Enter image description here

Enter image description here


剥離したHEADからの回復方法について、いくつかの選択肢があります。


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 に、reflogに新しいエントリがあります

git reflog
git checkout HEAD@{...}

これにより、目的のコミットに戻ることができます。

Enter image description here


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 2.7以降git rebase --no-autostash も使用できます。

git revert <sha-1>

指定されたコミットまたはコミット範囲を "Undo "します。
resetコマンドは、指定されたコミットで行われた変更を「元に戻す」コマンドです。
元のコミットは履歴に残りますが、undo パッチで新しいコミットがコミットされます。

# Add a 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 && checkoutHEAD を変更してください。

Enter image description here




Answer 2 amuliar


Do

git reset 23b6772

あなたが正しい位置にいるかどうかを確認するために。

git status

あなたは何かを見るでしょう

ブランチマスタ上 あなたのブランチは 'origin/master' より 17 コミット遅れています。

そして、変更を反映させるためにリモートで履歴を書き換えます。

git push --force-with-lease // a useful command @oktober mentions in comments



Answer 3 Kay V


最短で可能な解決策(たった1ステップ

git checkout - 使用する-

あなたは、表示されます Switched to branch <branch_name> 。目的のブランチであることを確認します。


簡単な説明:このコマンドは、HEADを最後の位置に戻します。この回答の最後にある結果に関するメモを参照してください。


記憶法:このアプローチは、以前にアクセスしたディレクトリに戻るために cd - を使用するのとよく似ています。構文と適用可能なケースはかなりよく一致しています(たとえば、HEADを実際に元の場所に戻したい場合に便利です)。


より方法論的な解決策(2段構えだが記憶に残る

クイックアプローチは OP の質問を解決してくれます。しかし、あなたの状況が少し違っていた場合はどうでしょうか?その場合、簡単に覚えられる2つのステップを紹介します。

1.必要なブランチを選ぶ

git branch -v を使用します

既存の支店のリストが表示されます。あなたのニーズに合った支店名をつかみましょう。

2.HEADをそこに移動させます。

git checkout <branch_name> を使用します

あなたは、表示されます Switched to branch <branch_name> 。成功!


Outcomes

どちらの方法でも、今までどおり作業の追加とコミットを続行できます。次の変更は <branch_name> で追跡されます。

両方のことを注意 git checkout -git checkout <branch_name> HEADが切り離された中にコミットされた変更がある場合は、追加の指示を与えます。




Answer 4 antak


質問は次のように読むことができます。

私は 23b6772HEAD を使用してデタッチされた状態で、 git reset origin/master と入力しました(スカッシュしたかったため)。気が変わったのですが、 23b6772 にいる HEAD に戻るにはどうすればよいですか。

簡単な答えは: git reset 23b6772

しかし、前の HEAD を参照したいと思ったり、何らかの速記があったかどうかを確認するためにグーグルしたりするたびに、入力(コピーと貼り付け)コミットハッシュまたはその省略形にうんざりしたので、この質問にあたりました。

あることが判明しました!

git reset - (または私の場合は git cherry-pick -

ちなみにこれは cd - と同じでした- * nixの前の現在のディレクトリに戻ります!ですから、私は1つの石で2つのことを学びました。




Answer 5 Deepak Kumar


コマンド git checkout commit_id を実行すると、HEADが 13ca5593d(say commit-id) から切り離され、ブランチがより長く使用できるようになります。

ステップワイズコマンドを実行して、前の場所に戻って移動します。

  1. git pull origin branch_name (たとえばマスター)
  2. git checkout branch_name
  3. git pull origin branch_name

リモートリポジトリから更新されたコミットで以前の場所に戻ります。