View the change history of a file using Git versioning

Viewed 2150896

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?

25 Answers

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

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 who's fault it was).

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.

Enter image description here

In the Sourcetree UI, you can find the history of a file by selecting the 'Log Selected' option in the right click context menu:

Enter image description here

It would show the history of all the commits.

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.

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

See gif imagegit commits for specific files

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.

Related