204

git diff actually runs a diff on all source code. How do I do this on a certain directory, so that I can view modifications on files underneath it?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
priya
  • 24,861
  • 26
  • 62
  • 81
  • 11
    http://stackoverflow.com/a/12123669/1815624 `git diff master..yourbranch path/to/folder` – CrandellWS May 13 '17 at 12:20
  • 1
    @CrandellWS Ugh, I hate the duplicate system. That excellent link is to a very succinct answer for this question, but that question is marked a dupe. We either need some way to merge questions into one (better) or we need a "dupes now pointing to this question" section for questions like this one (worse). Though ime suggesting that on meta invites only . – ruffin Feb 08 '23 at 15:00

10 Answers10

182

Provide a path (myfolder in this case) and just run:

git diff myfolder/
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Geo
  • 93,257
  • 117
  • 344
  • 520
  • 43
    I'd like to use `git diff -- myfolder` to minimize ambiguity to git. The general notation for git diff (and many git commands) is `git diff [commit-ish] -- [path]` where commit-ish defaults to HEAD (where you are at now) and `[path]` defaults to the git root directory, but can be anything relative to your current directory. Without the `--`, git will guess what you mean, `[commit-ish]` or `[path]`. In some cases, this causes git to say the notation is 'ambiguous'. If I remember correctly. – L0LN1NJ4 Aug 12 '14 at 13:00
  • 4
    This prints nothing when I try the method in the answer and the method in the comment. – ray Jun 06 '17 at 14:55
  • @ray which means you have no differences between working tree and latest commit – valerij vasilcenko Jan 29 '18 at 14:08
  • 7
    For @ray and future individuals seeing this you can include the branches you are trying to diff between `git diff master..develop myfolder/` as @CrandellWS said in the comment on the original question. Git status will show you changes if that's what you're looking for. – BVBAccelerate Jun 13 '18 at 13:57
  • 4
    @ray make sure you are at the root directory. The path will be relative to your current directory. – Nickofthyme Oct 19 '18 at 15:29
  • What does it mean when `git status` shows changes, but `git diff` shows no difference? (Presumably the directory isn't tracked?) – jvriesem Mar 18 '19 at 21:44
  • @jvriesem `git diff` doesn’t show new (untracked) files. – Franklin Yu May 01 '19 at 14:04
  • 1
    what if the folder name with space? – sky Jun 17 '21 at 08:36
82

If you're comparing different branches, you need to use -- to separate a Git revision from a filesystem path. For example, with two local branches, master and bryan-working:

$ git diff master -- AFolderOfCode/ bryan-working -- AFolderOfCode/

Or from a local branch to a remote:

$ git diff master -- AFolderOfCode/ origin/master -- AFolderOfCode/
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
bcattle
  • 12,115
  • 6
  • 62
  • 82
  • 42
    Only one -- clause is needed after listing both branches, as in: git diff branch1 branch2 -- path/to/dir – emery Jan 13 '16 at 21:18
30

What I was looking for was this:

git diff <ref1>..<ref2> <dirname>
Amin Karbas
  • 562
  • 1
  • 7
  • 16
16

Not only you can add a path, but you can add git diff --relative to get result relative to that folder.

git -C a/folder diff --relative

And with Git 2.28 (Q3 2020), the commands in the "diff" family learned to honor the "diff.relative" configuration variable.

See commit c28ded8 (22 May 2020) by Laurent Arnoud (spk).
(Merged by Junio C Hamano -- gitster -- in commit e34df9a, 02 Jun 2020)

diff: add config option relative

Signed-off-by: Laurent Arnoud
Acked-by: Đoàn Trần Công Danh

The diff.relative boolean option set to true shows only changes in the current directory/value specified by the path argument of the relative option and shows pathnames relative to the aforementioned directory.

Teach --no-relative to override earlier --relative

Add for git-format-patch(1) options documentation --relative and --no-relative

The documentation now includes:

diff.relative:

If set to 'true', 'git diff' does not show changes outside of the directory and show pathnames relative to the current directory.


Warning: Before Git 2.34 (Q4 2021), "git diff --relative"(man) segfaulted and/or produced incorrect result when there are unmerged paths.

See commit 8174627 (22 Aug 2021) by Đoàn Trần Công Danh (sgn).
(Merged by Junio C Hamano -- gitster -- in commit c8f4916, 08 Sep 2021)

diff-lib: ignore paths that are outside $cwd if --relative asked

Reported-by: Thomas De Zeeuw
Tested-by: Carlo Arenas
Signed-off-by: Đoàn Trần Công Danh

For diff family commands, we can tell them to exclude changes outside of some directories if --relative is requested.

In diff_unmerge(), NULL will be returned if the requested path is outside of the interesting directories, thus we'll run into NULL pointer dereference in run_diff_files when trying to dereference its return value.

Checking for return value of diff_unmerge before dereferencing is not sufficient, though.
Since, diff engine will try to work on such pathspec later.

Let's not run diff on those unintesting entries, instead.
As a side effect, by skipping like that, we can save some CPU cycles.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
3

Add Beyond Compare as your difftool in Git and add an alias for diffdir as:

git config --global alias.diffdir = "difftool --dir-diff --tool=bc3 --no-prompt"

Get the gitdiff as:

git diffdir 4bc7ba80edf6  7f566710c7

Reference: Compare entire directories w git difftool + Beyond Compare

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Barani
  • 47
  • 2
  • 1
    The equal sign seems to be wrong for git 2.17.1. Use `git config --global alias.diffdir = "difftool --dir-diff --tool=bc3 --no-prompt"` instead – Mark Schäfer Nov 01 '18 at 08:22
  • Note that when using Beyond Compare for dir diff, you need to either configure it to follow symlinks (In a Folder Compare View -> Rules (referee icon) -> Handling -> follow symlinks) OR, add the `--no-symlinks` option so that the command reads `git difftool --dir-diff --no-symlinks` – Ashutosh Jindal Sep 25 '19 at 10:20
2

If you want to exclude the sub-directories, you can use

git diff <ref1>..<ref2> -- $(git diff <ref1>..<ref2> --name-only | grep -v /)
2

You should make a habit of looking at the documentation for stuff like this. It's very useful and will improve your skills very quickly. Here's the relevant bit when you do git help diff

   git diff [options] [--no-index] [--] <path> <path>

The two <path>s are what you need to change to the directories in question.

Noufal Ibrahim
  • 71,383
  • 13
  • 135
  • 169
  • 3
    Well, maybe people (like me) are here because they tried reading the documentation but it didn't helped them. On my case changing those ``s make things worse: without it at least it returns the diff of all files changed between commits but if I change those it returns nothing. – Gustavo Rodrigues Sep 09 '20 at 11:12
1

To use Beyond Compare as the difftool for directory diff, remember enable follow symbolic links like so:

In a Folder Compare ViewRules (Referee Icon):

Enter image description here

And then, enable follow symbolic links and update session defaults:

Enter image description here


OR,

set up the alias like so:

git config --global alias.diffdir "difftool --dir-diff --tool=bc3 --no-prompt --no-symlinks"

Note that in either case, any edits made to the side (left or right) that refers to the current working tree are preserved.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ashutosh Jindal
  • 18,501
  • 4
  • 62
  • 91
1

If you have a diff tool installed and configured (ex: kdiff3)

git difftool -d  branch1 branch2 /path/to/dir/
KhogaEslam
  • 2,528
  • 1
  • 20
  • 21
0

I do it like this if I compare two branches:

git diff HEAD branchX path/to/my/folder
Black
  • 18,150
  • 39
  • 158
  • 271