How to move HEAD back to a previous location? (Detached head) & Undo commits

荒凉一梦 提交于 2019-11-25 22:13:45

问题


In git, I was trying to do a squash commit by merging in another branch and then resetting HEAD to the previous place via:

git reset origin/master

But I need to step out of this. How can I move HEAD back to the previous location?

I have the SHA1 frag (23b6772) of the commit that I need to move it to.
How can I get back to this commit?


回答1:


Before answering let's add some background, explaining what is this HEAD.

First of all what is HEAD?

HEAD is simply a reference to the current commit (latest) on the current branch.
There can only be a single HEAD at any given time. (excluding git worktree)

The content of HEAD is stored inside .git/HEAD and it contains the 40 bytes SHA-1 of the current commit.


detached HEAD

If you are not on the latest commit - meaning that HEAD is pointing to a prior commit in history its called detached HEAD.

On the command line, it will look like this- SHA-1 instead of the branch name since the HEAD is not pointing to the tip of the current branch

A few options on how to recover from a detached 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

This will checkout new branch pointing to the desired commit.
This command will checkout to a given commit.
At this point, you can create a branch and start to work from this point on.

# 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

You can always use the reflog as well.
git reflog will display any change which updated the HEAD and checking out the desired reflog entry will set the HEAD back to this commit.

Every time the HEAD is modified there will be a new entry in the reflog

git reflog
git checkout HEAD@{...}

This will get you back to your desired commit


git reset --hard <commit_id>

"Move" your HEAD back to the desired commit.

# 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.
  • Note: (Since Git 2.7)
    you can also use the git rebase --no-autostash as well.

git revert <sha-1>

"Undo" the given commit or commit range.
The reset command will "undo" any changes made in the given commit.
A new commit with the undo patch will be committed while the original commit will remain in the history as well.

# 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>

This schema illustrates which command does what.
As you can see there reset && checkout modify the HEAD.




回答2:


Here's an approach that may be very simple and easy to remember. Check 2 conditions and finish with 1 command. Then you're back on track.

If

you are in 'detached head'
(i.e. type git status; you see HEAD detached at <commit_id>)

And

an existing branch suits your needs
(i.e. type git branch -v; you see a branch name with a related commit messages representing the work you want to continue)

Then

simply check out that branch (i.e. type git checkout <branch_name>; you see Switched to branch <branch_name>).

Outcomes

You can now continue adding and committing your work as before; changes will be tracked on <branch_name>.

Note that if you had saved work while HEAD was detached, in most cases that work will be merged automatically in the above process. If you see a message about a merge conflict, don't panic. There are several great tutorials with simple steps for fixing the conflict and completing the merge.




回答3:


Do

git reset 23b6772

To see if you on the right position:

git status

You will see something

On branch master Your branch is behind 'origin/master' by 17 commits, and can be fast-forwarded.

Then fix the HEAD to current commit:

git push --force



回答4:


The question can be read as:

I was in detached-state with HEAD at 23b6772 and typed git reset origin/master (because I wanted to squash). Now I've changed my mind, how do I go back to HEAD being at 23b6772?

The straight-forward answer being: git reset 23b6772

But I hit this question because I got sick of typing (copy & pasting) commit hashes or its abbreviation each time I wanted to reference the previous HEAD and was Googling to see if there were any kind of shorthand.

It turns out there is!

git reset - (or in my case git cherry-pick -)

Which incidentally was the same as cd - to return to the previous current directory in *nix! So hurrah, learned two things with one stone.




回答5:


When you run the command git checkout commit_id then HEAD detached from 13ca5593d(say commit-id) and branch will be on longer available.

Move back to previous location run the command step wise- a) git pull origin branch_name(say master) b) git checkout branch_name c) git pull origin branch_name

You will be back to previous location with updated commit from remote repository.




回答6:


Today, I mistakenly checkout on a commit and starts working on it makes some commits on detach HEAD state. Then what I did I pushed to remote branch using following command

git push origin HEAD: <My-remote-branch>

then

git checkout <My-remote-branch>

then

git pull 

I finally gets my all changes in my branch that I made in detach HEAD



来源:https://stackoverflow.com/questions/34519665/how-to-move-head-back-to-a-previous-location-detached-head-undo-commits

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!