296

I've had a look at all similar questions. However, I've double checked and something strange is definitely happening.

On one server (Solaris with Git 1.8.1) I cloned the Git repository then copied the .git folder into my existing live files. This worked perfectly, I could run

git status

then

git diff [filename]

to check any files that were different.

On another server (Solaris with Git 1.7.6) I'm doing exactly the same however

git diff [filename]

shows nothing, even if the contents of the file is definitely different. I have also tested adding a new file, committing it, and then editing. The same issue, git status shows the file as changed, but git diff shows nothing. If I download the changed file and run a diff locally then I get diff output.

5
  • 18
    Is it in your index? If so, you can view the diff with git diff --cached. Commented Jan 28, 2013 at 15:17
  • 4
    git diff --cached just gives me blank output as well.
    – Oliver P
    Commented Jan 28, 2013 at 16:39
  • git log also gives no output.
    – Oliver P
    Commented Jan 28, 2013 at 17:02
  • Assuming that there is really a bug, you should be able to create a minimal example. Try to reproduce it and share the sample. Commented Feb 19, 2013 at 9:39
  • 1) File mode was changed? Look for core.fileMode option here 2) Also, I'm facing similar issue with Console2 config (I have it under git) when Console2 is actually running. Maybe kinda of a file lock makes git to thing the file has changed.
    – madhead
    Commented Feb 23, 2013 at 23:08

19 Answers 19

159

For me, it had something to do with file permissions. Someone with Mac/Linux on my project seems to commit some files with non-default permissions which my Windows Git client failed to reproduce.

The solution for me was to tell Git to ignore file permissions:

git config core.fileMode false

Other insight: How do I make Git ignore file mode (chmod) changes?

5
  • 2
    This solved an issue I was having with a bunch of files, though I think it was with the file created/modified time instead.
    – Derek
    Commented Mar 8, 2016 at 19:25
  • This solved it for me. The fileMode value appears to default to true on Mac/Linux volumes and false on Windows volumes. I moved a project from Mac to Windows and it needed to be switched to false.
    – geekinit
    Commented Jan 30, 2020 at 19:50
  • 2
    This also helped if you're running VSCode using a Docker container which mounts your directory on Windows 10. On the outside of the container, checking the git status, correctly shows that you have not changed any files. But if you check git status inside the container, it shows the files are changed. Running the above command inside the container fixed my issue. Commented May 19, 2020 at 17:12
  • This worked for me! Thank you!
    – ann.piv
    Commented Nov 23, 2021 at 23:46
  • This worked for me when i use WSL too, thanks
    – Rim
    Commented Oct 14, 2022 at 5:05
115

I added the file to the index:

git add file_name

And then ran:

git diff --cached file_name

You can see the description of git diff here.

If you need to undo your git add, then please see here: How do I undo 'git add' before commit?

2
  • 1
    maybe git diff remember previous content even you have modified this file and git add will refresh it.
    – netawater
    Commented Feb 9, 2021 at 13:21
  • this worked for me, but I'm still not clear what --cached does from reading that doc
    – otocan
    Commented Mar 2, 2023 at 9:13
78

There are a few reasons why git status might show a difference but git diff might not.

  • The mode (permission bits) of the file changed-- for example, from 777 to 700.

  • The line feed style changed from CRLF (DOS) to LF (UNIX)

The easiest way to find out what happened is to run git format-patch HEAD^ and see what the generated patch says.

7
  • 14
    if changes permission files apply: git config core.filemode false for ignore permission of files
    – jruzafa
    Commented Oct 8, 2015 at 21:15
  • How did you find out that the line feed change from CRLF to LF is one of the situations where git status will show a difference and git diff will not? Commented Jun 12, 2018 at 14:00
  • 1
    Having co-workers who use Windows will help you find out all kinds of fun things about line endings. I think might be cases where "git diff" does show the change from CRLF to LF, though-- it probably depend on your configuration. I haven't worked with Windows in a while, so I don't know what the defaults are like now.
    – cmccabe
    Commented Jun 13, 2018 at 15:35
  • If line ending style has changed, use dos2unix utility to change them. Then add all files git add -A. Line ending changes will all vanish. Commented Jul 31, 2020 at 11:03
  • @NagabhushanSN I use a repo where I pull from but do not want to push. I do not want to create commits, neither git add -A add to the index. I use both windows and linux and have the crlf problem. But know how to fix it now. So dos2unix is no option.. Wait, jaakko`s answer.
    – Timo
    Commented May 17, 2021 at 18:01
61

I had an issue where hundreds of line endings were modified by some program and git diff listed all source files as changed. After fixing the line endings, git status still listed the files as modified.

I was able to fix this problem by adding all files to the index and then resetting the index.

git add -A
git reset

core.filemode was set to false.

2
  • 6
    I solved with git add --renormalize ., see my answer below.
    – Stefano M
    Commented Jul 15, 2019 at 14:02
  • I add git restore ..to not pollute the index.
    – Timo
    Commented May 17, 2021 at 18:15
54

As already noted in a previous answer, this situation may arise due to line-ending problems (CR/LF vs. LF). I solved this problem (under Git version 2.22.0) with this command:

git add --renormalize .

According to the manual:

       --renormalize
           Apply the "clean" process freshly to all tracked files to
           forcibly add them again to the index. This is useful after
           changing core.autocrlf configuration or the text attribute in
           order to correct files added with wrong CRLF/LF line endings.
           This option implies -u.
5
  • No reset needed think.
    – Timo
    Commented May 17, 2021 at 18:10
  • @Timo yes, this commands should work without the need of a git reset afterwards.
    – Stefano M
    Commented May 30, 2021 at 17:11
  • 1
    Thank you!! I did git config --global core.autocrlf true and then ran this and it was solved.
    – Gavin Ray
    Commented Jul 5, 2021 at 18:34
  • 2
    The line ending problems are just one example; other git filters that perform automatic changes when the files are committed (clean operation) and/or extracted (smudge operation) could also be the culprit; check the filter section in your git config files.
    – Ansa211
    Commented Aug 13, 2021 at 11:52
  • @GavinRay 's solution worked for me Commented May 4 at 22:23
22
+50

I suspect there is something wrong either with your Git installation or your repository.

Try running:

GIT_TRACE=2 git <command>

See if you get anything useful. If that doesn't help, just use strace and see what's going wrong:

strace git <command>
3
  • 6
    @towi: Since this was worth a bounty to you, I'd be interested in seeing what you've learned about the reason for your similar failures.
    – cfi
    Commented Feb 25, 2013 at 13:29
  • 5
    In my case, I added the -F flag to the LESS env variable which tells less to exit if there is less than one screen full of information to show. Since git uses less as a pager, and I had a small diff, nothing was being shown. Either I had to add -X to the LESS env which shows the content on the screen even after less exits or just remove -F. GIT_TRACE showed that less was being executed which reminded me that I changed the LESS variable recently. Same reason in @rcwxok's answer, but wanted on comment on how GIT_TRACE helped.
    – sudocracy
    Commented Sep 28, 2016 at 21:01
  • This answer provides me hint of "pager" and leads me to the solution of setting core.pager in .gitconfig, which works perfectly for me.
    – ytu
    Commented Mar 14, 2018 at 3:02
10

I had a similar problem: git diff would show differences, but git diff <filename> would not. It turned out that I set LESS to a string including -F (--quit-if-one-screen). Removing that flag solved the problem.

2
  • 1
    Instead of removing -F, adding -X might also work, see my answer below for a similar case.
    – avivr
    Commented Nov 6, 2016 at 10:45
  • Thank you for this! Was driving me crazy.
    – hackel
    Commented Jun 19, 2017 at 22:26
10

Short Answer

Running git add sometimes helps.

Example

Git status is showing changed files and git diff is showing nothing...

> git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   package.json

no changes added to commit (use "git add" and/or "git commit -a")
> git diff
> 

...running git add resolves the inconsistency.

> git add
> git status
On branch master
nothing to commit, working directory clean
> 
7
  • 5
    This sounds to me like 'fighting the symptoms' instead of 'curing the illness'... ;)
    – einjohn
    Commented May 17, 2016 at 9:28
  • @einjohn What do you think is the illness in this case? Commented May 18, 2016 at 3:26
  • 1
    The illness could be several things. As mentioned by others, it could be a permissions problem or something with the line endings. It could also be already staged changes. However, this last possibility does not fit your example. Nevertheless, with your solution you will not know the reason (illness), you just eliminate the problem (of a seemingly faulty empty diff (symptoms)). To be clear: I'm not saying that it is a bad solution. It might help someone, if he/she just want the problem to disappear. ...hopefully I've shed some light on my illness-metapher. :)
    – einjohn
    Commented May 18, 2016 at 11:14
  • @einjohn It seems to be line endings most of the time. It seems status and diff have separate ways of handling those. Commented May 18, 2016 at 14:06
  • 1
    I had the issue today - checked file permissions and line endings, all normal. I tried running git add, and nothing was added, but git status got cleared. Commented Jul 22, 2021 at 8:04
9

TL;DR

Line ending issue:

  1. Change autocrlf setting to default true. I.e., checkout Windows-style line endings on Windows and commit Linux-style line endings on remote Git repository:
    git config --global core.autocrlf true
    
  2. On a Windows machine, change all files in the repository to Windows-style:
    unix2dos **
    
  3. Git add all modified files and modified files will go:
    git add .
    git status
    

Background

  • Platform: Windows, WSL

I occasionally run into this issue that git status shows I have files modified while git diff shows nothing. This is most likely an issue of line endings.

Root Cause

The reason I encounter this issue often is that I work on a Windows machine and interact with Git in WSL. Switching between Linux and Windows setting can easily cause this end-of-line issue. Since the line ending format used in the OS differs:

  • Windows: \r\n
  • OS X / Linux: \n

Common Practice

When you install Git on your machine, it will ask you to choose line endings setting. Usually, the common practice is to use (commit) Linux-style line endings on your remote Git repository and check out Windows-style on your Windows machine. If you use default setting, this is what Git do for you.

Enter image description here

This means if you have a shell script myScript.sh and Bash script myScript.cmd in your repository, the scripts both exist with Linux-style ending in your remote Git repository, and both exist with Windows-style ending on your Windows machine.

I used to check out shell script file and use dos2unix to change the script line-ending in order to run the shell script in WSL. This is why I encounter the issue. Git keeps telling me my modification of line-ending has been changed and asks whether to commit the changes.

Solution

Use the default line ending settings and if you change the line endings of some files (like use the dos2unix or dos2unix), drop the changings. If line-endings changes already exist and you would like to get rid of it, try git add them and the changes will go.

6

I ran into this problem. My case was similar to the LESS issue posted by rcwxok.

In my case, I set the PAGER environment variable to PAGER='less -RSF'.

However, unlike the previous answers, I didn't want to remove the -F option, because I explicitly put it there hoping to prevent showing the diff in less if it's shorter than a screenful.

To get the desired result, instead of removing -F, I added -X: PAGER='less -RSFX'. This both solved the git diff issue and in addition it prevents showing short diffs with less.

2
  • Capitalization seems weird. Do you mean "less -RSFX" instead of "LESS -RSFX"? Are the options the correct case? Commented Jul 13, 2017 at 6:57
  • 1
    Yes, thanks, it was a mistake. Not sure how it happened. Now fixed.
    – avivr
    Commented Jul 14, 2017 at 10:38
3

I've just run in a similar issue. git diff file showed nothing because I added file to the Git index with some part of its name in uppercase: GeoJSONContainer.js.

Afterwards, I've renamed it to GeoJsonContainer.js and changes stopped being tracked. git diff GeoJsonContainer.js was showing nothing. I had to remove the file from the index with a force flag, and add the file again:

git rm -f GeoJSONContainer.js
git add GeoJSONContainer.js
3

Many of the other answers refer to differences in line endings and the core.autocrlf setting. This can definitely be the case, but I want to call out another similar issue: git filters.

If core.autocrlf=true then the behavior is like a git smudge or clean filter, which automatically processes text as it moves between the working tree and the index.

Similarly, if you've changed your git filter settings since the file was last committed, it may cause the elusive difference in git status that doesn't show up in git diff. That elusive difference can still remain even after git add X; git diff --cached -- X, depending on the nature of the filters configured.

This problem happened to me when using nbstripout, a python package that implements git filters that filter out metadata before adding Jupyter notebook files to the index and before diffing them. I resolved it by reverting the filter config settings to how they were before, running git restore on the affected files, and then re-applying the changes to my filter config (because I wanted to keep the new settings long-term). For me, the settings were stored in .git/config under the filter.nbstripout and diff.ipynb sections.

2

My assumption on your use case:

You have an existing directory containing files and directories and now want to convert it into a Git repository that is cloned from some place else without changing any data in your current directory.

There are really two ways.

Clone repo - mv .git - git reset --hard

This method is what you did - to clone the existing repository into an empty directory, then move the .git directory into the destination directory. To work without problems, this generally requires you then to run

git reset --hard

However, that would change the state of files in your current directory. You can try this on a full copy/rsync of your directory and study what changes. At least afterwards you should no longer see discrepancies between git log and status.

Init new repository - point to origin

The second is less disturbing: cd into your destination, and start a new repository with

git init

Then you tell that new repository, that it has an ancestor some place else:

git remote add origin original_git_repo_path

Then safely

git fetch origin master

to copy over the data without changing your local files. Everything should be fine now.

I always recommend the second way for being less error-prone.

4
  • You seem to imply that this is a git error. Ok, could be. I still assumed I lacked proper git understanding, because I am not as smart as Linus ;-)
    – towi
    Commented Feb 20, 2013 at 13:49
  • @towi: No, I'm not implying that this is a git error, nor am I implying the opposite. I'm not familiar with the git internals. But as a general rule of thumb, by moving around .git folders into other working areas, we're potentially violating assumptions of git. If this results in erratic behaviour we cannot blame git, we have to blame ourselves for playing tricks with git. git provides means to fix that, e.g. the reset --hard. It's just that that's not what we want. This is exactly the reason why the init/remote add way is recommended, and all is well.
    – cfi
    Commented Feb 20, 2013 at 15:01
  • @towi and Oliver P: While I understand you'd like your particular case of error be solved, sometimes it's just advised to go with the general recommendations - especially if they fit your use case perfectly. There's also no data loss. And the remote add way of doing things can still be applied to a messed up situation like the one described by Oliver P
    – cfi
    Commented Feb 20, 2013 at 15:04
  • 1
    A downvote without a comment does not help to improve this answer, nor the site as a whole. Whoever downvotes, please leave a comment so the issue can be resolved.
    – cfi
    Commented Jun 28, 2013 at 9:17
1

I had this same problem described in the following way: If I typed

$ git diff

Git simply returned to the prompt with no error.

If I typed

$ git diff <filename>

Git simply returned to the prompt with no error.

Finally, by reading around I noticed that git diff actually calls the mingw64\bin\diff.exe to do the work.

Here's the deal. I'm running Windows and had installed another Bash utility and it changed my path so it no longer pointed to my mingw64\bin directory.

So if you type:

git diff

and it just returns to the prompt you may have this problem.

The actual diff.exe which is run by git is located in your mingw64\bin directory

Finally, to fix this, I actually copied my mingw64\bin directory to the location Git was looking for it in. I tried it and it still didn't work.

Then, I closed my Git Bash window and opened it again went to my same repository that was failing and now it works.

1

git diff -a treats all file as text and it works for me.

1

I stumbled upon this problem again. But this time it occurred for a different reason. I had copied files into the repository to overwrite the previous versions. Now I can see the files are modified, but diff doesn't return the diffs.

For example, I have a mainpage.xaml file. In File Explorer I pasted a new mainpage.xaml file over the one in my current repository. I did the work on another machine and just pasted the file here.

Git shows modified

The file shows modified, but when I run git diff, it will not show the changes.

It's probably because the fileinfo on the file has changed and Git knows that it isn't really the same file. Interesting.

Git diff shows nothing

You can see that when I run diff on the file it shows nothing, just returns the prompt.

0

I used git svn, and had this problem for one file. Using ls-tree for each ancestor of the file, I noticed that one had 2 subfolders - Submit and submit. Since I was on Windows, they couldn't both be checked out, causing this issue.

The solution was to delete one of them directly from TortoiseSVN Repo-browser, then to run git svn fetch followed by git reset --hard origin/trunk.

0

I recently switched from Windows to Linux and kept my working git repo not touched. When I run git diff, it says every file every line is changed; when I run git diff --cached, it shows no file changed.

git restore . solved the problem for me.

0

In case it is not about a file modes (permissions) or a line ending styles. I Got the same behaviour (as author mentioned) in some repos after migration from azure devops to github. Branches were just out of sync. For all examples below I will use generic develop branch name for the branch which showed this effect.

The git diff showed nothing as a diff, while git diff --cached showed some older commits as a diff for files.

I tried different things but most obvious and straightforward in this case was the next set of steps:

Checkout locally to the new branch but do it from remote (origin) as accepted source of truth, not the local copy of the files (in this case branch name is develop):

standing at any branch: git checkout -b "develop-from-remote" origin/develop

and then you push your new branch to the remote:

push -u origin develop-from-remote

and compare branches for PR in UI and see is that your case or not (do a PR/MR from this branch if required for the sync).

You also can accomplish same way locally with merging remote (origin) develop into your new branch which checked out from local develop:

standing at 'develop' or any desired branch you want to fix/sync with origin (develop):

git checkout -b "new-dev-to-dev"
git pull origin develop
git merge origin develop
git status
git push -u origin new-dev-to-dev

Not the answer you're looking for? Browse other questions tagged or ask your own question.