tags:

views:

217

answers:

3

A common thing I'd like to do is revert my working copy to a particular revision, do some testing, and then bring it back to the head of my current master. In the past I have naively done a "git checkout hash" only to lose my head. I've since learned I can create a branch and check that out, switch back and delete the branch, but it feels like too many steps for a simple check. In SVN parlance, is there a way to quickly revert and then quickly go back to the tip of trunk in git?

Edit: I think my confusion stems from the fact that when I checkout a hash and then git log, I don't see the changes that happened after the checked out hash (which is reasonable, when you think of it). But the accepted answer is correct; "git checkout branch" will restore the head to the previous branch.

+2  A: 

If you want Git to show the tip of some line of changes, you need to have it branched or tagged. But even if you do not make a branch, none of the commits is lost. It stays in the repository as a garbage node (i.e. not reachable through any branch or tag), and is removed only some days/weeks later when you do "git gc".

So if you want to have an easy access to the changes, it's best to create a temporary branch and work there. If you do commits outside a branch and then checkout another branch, then you will need to use the command "git reflog" or look into the logs (".git/logs" directory) to find out what was the hash of the changes that you lost. When you know the hash, you can do "git checkout hash" or "git checkout -b new_branch hash" and recover the tip.

Esko Luontola
What do you mean by "show" in "show the tip of some line of changes"? If I do the (IMO) natural thing and "checkout hash" I find that there is no way to get back to where I was without (somehow) knowing the hash where I was.
Nick
By Git showing some line of changes, I mean that you can see it with commands such as "git branch", "git tag" or "gitk --all". Do you mean by "knowing the hash where I was" that you were doing work outside a branch? You are not supposed to know the hash where you were - you are supposed to know the branch where you were.
Esko Luontola
+2  A: 

Yes, you can visit any arbitrary revision with "git checkout" as you describe. If you ask for an arbitrary revision rather than a branch, git will not have any obvious way to keep track of what changes you make, though. You can see where you were before by consulting the reflog ("git reflog show") - but in general, you would have been on a branch before so presumably just want to change back to that with "git checkout master" or similar.

Note that this method won't automatically deal with uncommitted changes in your workspace--- either commit or stash your changes before moving between branches, or use "git checkout -m" to carry them around as you move (and be prepared to deal with merge conflicts if the changes you're carrying aren't trivial).

I think recent git versions have introduced the shorthand "@{-1}" for "where I was before I last moved", which might actually be what you want in this case. (I haven't used it, just read about it in the release notes).

araqnid
"If you ask for an arbitrary revision rather than a branch, you won't be able to commit any changes, of course." -- You *can* commit. It's just that you will be working on "(no branch)" (as shown by "git branch"), so finding the commit after checking out another branch will be hard, unless you write down the commit's hash or dig it out from the logs.
Esko Luontola
Yes, good point; I admit, I didn't try it first.
araqnid
+2  A: 

Assuming you're already on a branch (which you always should be for changes you want to keep), you can just do

git checkout <revision to check out>

This will take you off the topic branch you were working on into (no branch), in which the working copy refers directly to a commit ID rather than a branch name as normal.

Then to move back, simply:

git checkout <old branch name>

A helpful way to think of it is this: git checkout never alters branches; it merely changes what your working copy is currently looking at (ie, HEAD), which might either be a branch (in which case commits will update the branch) or a random commit hash.

As such, as long as the changes you want to keep are on a branch, you don't have to worry about git checkout losing them.

bdonlan