180

Possible Duplicate:
View the change history of a file using Git versioning

Sometimes I want to step through the history of a particular file. In the past I used P4V and this was very quick and intuitive.

  1. Right click on a file and select history.
  2. Scrolling through the dates and see a nice diff of exactly what changed in that file on that date. Simple.

Switching to git this is now a grueling task.

  1. "git log filename"
  2. Look at history and pick a date, copy hash
  3. "git diff hash"
  4. Scroll through diff for the stuff that changed in the file I am interested in.
  5. Nope, that's not it, lets try a different date - back to step 2, rinse and repeat.

I've searched SO, and I've tried a few of the commonly suggested guis: github, gitk, gitg, git-gui.

These all remove the need to manually run commands, but the workflow is the same for this. View history of file; view commit; search through diff of lots of irrelevant files. It's slow and repetitive.

All the data is in the repo so I see no reason this simple common use case could not be more streamlined.

Can anyone recommend a tool that does this - or a more efficient way to utilize the command line to do what I want?

Thanks for any suggestions.

codeforester
  • 39,467
  • 16
  • 112
  • 140
Chris
  • 6,076
  • 11
  • 48
  • 62
  • 2
    I dont know if you want this but does `git diff --stat` or `git diff filename` help for your cause? – uday Mar 21 '12 at 15:22

4 Answers4

218

You can use git log to display the diffs while searching:

git log -p -- path/to/file
rtn
  • 127,556
  • 20
  • 111
  • 121
  • 1
    I like this - much better. Only thing that would be better is a gui to present the diff in a more friendly way... – Chris Mar 21 '12 at 15:20
  • 4
    after a while you will love console diffs, just enable colors – the.malkolm Mar 21 '12 at 16:38
  • 4
    I agree. git --config --global color.ui true – rtn Mar 21 '12 at 16:43
  • 3
    you can also pipe the diff into a text editor like Sublime for better colors, search functionality and an overall better ease-of-work experience: `git log -p -- path/to/file | subl` – Rocco Aug 01 '16 at 13:49
  • To make the output more readable, you can wrap long lines by typing `-S` and then Return. Works if your git uses the default Linux pager "less". ([source](http://stackoverflow.com/a/3107807)) – tanius Dec 28 '16 at 15:58
  • 7
    Enabling colors is definitely helpful. The command however appears to be `git config --global color.ui true` (without the double dash before config). At least that is what worked for me using git version 1.9.1 – Norman Breau Aug 16 '17 at 14:37
  • This is very useful! Why is `-p` only referred to tangentially in the doc??? https://git-scm.com/docs/git-log – Jerry101 Aug 09 '19 at 23:30
156

Have you tried this:

gitk path/to/file
Pierre Mage
  • 2,250
  • 1
  • 15
  • 20
55

git log -p will generate the a patch (the diff) for every commit selected. For a single file, use git log --follow -p $file.

If you're looking for a particular change, use git bisect to find the change in log(n) views by splitting the number of commits in half until you find where what you're looking for changed.

Also consider looking back in history using git blame to follow changes to the line in question if you know what that is. This command shows the most recent revision to affect a certain line. You may have to go back a few versions to find the first change where something was introduced if somebody has tweaked it over time, but that could give you a good start.

Finally, gitk as a GUI does show me the patch immediately for any commit I click on.

Example enter image description here:

Jeff Ferland
  • 17,832
  • 7
  • 46
  • 76
  • Good information, thanks. However as for the gui - this suffers the problem I was describing - yes it shows the diff for a commit / file. But not for all the diffs on a file. Looks like I'm stuck with the command line! – Chris Mar 21 '12 at 15:37
  • @Chris click on a different revision in the top-left window and you'll see the corresponding diff in the bottom-left window. If you're talking about something else, can you elaborate? – Jeff Ferland Mar 21 '12 at 15:50
  • That, combined with gitk path/to/file , does the trick! – Chris Mar 21 '12 at 16:02
  • 1
    @Chris Go to the `View -> Edit view...` menu and you'll find a very powerful filtering criteria that will give you great flexibility in narrowing down your search besides listing the path on the command line (you can here as well, and don't need to relaunch instances). – Jeff Ferland Mar 21 '12 at 16:21
11

The main question for me would be, what are you actually trying to find out? Are you trying to find out, when a certain set of changes was introduced in that file?

You can use git blame for this, it will anotate each line with a SHA1 and a date when it was changed. git blame can also tell you when a certain line was deleted or where it was moved if you are interested in that.

If you are trying to find out, when a certain bug was introduced, git bisect is a very powerfull tool. git bisect will do a binary search on your history. You can use git bisect start to start bisecting, then git bisect bad to mark a commit where the bug is present and git bisect good to mark a commit which does not have the bug. git will checkout a commit between the two and ask you if it is good or bad. You can usually find the faulty commit within a few steps.

Since I have used git, I hardly ever found the need to manually look through patch histories to find something, since most often git offers me a way to actually look for the information I need.

If you try to think less of how to do a certain workflow, but more in what information you need, you will probably many workflows which (in my opinion) are much more simple and faster.

LiKao
  • 10,408
  • 6
  • 53
  • 91
  • I think you are right, as an ex perforce user I'm just used to getting a feel for what's changing in a file by clicking through the history. I know tools like git blame are faster for seeing who last touched a particular line - (something that was grueling to find with perforce). But for just a casual browse of the history of a file - git is a bit more tedious. – Chris Mar 21 '12 at 15:49
  • @Chris: Yes, this has to do a lot with the design behind git. At the basic level, git has not such concept as "a file history". This is often stated by "git does not manage files, it manages content". For git your whole work-tree is the content, and the history is the history of this complete directory. This is quite different from other SCMs, who attach a history to individual files. – LiKao Mar 21 '12 at 15:51
  • 1
    I understand, but hey old habbits die hard :) – Chris Mar 21 '12 at 15:58