git-checkout older revision of a file under a new name

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.


Single file use case

In order to get consistent checkout behavior including autocrlf etc., use a secondary folder (TEMP as example) and restore the file state from an older / different <commit> like this:

git --work-tree TEMP/ restore main.cpp -s <commit>
mv TEMP/main.cpp old_main.cpp

Use an alias to make it a one-line command

git restore-as old_main.cpp main.cpp -s <commit>

Create the alias:

git config --global alias.restore-as "!f() { git --work-tree /tmp/ restore $2 $3 $4 $5 $6 && mv -iv /tmp/$2 $1; }; f"

(Best replace /tmp/ with a directory reserved for such operations - e.g. /tmp/gitmv - after creating that.)

Note:

git show <commit>:main.cpp > old_main.cpp

.. will just produce a raw read from the repository.

Use a 2nd work tree - linked or anonymous

A long-term parallel working tree (linked / known to the repository with main worktree) can be used via git-worktree (new since git v2.6.7) and can have its HEAD on a different branch / <commit> :

git worktree add [<options>] <new-worktree-path> [<commit-ish>]

The worktree could be created without initial checkout (--no-checkout), and subsequently sparse-checkout could be configured, or just selected individual files / sub-dirs could be retrieved via git restore -s <commit> <file(s)/sub-dir>

Similarly an extra anonymous worktree (sharing the HEAD) could be created, by simply puting a file .git into it with content

gitdir: <MAIN-REPO-WORKTREE>/.git

You can use git show for that:

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:

<rev>:<path>, e.g. HEAD:README, :README, master:./README

A suffix : followed by a path names the blob or tree at the given path in the tree-ish object named by the part before the colon. :path (with an empty part before the colon) is a special case of the syntax described next: content recorded in the index at the given path. A path starting with ./ or ../ is relative to the current working directory. The given path will be converted to be relative to the working tree’s root directory. This is most useful to address a blob or tree from a commit or tree that has the same tree structure as the working tree.

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.)

If you want to use path relative to the current directory, you need to use ./<path> syntax (or ../path to go up from current directory).

Edit 2015-01-15: added information about relative path syntax


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

git cat-file blob HEAD^:main.cpp > old_main.cpp

Tags:

Git