How do I view the history of an individual file with complete details of what has changed?
git log -- [filename]
shows me the commit history of a file, but how do I see the file content that changed?
How do I view the history of an individual file with complete details of what has changed?
git log -- [filename]
shows me the commit history of a file, but how do I see the file content that changed?
For a graphical view, use gitk
:
gitk [filename]
To follow the file across file renames:
gitk --follow [filename]
gitk -- [filename]
. –
Mccowyn gitk --follow [filename]
shows the history of the file past renames. It doesn't show the file content's changes before the renaming, though. See this answer. –
Sherasherar git log -- [filename]
–
Indemnification gitk
is not part of the basic git package. You need to download the tk package to use gitk. @VolkA's answer is better, git log -p filename
works without any dependencies. –
Hara git log -p
answer below is much more applicable to a majority of users. –
Desrochers gitk
? –
Eveevection gitk
is, you'll find it as part of Git for Windows
. Launch from the git-bash.exe
application (a Linux command-line emulator). Git for Windows
, git bash
and gitk
are awesome... –
Heterogynous This lets Git generate the patches for each log entry:
git log -p -- filename
See git help log
for more options — it can actually do a lot of nice things. :)
To get just the diff for a specific commit, use
git show HEAD
or specify any other revision by identifier.
To browse the changes visually:
gitk
--follow
will also consider file renames. –
Rolan --follow
flag –
Odisodium -p
= Generate patch
= show diff except commit description –
Rosina meld
, another graphical tool, using git difftool
. –
Bateau For a graphical view, use gitk
:
gitk [filename]
To follow the file across file renames:
gitk --follow [filename]
gitk -- [filename]
. –
Mccowyn gitk --follow [filename]
shows the history of the file past renames. It doesn't show the file content's changes before the renaming, though. See this answer. –
Sherasherar git log -- [filename]
–
Indemnification gitk
is not part of the basic git package. You need to download the tk package to use gitk. @VolkA's answer is better, git log -p filename
works without any dependencies. –
Hara git log -p
answer below is much more applicable to a majority of users. –
Desrochers gitk
? –
Eveevection gitk
is, you'll find it as part of Git for Windows
. Launch from the git-bash.exe
application (a Linux command-line emulator). Git for Windows
, git bash
and gitk
are awesome... –
Heterogynous git log --follow -p -- path-to-file
This will show the entire history of the file (including history beyond renames and with diffs for each change).
In other words, if the file named bar
was once named foo
, then git log -p bar
(without the --follow
option) will only show the file's history up to the point where it was renamed -- it won't show the file's history when it was known as foo
. Using git log --follow -p bar
will show the file's entire history, including any changes to the file when it was known as foo
. The -p
option ensures that diffs are included for each change.
-CC
flag with log --follow file
or it will find nothing (git 1.7.0.4). –
Phelgon --follow
ensures that you see file renames (2.) -p
ensures that you see how the file gets changed (3.) it is command line only. –
Mislead --
before your file
, and this would be absolutely the best answer! –
Lowther --
was added, but I don't know why this makes it best? What is it that it does? –
Capitally --
option tells Git that it has reached the end of the options and that anything that follows --
should be treated as an argument. For git log
this only makes any difference if you have a path name that begins with a dash. Say you wanted to know the history of a file that has the unfortunate name "--follow": git log --follow -p -- --follow
–
Sobriquet --
is useful because it can also guard against any revision
names that match the filename you've entered, which can actually be scary. For example: If you had both a branch and a file named foo
, git log -p foo
would show the git log history up to foo
, not the history for the file foo
. But @DanMoulding is right that since the --follow
command only takes a single filename as its argument, this is less necessary since it can't be a revision
. I just learned that. Maybe you were right to leave it out of your answer then; I'm not sure. –
Lowther --follow
it would be useful to explain -p
too. –
Octarchy --all
to see the file history in all branches. might be useful in some cases. –
Filigree skipping...
followed by series of tildes ~
(presumably one for each commit/ I dunno). –
Burgwell fatal: unrecognized argument: --folow
. But the command git log -p <file/to/the/path>
worked. –
Floria fatal: --follow requires exactly one pathspec
–
Friulian tig
is a terminal-based viewer with color support similar to the GUI-based gitk
.
Quick Install:
Use it to view history on a single file: tig [filename]
Or browse the detailed repository history via: tig
tig -- path/to/specific/file
–
Mcwherter tig --follow filename
. Thank you so much @falken for helping us discover such a wonderful TUI tool. –
Atwood git whatchanged -p filename
is also equivalent to git log -p filename
in this case.
You can also see when a specific line of code inside a file was changed with git blame filename
. This will print out a short commit id, the author, timestamp, and complete line of code for every line in the file.
This is very useful after you've found a bug and you want to know when it was introduced (or whose fault it was).
If you use Sourcetree to visualize your repository (it's free and quite good) you can right click a file and select Log Selected
The display (below) is much friendlier than gitk and most the other options listed. Unfortunately (at this time) there is no easy way to launch this view from the command line — Sourcetree's CLI currently just opens repositories.
gitk
to find the SHA1
hash, and then open SourceTree
to enter Log Selected..
based on the found SHA1
. –
Gulfweed To show what revision and author last modified each line of a file:
git blame filename
or if you want to use the powerful blame GUI:
git gui blame filename
Summary of other answers after reading through them and playing a bit:
The usual command line command would be
git log --follow --all -p dir/file.c
But you can also use either gitk (GUI) or tig (text UI) to give much more human-readable ways of looking at it.
gitk --follow --all -p dir/file.c
tig --follow --all -p dir/file.c
Under Debian/Ubuntu, the install command for these lovely tools is as expected:
sudo apt-get install gitk tig
And I'm currently using:
alias gdf='gitk --follow --all -p'
so that I can just type gdf dir
to get a focussed history of everything in subdirectory dir
.
--all
is for all branches, the rest is explained in @Dan's answer –
Filigree You can use Visual Studio Code with GitLens. It's a very powerful tool.
After having installed GitLens, go to GitLens tab, select FILE HISTORY
and you can browse it.
donjayamanne.githistory
–
Stationary Add this alias to your .gitconfig:
[alias]
lg = log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\n--abbrev-commit --date=relative
And use the command like this:
> git lg
> git lg -- filename
The output will look almost exactly the same as the gitk output. Enjoy.
git lg -p filename
- it returns a beautiful diff of searched file. –
Whereupon Lately I discovered tig
and found it very useful. There are some cases I'd wish it does A or B but most of the time it's rather neat.
For your case, tig <filename>
might be what you're looking for.
You can also try this which lists the commits that has changed a specific part of a file (implemented in Git 1.8.4).
The result returned would be the list of commits that modified this particular part. Command:
git log --pretty=short -u -L <upperLimit>,<lowerLimit>:<path_to_filename>
where upperLimit is the start line number and lowerLimit is the ending line number of the file.
More details are at http://techpurohit.in/list-some-useful-git-commands.
techpurohit.com
no longer exists. –
Corenecoreopsis In the Sourcetree UI, you can find the history of a file by selecting the 'Log Selected' option in the right click context menu:
It would show the history of all the commits.
I wrote git-playback for this exact purpose
pip install git-playback
git playback [filename]
This has the benefit of both displaying the results in the command line (like git log -p
) while also letting you step through each commit using the arrow keys (like gitk
).
If you want to see the whole history of a file, including on all other branches use:
gitk --all <filename>
If you're using the Git GUI (on Windows):
Under the Repository
menu, you can use Visualize master's History
.
Highlight a commit in the top pane and a file in the lower right and you'll see the diff for that commit in the lower left.
With the excellent Git Extensions, you go to a point in the history where the file still existed (if it have been deleted, otherwise just go to HEAD), switch to the File tree
tab, right-click on the file and choose File history
.
By default, it follows the file through the renames, and the Blame
tab allows to see the name at a given revision.
It has some minor gotchas, like showing fatal: Not a valid object name
in the View
tab when clicking on the deletion revision, but I can live with that. :-)
To get all commits for a specific file use this command:
git rev-list HEAD --oneline FileName
For example
git rev-list HEAD --oneline index.html
Output
7a2bb2f update_index_with_alias
6c03e56 update_changes
e867142 Revert "add_paragraph"
If you want to view the changes that make on the file
git log -p fileName
The answer I was looking for wasn't here. It was to see changes in files that I'd staged for commit. I.e.,
git diff --cached
git diff origin/master
to show the complete differences between your local branch and the master branch (which can be updated from remote via git fetch
) –
Kelsiekelso git diff --cached path/to/file.xml
–
Dacoity Here's my preference: view the change history visually in meld, one commit at a time, going backwards in time, starting at commit commit
:
# Option 1: for all files and folders
git difft commit
# Option 2: just for the specified files and folders
git difft commit -- path/to/file.c path/to/folder/
I wrote git difft
. Installation instructions are below.
meld
If you want to just see which commits changed a file, so you can do git difftool
on them to graphically see the changes with meld
(as I explain here), do this instead:
git log --follow --oneline -- path/to/file.c
Sample run and output:
eRCaGuy_hello_world$ git log --follow --oneline -- c/alsa_aplay__play_tone_sound_WIP.c
04b67fb (HEAD -> master) Update c/alsa_aplay__play_tone_sound_WIP.c
301122a wip: alsa_aplay__play_tone_sound.c: finish initial version of program
d4e8092 wip: add c/alsa_aplay__play_tone_sound.c
Now I can just look at the last changes graphically in meld
like this (pulling the commit hashes from the output above).
Note that I intentionally leave off the filename so that it can properly track the file automatically for me since the file was renamed, and I know these commits likely only edited this file anyway:
# just the last change
git difftool 04b67fb~..04b67fb
# and the one before that
git difftool 301122a~..301122a
# ...and before that
git difftool d4e8092~..d4e8092
If you need to specify the filename, just do so with:
git difftool 04b67fb~..04b67fb -- path/to/file.c
git difft
Install meld
as your git difftool
, per my instructions.
Install my git difft
wrapper from my eRCaGuy_dotfiles repo.
In Linux, it runs in the terminal. In Windows, it runs in the Git Bash terminal which comes with Git for Windows.
Installation instructions, as modified from my git diffn
installation instructions here, are:
mkdir -p ~/bin
cd ~/bin
curl -LO https://raw.githubusercontent.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/master/useful_scripts/git-difft.sh
chmod +x git-diffn.sh
mv git-diffn.sh git-diffn
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc
. ~/.bashrc
See also the instructions in the top of the git-difft.sh
file.
Usage:
# Look at changes from just one commit at at time, going backwards from the
# current commit
git difft
# Look at changes starting from commit `commit`
git difft commit
You can also specify a set of files or folders to track, like this:
git difft commit -- path/to/file.c path/to/folder/
git difft commit -- path/to/file1 path/to/file2 path/to/file3
git difft -- path/to/some/dir
# etc/
Press Ctrl + C, then Enter to skip the current commit and go to the next one back in time.
Or, press Ctrl + C twice to exit the program.
Here is the full help menu, as shown by git difft -h
:
'git-difft' version 0.2.0
Iterate through all commits going backwards from HEAD to the first commit, one commit at a time,
running 'git difftool' on each one to see the changes it introduced.
- Press Ctrl + C once, then Enter, to break out of the current 'git difftool' command, but continue
on with the previous commit.
- Press Ctrl + C twice to exit out of the whole program.
USAGE:
git-difft [OPTIONS] [[commit] [commit_start~..commit_end]] -- [file1 file2 file3 ...]
OPTIONS
-h, -?
Print help menu
-v, --version
Print version information.
--
Lists of files or directories go after this point.
EXAMPLE USAGES:
git-difft -h
Print help menu.
git-difft
Start running 'git difftool' on the commit starting at HEAD (the currently-checked-out
commit).
git-difft HEAD
Same as above.
git-difft HEAD~
Start running 'git difftool' on the commit starting at HEAD~ (one before HEAD).
git-difft HEAD~2
Start running 'git difftool' on the commit starting at HEAD~2 (two before HEAD).
git-difft abcdefg
Start running 'git difftool' on commit hash abcdefg.
git-difft my_branch
Start running 'git difftool' on the commit at the tip of branch 'my_branch'.
git-difft commit1~..commit2
Run 'git difftool' on all commits between commit1 and commit2, inclusive.
git-difft commit1..commit2
Run 'git difftool' on all commits between commit1 and commit2, including commit2 but
NOT including commit1.
git-difft commit1~..commit2 -- file1 file2 file3
Run 'git difftool' on all commits between commit1 and commit2, inclusive, but only
for the files file1, file2, and file3.
git-difft -- path/to/file1
Start running 'git difftool' on the commit starting at HEAD, but only for the file
"path/to/file1".
git-difft -- path/to/dir1
Start running 'git difftool' on the commit starting at HEAD, but only for the files
in the directory "path/to/dir1/".
This program is part of eRCaGuy_dotfiles: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles
by Gabriel Staples.
If you use TortoiseGit you should be able to right click on the file and do TortoiseGit --> Show Log
. In the window that pops up, make sure:
'Show Whole Project
' option is not checked.
'All Branches
' option is checked.
git diff -U <filename>
give you a unified diff.
It should be colored on red and green. If it's not, run: git config color.ui auto
first.
If you are using Eclipse with the Git plugin, it has an excellent comparison view with history. Right click the file and select "Compare With" → "History".
You can use git log command as the following:
git log -L 992,+4:path-to-file
Explanation:
Here the 992
shows the line number you want to see the revision information,
+4
indicates how many lines you want to see after the specified line 992
.
And lastly path-to-file , it generally starts with ./src/..
I'm probably about where the OP was when this started, looking for something simple that would let me use git difftool with vimdiff to review changes to files in my repo starting from a specific commit. I wasn't too happy with answers I was finding, so I threw this git incremental reporter (gitincrep) script together and it's been useful to me:
#!/usr/bin/env bash
STARTWITH="${1:-}"
shift 1
DFILES=( "$@" )
RunDiff()
{
GIT1=$1
GIT2=$2
shift 2
if [ "$(git diff $GIT1 $GIT2 "$@")" ]
then
git log ${GIT1}..${GIT2}
git difftool --tool=vimdiff $GIT1 $GIT2 "$@"
fi
}
OLDVERS=""
RUNDIFF=""
for NEWVERS in $(git log --format=format:%h --reverse)
do
if [ "$RUNDIFF" ]
then
RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
elif [ "$OLDVERS" ]
then
if [ "$NEWVERS" = "${STARTWITH:=${NEWVERS}}" ]
then
RUNDIFF=true
RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
fi
fi
OLDVERS=$NEWVERS
done
Called with no args, this will start from the beginning of the repo history, otherwise it will start with whatever abbreviated commit hash you provide and proceed to the present - you can ctrl-C at any time to exit. Any args after the first will limit the difference reports to include only the files listed among those args (which I think is what the OP wanted, and I'd recommend for all but tiny projects). If you're checking changes to specific files and want to start from the beginning, you'll need to provide an empty string for arg1. If you're not a vim user, you can replace vimdiff with your favorite diff tool.
Behavior is to output the commit comments when relevant changes are found and start offering vimdiff runs for each changed file (that's git difftool behavior, but it works here).
This approach is probably pretty naive, but looking through a lot of the solutions here and at a related post, many involved installing new tools on a system where I don't have admin access, with interfaces that had their own learning curve. The above script did what I wanted without dealing with any of that. I'll look into the many excellent suggestions here when I need something more sophisticated - but I think this is directly responsive to the OP.
© 2022 - 2024 — McMap. All rights reserved.