Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reset Git to commit without changing HEAD to detached state

Tags:

I'd like to restore the files of the git working copy to a given commit, without setting that commit as the HEAD commit.

If I git checkout to a given commit I obtain a detached HEAD, and after commiting changes, the commit tree would look something like:

A | B | C   | \ D  E 

While the behaviour I'd like to obtain is:

A | B | C | D | <- git command so my files are restored to C, but my HEAD still points to D E 

Thanks

like image 745
Josep Rodríguez López Avatar asked Dec 15 '12 21:12

Josep Rodríguez López


People also ask

How do you reset head in git to a specific commit?

To hard reset files to HEAD on Git, use the “git reset” command with the “–hard” option and specify the HEAD. The purpose of the “git reset” command is to move the current HEAD to the commit specified (in this case, the HEAD itself, one commit before HEAD and so on).

Does git reset HEAD keep changes?

The easiest way to undo the last Git commit is to execute the “git reset” command with the “–soft” option that will preserve changes done to your files. You have to specify the commit to undo which is “HEAD~1” in this case. The last commit will be removed from your Git history.

How do I fix a detached committed head?

If you want to keep changes made with a detached HEAD, just create a new branch and switch to it. You can create it right after arriving at a detached HEAD or after creating one or more commits. The result is the same. The only restriction is that you should do it before returning to your normal branch.

What does resetting a commit do?

Reset A Specific Commit On the commit-level, resetting is a way to move the tip of a branch to a different commit. This can be used to remove commits from the current branch. For example, the following command moves the hotfix branch backwards by two commits.


2 Answers

This should do it:

git reset --hard C git reset --soft D 

First you reset the HEAD, index and worktree to C.
Then you reset HEAD (and only HEAD, as explained in "Practical uses of git reset --soft?") to D.

Note that a commit at this point would create a new commit with C content, replacing D by a D' looking like C.
That changes the history, and is not much different than a simple git reset --hard C.

Another option would git revert C on top of D, but D would still be visible in the history, which might be what you don't want.

like image 125
VonC Avatar answered Oct 05 '22 19:10

VonC


VonC answer requires you to do a roundtrip. You can achieve the same thing with a single 'git checkout'

git checkout C ./

Note that you have to provide ./ otherwise git will actually check out the specified branch or commit.

like image 26
Willem D'Haeseleer Avatar answered Oct 05 '22 17:10

Willem D'Haeseleer