1098

Is there a way to list all commits that changed a specific file?

Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
Daniel
  • 11,315
  • 4
  • 19
  • 15

17 Answers17

1430

The --follow works for a particular file

git log --follow -- filename

Difference to other solutions given

Note that other solutions include git log path (without the --follow). That approach is handy if you want to track e.g. changes in a directory, but stumbles when files were renamed (thus use --follow filename).

OLIVER.KOO
  • 5,654
  • 3
  • 30
  • 62
jackrabb1t
  • 14,609
  • 1
  • 21
  • 20
  • 5
    This is better, it seems to list the commits concerning the file across all commits unlike just ` git log ` – Yo Ludke Jun 07 '13 at 13:48
  • 46
    +1 `--follow` accounts for renames, so this is more robust than `git log -- path` – Gabe Moothart Aug 07 '13 at 21:09
  • 60
    Note that `--follow` accepts a _path_, which can be a file but also a directory. In the case of the latter it will run recursively and report changes to all files below that point. (This behaviour is not documented in the manpage and may not be permanent.) – StvnW Nov 22 '14 at 16:48
  • 9
    @SaulOrtega, `git log filename` doesn't follow file renaming, i.e. it will show all commits regarding that **filename** (not actual file). If you create files `X` and `Y`, changed both, then deleted `Y` and renamed `X` to `Y` and then also changed it, and you run `git log Y`, you will get messages for both _old_ `Y` and _new_ one. And the opposite, with `--follow` you will get commits regarding that file when it was named `X` _and_ when it was named `Y`. – MarSoft Jun 24 '15 at 10:09
  • 13
    use "git log --all filename" for view all commits in all branches – Lebnik Aug 13 '15 at 11:22
  • Any way to do this using the GitHub API for a particular file? – code Jan 03 '18 at 17:03
  • @AbhishekSoni That seems to be a new question. – reducing activity Jul 03 '18 at 16:26
  • 2
    Does this command (git log --follow -- filename) view all commits in all branches? – Borneo777 Feb 01 '19 at 17:06
  • -- is used in several unix commands to indicate file names. Since --follow is a valid file name in unix, if you wanted to show the logs for that file and types `git log --follow` it would be interpreted as the --follow option, not the file, so you would do: `git log -- --follow` – Danilo Souza Morães Feb 14 '19 at 17:45
  • 1
    use with `-p` to not only list but preview the followed changes. – Sławomir Lenart Apr 09 '19 at 15:29
  • 3
    the last argument is not really the filename. it should be the full path (absolute or relative) to the file. Just using the filename doesn't return anything since git can't find the file. i.e. `-- src/main/java/hello.java`, not `-- hello.java` – Hilikus Apr 29 '20 at 15:38
  • 1
    Agreed with @Hilikus. For example, if you want to search for `hello.java` changes anywhere in the tree, you may use `-- **/hello.java`. Git documentation seems to be utterly underdocumented on this. – Petr Bodnár Oct 16 '20 at 08:49
  • I like your answer better because `--oneline` works whereas `-p` doesn't work for that flag. – destroyer22719 Jul 27 '21 at 13:49
  • For posterity: In my version of git (`2.33.0.windows.2.7.g2aa9e28d2a.20210908104152`) I have to **not** use the double-dash before the file path, even when looking for a file and not a directory. – Niko O Oct 12 '21 at 07:51
  • @NikoO: In my version (2.34.1), using that double-dash seems totally optional, but works well if typed. – Olivier Feb 22 '22 at 08:29
  • For me, `git log --follow -- filename` didn't work because the file was subsequently renamed and I was searching with the old name, but `git log --all -- filename` and `git log --all --first-parent --remotes --reflog --author-date-order -- filename` worked with the former being much faster. – haridsv Aug 09 '22 at 14:28
  • What's the `--`? – John Oct 09 '22 at 09:21
  • @jackrabb1t `git log --follow -- ` ***also*** works for folder. Say `git log --follow -- /path/to/folder` – John Oct 09 '22 at 09:29
150

I have been looking at this closely and all these answers don‘t seem to really show me all the commits across all the branches.

Here is what I have come up with by messing around with the gitk edit view options. This shows me all the commits for a file regardless of branch, local, reflog, and remote.

gitk --all --first-parent --remotes --reflog --author-date-order -- filename

It also works with git log:

git log --all --first-parent --remotes --reflog --author-date-order -- filename
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
BigMiner
  • 1,922
  • 1
  • 12
  • 10
  • 18
    This is perfect for when someone makes changes but they forget where they commited the changes. – earthmeLon Feb 23 '16 at 17:49
  • 4
    Very useful. Includes also stash commits – Juan Antonio Tubío May 10 '17 at 14:05
  • 1
    This should be the prefered answer. The question was to find all commits, this one does. – carl verbiest Jul 02 '19 at 08:02
  • 2
    Notice that `--reflog` includes commits which were rebased/amended or otherwise discarded. Maybe that should be obvious, but I tried to use this with `git log` and was trying to figure out why I was seeing seemingly duplicated commits! – Soren Bjornstad Jul 09 '19 at 14:48
  • I don't get it..the accepted answer by @gabe-moothart shows all parent commits of the commit that creates a file on my test tree - ie commits that don't modify the file. This answer works perfectly on my test repo though. – Ewan Jan 18 '21 at 17:30
  • However, this only shows the changes for this file in each commit, how to let gitk show all changes (including this file and other files that co-changes)? – K. Symbol Apr 18 '21 at 03:44
  • this is a life-saver (should I say "file-saver")) when branch was forcefully rewritten – mz0 Sep 27 '21 at 14:26
128

git log path should do what you want. From the git log man page:

[--] <path>…

Show only commits that affect any of the specified paths. To prevent confusion with
options and branch names, paths may need to be prefixed with "-- " to separate them
from options or refnames.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gabe Moothart
  • 31,211
  • 14
  • 77
  • 99
51

Use the command below to get commits for a specific file:

git log -p filename
Community
  • 1
  • 1
Sankar Subburaj
  • 4,992
  • 12
  • 48
  • 79
  • 9
    I understand that this doesn't exactly answer the question since he wanted a list of commits but this is gold and going in my file. – zkent Jan 07 '16 at 16:04
  • 3
    This won't work at all if the file doesn't exist in the currently checked-out branch. You can add the branch like `git log -p mybranch -- filename` or just use `git log --all -- filename` to look in all branches. – Soren Bjornstad Jul 09 '19 at 14:51
  • 1
    for some reason the `log --follow` solutions above were giving me false information (more commits than there should have been). This solution `git log -p filename` gave the correct information. – chillpenguin Aug 23 '22 at 17:04
42

It should be as simple as git log <somepath>; check the manpage (git-log(1)).

Personally I like to use git log --stat <path> so I can see the impact of each commit on the file.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rfunduk
  • 30,053
  • 5
  • 59
  • 54
  • 12
    Or even `-p` if you want to see the full diff, not just that it had some number of lines modified. – Cascabel Sep 13 '10 at 15:02
  • True, but that's pretty noisy considering most files have been changed many times over their lives. I don't want to see full diffs of every single commit that ever touched a file. I'm usually looking for a specific thing, so I can get a log with just impacts and then `git show` on the specific commits that look like they matter. – rfunduk Sep 13 '10 at 16:39
  • git log --stat --follow -- *.html => output list of commits with exactly one files in each commit. Very nice! – Sergio Belevskij Feb 07 '19 at 09:22
26

Alternatively (since Git 1.8.4), it is also possible to just get all the commits which has changed a specific part of a file. You can get this by passing the starting line and the ending line number.

The result returned would be the list of commits that modified this particular part. The command goes like:

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

More Info - https://www.techpurohit.in/list-some-useful-git-commands

jitendrapurohit
  • 9,435
  • 2
  • 28
  • 39
  • The link is broken: [HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol): *"techpurohit.com has expired and is parked free"*. [HTTPS](https://en.wikipedia.org/wiki/HTTPS): *"An error occurred during a connection to www.techpurohit.com. PR_END_OF_FILE_ERROR"* – Peter Mortensen Apr 12 '21 at 12:26
19

As jackrabb1t pointed out, --follow is more robust since it continues listing the history beyond renames/moves. So, if you are looking for a file that is not currently in the same path or a file that has been renamed throughout various commits, --follow will track it.

This can be a better option if you want to visualize the name/path changes:

git log --follow --name-status -- <path>

But if you want a more compact list with only what matters:

git log --follow --name-status --format='%H' -- <path>

or even

git log --follow --name-only --format='%H' -- <path>

The downside is that --follow only works for a single file.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Roberto
  • 11,557
  • 16
  • 54
  • 68
  • 4
    `--follow` works for a single _path_, which could be a directory. If passed a directory it will run recursively and report changes to all files below that point. – StvnW Nov 22 '14 at 16:25
17

To get all commits for a specific file use:

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"

See gif imagegit commits for specific files

Eng_Farghly
  • 1,987
  • 1
  • 23
  • 34
14

If you want to look for all commits by filename and not by filepath, use:

git log --all -- '*.wmv'
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
WonderLand
  • 5,494
  • 7
  • 57
  • 76
14

If you wish to see all changes made in commits that changed a particular file (rather than just the changes to the file itself), you can pass --full-diff:

git log -p --full-diff [branch] -- <path>
Cubic
  • 14,902
  • 5
  • 47
  • 92
11

If you are trying to --follow a file deleted in a previous commit, use

git log --follow -- filename
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
snovelli
  • 5,804
  • 2
  • 37
  • 50
  • 3
    For `git` newbies: Use `git log -p --follow -- filename` to display the changes as well. Also note: "filename" can be a file, a directory or a submodule. – Tino May 30 '16 at 13:53
9

If you want to view all the commits that changed a file, in all the branches, use this:

git log --follow --all <filepath>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Always_Beginner
  • 2,546
  • 6
  • 25
  • 33
8

Use git log --all <filename> to view the commits influencing <filename> in all branches.

Palec
  • 12,743
  • 8
  • 69
  • 138
Lebnik
  • 628
  • 8
  • 11
4
gitk <path_to_filename>

Assuming the package "gitk" is already installed.

If it is not installed, do this:

sudo apt-get install gitk

And then try the above command. It is for Linux... It might help Linux users if they want a GUI.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Breen ho
  • 1,601
  • 14
  • 23
4

To just get a list of the commit hashes, use git rev-list:

 git rev-list HEAD <filename>

Output:

b7c4f0d7ebc3e4c61155c76b5ebc940e697600b1
e3920ac6c08a4502d1c27cea157750bd978b6443
ea62422870ea51ef21d1629420c6441927b0d3ea
4b1eb462b74c309053909ab83451e42a7239c0db
4df2b0b581e55f3d41381f035c0c2c9bd31ee98d

Which means five commits have touched this file. It's in reverse chronological order, so the first commit in the list b7c4f0d7 is the most recent one.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
1

On Linux you can use gitk for this.

It can be installed using "sudo apt-get install git-gui gitk". It can be used to see commits of a specific file by "gitk <Filename>".

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chamila Wijayarathna
  • 1,815
  • 5
  • 30
  • 54
1
# Shows commit history with patch
git log -p -<no_of_commits> --follow <file_name>

# Shows brief details like "1 file changed, 6 insertions(+), 1 deletion(-)"
git log --stat --follow <file_name>

Reference

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
AnshBikram
  • 2,028
  • 13
  • 8