How can I show the complete history of a single file in Git? When I use git log <filename>
or gitk <filename>
, I only get merges. I want to see the commits from the merged branches that affect the file. I've tried --follow
and other flags and can't find a way.
Use --follow option in git log to view a file's history This lists out the commits of both the files. Still, the first commit of the TS file would be a single creation commit, and the last commit of the JS file would be a single deletion one.
Use git log --all <filename> to view the commits influencing <filename> in all branches.
gitk and git-gui gitk is a graphical history viewer. Think of it like a powerful GUI shell over git log and git grep . This is the tool to use when you're trying to find something that happened in the past, or visualize your project's history.
To find out which files changed in a given commit, use the git log --raw command. It's the fastest and simplest way to get insight into which files a commit affects.
--all
First, let me tackle one general item that applies to many git commands.
git log
looks at the revision(s) you specify, using git rev-list
to handle them. The reason you normally see many commits is that git rev-list
"walks history", unless told not to:
$ git rev-list --no-walk HEAD
d1574b852963482d4b482992ad6343691082412f
$ git rev-list HEAD
d1574b852963482d4b482992ad6343691082412f
b9491ea160d12ddfd69a9ddc79ebd264cda20679
676699a0e0cdfd97521f3524c763222f1c30a094
[snip]
However, the revisions visited by git rev-list
start from the point(s) you specify (with default = HEAD
). So any revisions that are not already part of the point(s) you specified, or its history, are omitted:
C - D <-- branchA
/
A - B - E - F - G <-- branchB
\
H - I - J - M <-- HEAD=branchC
\ /
K - L
In this diagram I've put in three branch names, and shown that HEAD
is branchC
. Each single letter represents a commit (an SHA-1). Any commit's parents are those to the left of it, either directly left or moving up or down along the parent-commit links that go between commits.
At this point, git log
will show you commits M
, L
, K
, J
, I
, H
, B
, and A
, because git log
(and git rev-list
) will start at HEAD
and walk backwards. (The precise order of these commits depends on additional arguments.)
On the other hand, git log branchB
will show you commits G
, F
, E
, B
, and A
, because starting at commit G
and walking backwards selects those commits (and no others). Similarly, git log branchA
starts with D
and walks back to A
.
If you ask git rev-list
to look at --all
, it will start at all references (all branches, all tags, all remote-branches, and all other refs in the refs/
namespace) and walk backwards. In this case, all branches alone suffices to select every commit. In repositories with tags, --branches
might get you less than --all
, since there might be some line(s) that are tagged but not marked with a branch. See the (rather overwhelming) git rev-list
documentation to see all available options here.
Adding a file name to git log
makes it skip the printing of some (many or most) of the commits it visits, through what is described in the documentation as "History Simplification". That is, git log
first selects all the commits selected by your git rev-list
arguments, but then it only shows a smaller number.
Adding --follow
makes git log
attempt to notice cases where a file is renamed across a particular commit, and in those cases, switch selected revisions to those with the previous name once it transitions across such commits in its history-walk. In other words, it tries to adjust the history simplification to correct for name changes. This rename discovery is performed dynamically (re-tested for every pair of commits). It works only when stepping backwards—the code is just not there for handling other commit-orders.
When using git diff
, you have more control over what is recognized as a rename; with git log
's --follow
, you're stuck with the compiled-in default of a 50% match.
This will show all versions of the file (merges or not):
gitk --all <filename>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With