27

To track down at which point I broke a feature in my software, I need to review older versions of my repository. I just want to set the working directory to an older commit, play with the code, afterwards discard the changes, and then try another commit.

I do not want to change anything about commits, neither remove nor create ones. I tried using git reset but after that newer commit weren't shown anymore. So I downloaded the repository again, because I didn't know how to revert that.

danijar
  • 32,406
  • 45
  • 166
  • 297
  • I came to this after googling "[swap working directory to an earlier commit but leave head unchanged](https://www.google.co.uk/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#safe=active&q=swap+working+directory+to+an+earlier+commit+but+leave+head+unchanged)". I ended up using `git checkout -- ` for each of the files I wanted to revert to the earlier commit – dumbledad Nov 01 '16 at 15:53

3 Answers3

21

A simple git checkout old-sha1 can be a start, but the real command for that kind of task is:

git bisect.

Find by binary search the change that introduced a bug

If you have a script able to test if your working tree "works" or not, you can execute that script on previous commits through git bisect, locating the first commit which breaks your test.

Note that this command isn't yet supported directly by GitHub for Windows: you will have to open a shell.


A git checkout would leave you in a detached HEAD, which doesn't matter since you won't make any modification.
To get back to were you were, checkout a branch:

git checkout master

See "Why did git detach my head?".

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thanks, I thought `checkout` is only for branches before. Which kind of script could I use for `bisect`? My application is written in native C++. By the way I am impressed by Git to include such a command. – danijar May 14 '13 at 09:43
  • @danijar no, you can checkout any treeish. For instance, `git checkout "@{10 minutes ago}"` would give you the commit from 10 minutes ago. – VonC May 14 '13 at 09:45
  • @danijar for git bisect, any script you want as long as it exits with status 0 (works) or 1 (fails). – VonC May 14 '13 at 09:45
  • I used `checkout` and Git told me I am in "detached Head" state now. What does that mean? How can I get back to the newest commit? – danijar May 14 '13 at 09:56
  • @danijar I have edited the answer to address the detached head aspect. – VonC May 14 '13 at 10:27
12

You can checkout the code in another branch to the index by using the following:

git checkout my-other-branch .

The dot is a path specifier indicating you want to do this for the entire repository. You could likewise specify only a specific folder. Technically, you can specify any 'tree-ish' specifier for the my-other-branch parameter, such as a tag, a commit hash, something like HEAD~1, ect... If you want these changes to be unstaged, you could then do:

git reset HEAD

Assuming you began in a clean state, you'll now have your working directory be in the same state as my-other-branch.

mhand
  • 1,231
  • 1
  • 11
  • 21
  • This one worked for me. Without dot specifier files in work directory was not restored. – dess Apr 15 '21 at 15:59
3

Using git checkout <branch_name> you can switch to the other available branch. If you want to reset your HEAD to the older commit, you can try the following command :

  • git reset --hard HEAD~1 to reset the HEAD by a single commit
  • git reset --hard HEAD~2 to reset the HEAD by 2 commits and so on

Also if you have the commit, then you can try this command : git reset --hard <commit> In this way you can set the working directory to an older commit.

To completely discard the changes you can try : git reset --hard which will clean your directory to the previous commit.

Kedar Tiwaskar
  • 1,292
  • 1
  • 10
  • 16