317

I have recently moved from SVN to Git and am a bit confused about something. I needed to run the previous version of a script through a debugger, so I did git checkout <previous version hash> and did what I needed to do.

Now I want to get back to the newest version, but I don't know the hash for it. When I type git log, I don't see it.

How can I do this? Also, is there an easier way to change versions than by typing out hashes - something like "go back two versions" or "go to the most chronologically recent"?

Mateusz Piotrowski
  • 6,087
  • 9
  • 44
  • 71
Nathan Long
  • 113,812
  • 91
  • 316
  • 418

10 Answers10

391

git checkout master should do the trick. To go back two versions, you could say something like git checkout HEAD~2, but better to create a temporary branch based on that time, so git checkout -b temp_branch HEAD~2

Ana Betts
  • 71,086
  • 16
  • 135
  • 201
  • 8
    Cool! `git checkout master` is exactly how I switch back from a branch. So does that mean that when I check out a previous version, I'm essentially creating a branch? – Nathan Long Aug 24 '10 at 17:19
  • 5
    @Nathan: In git a branch is really mostly a movable pointer to a certain revision. So conceptually, you're sort of creating a branch, but not in the sense that git thinks of branches. – DLH Aug 24 '10 at 17:26
  • 3
    So in the simplest case, where I've got a bunch of linear changes, when I checkout an earlier revision, I'm moving the HEAD pointer there, which means `git log` will display relative to that point? And when I checkout master, I move the pointer to the latest version of the master branch? – Nathan Long Aug 24 '10 at 17:30
  • 8
    @Nathan: Exactly. HEAD is something called a symbolic ref - it's in general a pointer to another ref (the currently checked out branch). `git checkout` is a way to move HEAD around. When you detached HEAD, you made it point straight to that given commit; when you check out master again it points back to master. (And many many commands like `git log` actually take a revision range, which defaults to HEAD.) – Cascabel Aug 24 '10 at 17:39
  • 3
    Yep - HEAD is the "pronoun" used to refer to "The version of the code that's in the working directory". It's also the pronoun for "The parent of whatever you commit next" – Ana Betts Dec 03 '13 at 10:07
  • when I use git checkout master I get this error message. "error: pathspec 'master' did not match any file(s) known to git." Does anyone know why? – user1601259 Oct 08 '15 at 04:44
  • Oh I think I figured it out, I had to checkout the previous branch I was on and that fixed the issue – user1601259 Oct 08 '15 at 04:51
  • 2
    To be more generic the command should be `git checkout `. If you want to checkout to master branch specifically, then the above command works. – Ashutosh Chamoli Nov 30 '18 at 03:26
59

When you checkout to a specific commit, git creates a detached branch. So, if you call:

$ git branch 

You will see something like:

* (detached from 3i4j25)
  master
  other_branch

To come back to the master branch head you just need to checkout to your master branch again:

$ git checkout master

This command will automatically delete the detached branch.

If git checkout doesn't work you probably have modified files conflicting between branches. To prevent you to lose code git requires you to deal with these files. You have three options:

  1. Stash your modifications (you can pop them later):

    $ git stash
    
  2. Discard the changes reset-ing the detached branch:

    $ git reset --hard
    
  3. Create a new branch with the previous modifications and commit them:

    $ git checkout -b my_new_branch
    $ git add my_file.ext
    $ git commit -m "My cool msg"
    

After this you can go back to your master branch (most recent version):

$ git checkout master
Thomio
  • 1,205
  • 14
  • 16
41

This did the trick for me (I still was on the master branch):

git reset --hard origin/master
Liam
  • 22,818
  • 25
  • 93
  • 157
averasko
  • 940
  • 7
  • 15
  • 39
    **reset --hard** is a overkill and demonstrates you are not aware of the modifications you made. This can result it losing code. – Thomio Mar 08 '16 at 13:38
  • 1
    In my case I wanted to get rid of unpushed accidentally committed changes. I know there can be other methods to achieve that. I agree if you don't want to loose your unpushed committed changes this is data loss. – Csaba Toth Aug 31 '17 at 23:57
  • There is a small detail in this answer. If the remote branch received a forced push commit (because of a `rebase` or `amend` for example) your local/remote branch will diverge and you need to reset the local branch to the remote one, updating your local branch with the remote modifications. In this case, you are not really **going back** to the most recent version. For a proper answer, search for `git remote branch diverged` – Thomio Sep 15 '20 at 18:09
9

To return to the latest version:

git checkout <branch-name> 

For example, git checkout master or git checkout dev

Reggie Pinkham
  • 9,381
  • 3
  • 34
  • 32
9

Some of the answers here assume you are on master branch before you decided to checkout an older commit. This is not always the case.

git checkout -

Will point you back to the branch you were previously on (regardless if it was master or not).

Itai Noam
  • 2,217
  • 2
  • 15
  • 11
  • Not necessary a branch, it will point HEAD to where it was pointing to before; if you did `git checkout hash2` after `git checkout hash1`, `git checkout -` will take you back to `hash1`. – Mikhail Vasin Oct 17 '19 at 10:58
7

You can check out using branch names, for one thing.

I know there are several ways to move the HEAD around, but I'll leave it to a git expert to enumerate them.

I just wanted to suggest gitk --all -- I found it enormously helpful when starting with git.

Jay
  • 51,986
  • 8
  • 91
  • 118
7

I am just beginning to dig deeper into git, so not sure if I understand correctly, but I think the correct answer to the OP's question is that you can run git log --all with a format specification like this: git log --all --pretty=format:'%h: %s %d'. This marks the current checked out version as (HEAD) and you can just grab the next one from the list.

BTW, add an alias like this to your .gitconfig with a slightly better format and you can run git hist --all:

  hist = log --pretty=format:\"%h %ai | %s%d [%an]\" --graph

Regarding the relative versions, I found this post, but it only talks about older versions, there is probably nothing to refer to the newer versions.

Community
  • 1
  • 1
haridsv
  • 7,212
  • 4
  • 56
  • 57
3

When you go back to a previous version,

$ git checkout HEAD~2
Previous HEAD position was 363a8d7... Fixed a bug #32

You can see your feature log(hash) with this command even in this situation;

$ git log master --oneline -5
4b5f9c2 Fixed a bug #34
9820632 Fixed a bug #33
...

master can be replaced with another branch name.

Then checkout it, you'll be able to get back to the feature.

$ git checkout 4b5f9c2
HEAD is now at 4b5f9c2... Fixed a bug #34
kujiy
  • 4,258
  • 1
  • 24
  • 30
1

With Git 2.23+ (August 2019), the best practice would be to use git switch instead of the confusing git checkout command.

To create a new branch based on an older version:

git switch -c temp_branch HEAD~2

To go back to the current master branch:

git switch master
VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
0

A more elegant and simple solution is to use

git stash

It will return to the most resent local version of the branch and also save your changes in stash, so if you like to undo this action do:

git stash apply
Ilya Gazman
  • 27,805
  • 19
  • 119
  • 190
  • I know it is very old but I have to make a comment on this (since I think this solution shouldn't be used) - I would not use this solution because it does not solve this problem but a different problem. with this stash solution every time you want to checkout to a previous commit you actually "save" data which is very unnecessary for this case. The right and more elegant way is (as stated before) to just checkout . – Maayao Mar 28 '19 at 09:37