21

Here is what I want to do. I want to go back to 2 commits before, bring back the files that changed in that commit as a new commit maybe. But I do not want to lose my last commit. My last commit has some mistakes in the code but I would like to keep that one for now.

I read some documentation but none made it clear about what happens when you reset your head. Do you lose all the commits up until the one that you are resetting to (going backward) for example?

I am trying to understand how all this works but I am rather confused about git revert, reset and checkout commands.

I realize that I should have stashed the last commit instead of committing, but that is another story for now.

John Szakmeister
  • 44,691
  • 9
  • 89
  • 79
yarun can
  • 2,871
  • 5
  • 25
  • 27
  • 1
    Can you be a little more specific about what you want to do? Do you want to undo the previous commit? Or do you want to keep most of the changes those two commits made, except to a couple of files? – John Szakmeister Mar 10 '13 at 23:37
  • jszakmeister, Well I do not want to get rid of any commits. I want to keep my past history intact. I just want to bring back 2 commits before as a new working stage I guess. – yarun can Mar 10 '13 at 23:40
  • It is still unclear what does "bring back" mean. – wRAR Mar 10 '13 at 23:41
  • I was in a similar situation recently and I solved it like this: Create a new branch off of the old commit, right below the two commits you don't want. Check out the new branch and you will have exactly the state before the two unwanted commits. Your unwanted commits will be safe on the original branch. You can keep working on the new branch and once you're happy, you can merge or cherry-pick your old branch into the new one or vice-versa – Cerno Sep 28 '20 at 13:56

3 Answers3

20

If you want to go back, say 2 commits previous, you can just do git checkout HEAD~2. This will get you all as it was then. If you were on branch master, git checkout master will bring you back to the present. If, however, you want to keep the current state but start a new developemnt branch there, git checkout -b HEAD~2 will start a new branch there. In case you want to rewind master but not loose your current, unfinished/broken work, do

git branch wip           # New branch ends a current tip
git reset --hard HEAD~2  # Old branch rewound, get files from then
vonbrand
  • 11,412
  • 8
  • 32
  • 52
13

revert makes a new commit that reverts changes made by an older commit. reset --hard changes the HEAD of the current branch to the specified commit. checkout switches the working copy to the specified branch or commit.

When you reset a branch to an older commit the newer commits are lost if they are not parts of other branches or ancestors of tags (they are still accessible via reflog though).

It is not clear what do you need to do, the most probable solutions are revert (to fully revert an older commit or series of commits) and rebase -i (to change an older commit or delete it from the history).

wRAR
  • 25,009
  • 4
  • 84
  • 97
  • 1
    `git revert` has strong implications since it creates a commit that negates the changes of a previous commit. Be careful when using it unless you are sure of what you intend. – Maic López Sáenz Mar 12 '13 at 01:05
  • @LopSae created commit is not published, so you can easily remove it if it does something that you didn't want. reset and rebase are much more dangerous commands as recovery from errors is much harder. – wRAR Mar 12 '13 at 12:05
  • Hi, @wRAR. When I checkout back to a previous commit, after that, when I use git log to view commit history, all the record after the commit which I switched back to are missing. How to solve that? I mean to view the full commit history after I checkout to a previous commit. – Mario Mar 02 '14 at 03:50
  • @Mario if you don't remember the ID of the commit you need you may try to find it in `git reflog` – wRAR Mar 06 '14 at 09:48
0

With $ git reflog you can see the last hashes which are useful to return to a previous state after having lost the last commits by forcing a push from a previous commit.

Also:

$ git fsck --no-reflog
$ git show <hash>
$ git checkout -b <new-branch> <hash>

GL

Source

Braian Coronel
  • 22,105
  • 4
  • 57
  • 62