tags:

views:

2651

answers:

4

I have the file "main.cpp" open in my editor.

I want to see the previous revision of "main.cpp" in the editor too.

The way I do it now is like this.

close "main.cpp" in the editor

prompt> mv main.cpp tmp
prompt> git checkout HEAD^ main.cpp
prompt> mv main.cpp old_main.cpp
prompt> mv tmp main.cpp
prompt>

open "main.cpp" and "old_main.cpp" in the editor

Can it be simplified, so I don't have to close "main.cpp" in the editor?

What I'm hoping for is a variant of git-checkout that can do this.


UPDATE: im using git on mac osx 10.5.7

prompt> git --version
git version 1.6.0.4
prompt>


UPDATE2: Jakub Narębski answer is:

prompt> git show HEAD^:dir1/dir2/dir3/main.cpp > old_main.cpp
prompt>
A: 

A number of us have been discussing exactly this problem, which bzr makes very easy. We think the git-style solution is to clone a new repository on the same filesystem and then checkout one branch in each repository, for comparison. git is set up to make this kind of thing very efficiently.

If you understand the scary words in the man page, you can even use git clone -s ...

Norman Ramsey
FUD. Not true: you can use "git show HEAD^:main.cpp > old_main.cpp" for that.
Jakub Narębski
Sure, if you just care about one file, that's better. But if you want to compare a whole tree, then what?
Norman Ramsey
E.g. "git diff HEAD^ -- subdirectory" -- that is what git-diff (and friends) is for. But this is outside the scope of this question, really.
Jakub Narębski
+5  A: 

You can use "git show" for that:

prompt> git show HEAD^:main.cpp > old_main.cpp

(Note that there is colon ':' character between HEAD^ and main.cpp`.) The "<revision>:<path>" syntax is described in git rev-parse manpage, next to last point in the "Specifying revisions" section:

  • A suffix ':' followed by a path; this names the blob or tree at the given path in the tree-ish object named by the part before the colon.

Note that "<path>" here is FULL path relative to the top directory of your project, i.e. the directory with .git/ directory. (Or to be more exact to "<revision>" (which in general can be any <tree-ish>, i.e. something that represents tree))


You can get in most cases the same output using low-level (plumbing) git cat-file command:

prompt> git cat-file blob HEAD^:main.cpp > old_main.cpp
Jakub Narębski
I'm interested in a full copy, but git-show shows me only the differences.. I have tried playing around with the --pretty option.. prompt> git show --pretty=fuller HEAD^ main.cppbut it didn't solve it.
neoneye
"git show HEAD^ main.cpp" (with space between HEAD^ and main.cpp) is DIFFERENT from "git show HEAD^:main.cpp" (with _colon_ ':' between HEAD^ and main.cpp).
Jakub Narębski
Hmm, with colon I see this error, so I thought that the colon was a mistake. Yes it seems like colon is the way to go, but how do I resolve this?prompt> git show HEAD^:main.cppfatal: ambiguous argument 'HEAD^:main.cpp': unknown revision or path not in the working tree.Use '--' to separate paths from revisionsprompt>
neoneye
That probably means that you have given wrong PATHNAME (unfortunately because of "git show" magic git cannot give better error message). It should be FULL pathname relative to top directory of your project: $(git ls-tree -r --name-only HEAD^ | grep main.cpp)
Jakub Narębski
Absolute path from git root dir.. AHA. That works!prompt> git show HEAD^:dir1/dir2/dir3/main.cpp > old_main.cppprompt>Thank you very much.
neoneye
What if you want to extend this problem to compare a directory or a tree containing a whole bunch of files? How would you do it?
Norman Ramsey
This is outside this question, which is about getting some other version of a file. Generally you use "git diff" (with appropriate options and limiters) for comparing directories.
Jakub Narębski
+2  A: 

Just to add to Jakub's answer: you don't even have to redirect the output to a file with >, if you are only interested in skimming the file contents in the terminal. You can just run $ git show 58a3db6:/path/to/your/file.txt.

karmi
A: 

The git show command didn't work for me either (using 1.6.4.msysgit). Maybe something to do with the Windows path separator character?

I ended up just downloading and using QGit.... much easier!

nelsonmichael