Is there a command in Git to see (either dumped to stdout, or in $PAGER
or $EDITOR
) a particular version of a particular file?
You can use git show
with a path from the root of the repository (./
or ../
for relative pathing):
$ git show REVISION:path/to/file
Replace REVISION
with your actual revision (a Git commit SHA, tag name, branch name, relative commit name, or any other way of identifying a commit in Git).
For example, to view the version of file <repository-root>/src/main.c
from 4 commits ago, use:
$ git show HEAD~4:src/main.c
Git for Windows requires forward slashes even in paths relative to the current directory. For more information, check out the man page for git-show
.
git checkout <revision>
. –
Toothsome (commit):(path to file) | vim -
. I find this much better than using the less/more that is used by default. –
Endure git show <commit>:file
Everything else just gives the most recent version. –
Mohammedanism git blame
, so it must be in the commit. –
Don REVISION
can be a commit hash. See my answer: https://mcmap.net/q/11538/-how-can-i-view-an-old-version-of-a-file-with-git –
Anders git-show
is great. Can I toggle on line numbers when using it on command line? –
Gage git show <commit>:<file> | less -N
–
Gage .
for example: git show HEAD:./subdir/main.c > foo
. This works in recent versions of git (tested in git 2.8.3 on CentOS 7) –
Duyne git add -p
. Is there a way to see the entire file as it is in the index, before I commit it? –
Barocchio fatal: Invalid object name 'REVISION'.
–
Unsearchable git show REVISION:path/to/file > path/to/file
. –
Toothsome git show <commit> -- <filename>
gives a diff, whilst git show --help
is overly verbose. Then I have to come back here. There's a reason it's called git
. –
Whereabouts --no-pager
to Git if you don't want to use less
. (This works with any Git command.) –
Toothsome git show <ref>:<path>
is different from git show <ref> -- <path>
. –
Alexandrite REVISION
with whatever revision (commit SHA, tag, branch name, relative commit string, etc.) you want to show (as written in the answer). –
Toothsome Doing this by date looks like this if the commit happened within the last 90 days:
git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt
Note that HEAD@{2013-02-25}
means "where HEAD was on 2013-02-25" in this repository (using the reflog), not "the last commit before 2013-02-25 in this branch in history".
This is important! It means that, by default, this method only works for history within the last 90 days. Otherwise, you need to do this:
git show $(git rev-list -1 --before="2013-02-26" HEAD):./fileInCurrentDirectory.txt
master
instead of HEAD@{2013-02-25}
, if you're on a branch –
Monometallism git log --since='2016-04-28 23:59:59 +0100'
? –
Lobby :
and before the filename. –
Expectoration If you like GUIs, you can use gitk:
start gitk with:
gitk /path/to/file
Choose the revision in the top part of the screen, e.g. by description or date. By default, the lower part of the screen shows the diff for that revision, (corresponding to the "patch" radio button).
To see the file for the selected revision:
- Click on the "tree" radio button. This will show the root of the file tree at that revision.
- Drill down to your file.
gitk REVISION /path/to/file
. This can come in handy when you want to check against a certain version for instance. –
Embargo sudo apt install gitk
for ubuntu –
Swarts You can also specify a commit hash
(often also called commit ID
) with the git show
command.
In a nutshell
git show <commitHash>:/path/to/file
Step by step
- Show the log of all the changes for a given file with
git log /path/to/file
- In the list of changes shown, it shows the
commit hash
such ascommit 06c98...
(06c98... being the commit hash) - Copy the
commit hash
- Run the command
git show <commitHash>:/path/to/file
using thecommit hash
of step 3 & thepath/to/file
of step 1.
Note: adding the ./
when specifying a relative path seems important, i.e. git show b2f8be577166577c59b55e11cfff1404baf63a84:./flight-simulation/src/main/components/nav-horiz.html
.
git show <SHA1> --name-only
to get it. –
Stokehole debian
, the addition of ./
does not matter for the pathing. –
Rhinelandpalatinate To quickly see the differences with older revisions of a file:
git show -1 filename.txt
> to compare against the last revision of file
git show -2 filename.txt
> to compare against the 2nd last revision
git show -3 fielname.txt
> to compare against the last 3rd last revision
:
- double colon - between commit-hash and file the commenters mention about the entire file and diff to another older version. –
Rhinelandpalatinate In addition to Jim Hunziker's answer,
you can export the file from the revision as,
git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt > old_fileInCurrentDirectory.txt
Hope this helps :)
git log -p
will show you not just the commit logs but also the diff of each commit (except merge commits). Then you can press /
, enter filename and press enter
. Press n
or p
to go to the next/previous occurrence. This way you will not just see the changes in the file but also the commit information.
git log -pm
would also show merge commits. –
Despumate git log -p -- filename.txt
to restrain the history to only the desired file. –
Better WAY 1:
Find commit id with:
git reflog
List files from commit
git diff-tree --no-commit-id --name-only -r <commitHash>
Example:
git diff-tree --no-commit-id --name-only -r d2f9ba4
whered2f9ba4
is commit id from step 1.Open required file with following command:
git show <commitHash>:/path/to/file
Example:
git show d2f9ba4:Src/Ext/MoreSwiftUI/ListCustom.swift
Src/...
is file path from step 2.
WAY 2:
///////////////
/// WARNING:
/// Ability to lose uncommitted data.
/// Perform commit or save your uncommited files to stash.
///////////////
- Find commit id with:
git reflog
- Make hard reset to this commit:
git reset --hard %commit ID%
Example:
git reset --hard c14809fa
- Make necessary changes and do a new commit into required branch
WAY 3: ( MacOS, TaoGit - it's free to use )
I prefer this way.
After steps on screenshot below you will have ability to copy all needed data even if commited data is "lost" in commit to detached head
You can use a script like this to dump all the versions of a file to separate files:
e.g.
git_dump_all_versions_of_a_file.sh path/to/somefile.txt
Get the script here as an answer to another similar question
git_root
, git_log_short
and git_log_message_for_commit
are missing. –
Holtorf Helper to fetch multiple files from a given revision
When trying to resolve merge conflicts, this helper is very useful:
#!/usr/bin/env python3
import argparse
import os
import subprocess
parser = argparse.ArgumentParser()
parser.add_argument('revision')
parser.add_argument('files', nargs='+')
args = parser.parse_args()
toplevel = subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).rstrip().decode()
for path in args.files:
file_relative = os.path.relpath(os.path.abspath(path), toplevel)
base, ext = os.path.splitext(path)
new_path = base + '.old' + ext
with open(new_path, 'w') as f:
subprocess.call(['git', 'show', '{}:./{}'.format(args.revision, path)], stdout=f)
Usage:
git-show-save other-branch file1.c path/to/file2.cpp
Outcome: the following contain the alternate versions of the files:
file1.old.c
path/to/file2.old.cpp
This way, you keep the file extension so your editor won't complain, and can easily find the old file just next to the newer one.
None of the previous answers addressed the second possibility mentioned by the OP, which is how to open the results into $EDITOR
.
Most editors on the terminal will accept reading from stdin
if you pass a single dash -
as the filename, which allows piping the output of the git show
command to the command you would use to open the editor.
As a Vim user, I'll use it as an example to clarify. You could do the following:
# The reference to a commit, branch, tag, etc
$ REVISION='...'
$ git show "$REVISION":path/to/file | vim -
One drawback of doing this is that the editor has no good hint of what is the file type you are dealing with and it may have trouble with syntax highlighting, for example. This happens because there is no file extension to look at. From the editor's perspective, it just receives a blob of bytes from stdin
.
In Vim, this can be easily solved by explicitly setting the filetype
:
$ git show "$REVISION":path/to/file.py | vim -c 'set filetype=python' -
Something very useful is to combine git show
with process substitution to compare two historical versions of a file directly using a diff utility (diff
, vimdiff
, etc). The file may have changed in position a lot inside the Git repository or maybe it was deleted for a while and later recreated. These situations give a hard time to Git to show the diff you want, but the following command does the trick:
$ vimdiff <(git show "$REV_0":path/to/file) <(git show "$REV_1":another/path/to/file)
Nice to find something to add to an almost 15 years old question!
© 2022 - 2024 — McMap. All rights reserved.
git checkout <sha1-of-the-commit-you-need>
, afterwards,git checkout HEAD
– Anthropoid