403

After git reset --hard, git status gives me files within the Changes not staged for commit: section.

I've also tried git reset ., git checkout -- . and git checkout-index -f -a, to no avail.

So, how can I get rid of those unstaged changes?

This seems to hit only Visual Studio project files. Weird. See this paste: http://pastebin.com/eFZwPn9Z. What is special with those files, is that in .gitattributes I have:

*.sln        eol=crlf
*.vcproj     eol=crlf
*.vcxproj*   eol=crlf

Also, autocrlf is set to false in my global .gitconfig. Could that be somehow relevant?

halfer
  • 19,824
  • 17
  • 99
  • 186
Norswap
  • 11,740
  • 12
  • 47
  • 60
  • Did you apply those commands from the root of the repository? Notice `.` stands for current directory not root directory – Alexander Jul 08 '12 at 12:24
  • 1
    I did do them from the root repository indeed. – Norswap Jul 08 '12 at 12:25
  • What is your `git` version? Either you are making a silly mistake or you have an old version that is buggy? – Shahbaz Jul 08 '12 at 12:27
  • It's git 1.7.4 msysgit. It might be a mistake, but the commands seem simple enough, and I couldn't spot a mistake. – Norswap Jul 08 '12 at 12:29
  • For the record, I tried using the latest version of msysgit (1.7.11), but the problem persists. – Norswap Jul 08 '12 at 12:38
  • Same problem, I've added `.gitattributes` on one machine (Windows) and now on another one (Linux) after the pull from the main repo some files appear modified, namely those that have `eol=crlf`... – szx Mar 13 '13 at 08:49
  • The proper fix would be using git history rewrite – Sergei Krivonos Jul 07 '20 at 22:17
  • I suddenly had this problem and it turned out I renamed the files (changing the case of the filenames). Completely confused GIT. Kept showing the files as "removed" but when I would try to stage them, it wouldn't show any files changed. The solution was to temporarily move those files out of their folders into a temp folder, which I was able to remove them from the repo, then put the files back into their proper files, and add them back in. – LarryBud May 10 '22 at 12:18

22 Answers22

457

I had the same problem and it was related to the .gitattributes file. However the file type that caused the problem was not specified in the .gitattributes.

I was able to solve the issue by simply running

git rm .gitattributes
git add -A
git reset --hard
Richard Ev
  • 52,939
  • 59
  • 191
  • 278
GameScripting
  • 16,092
  • 13
  • 59
  • 98
  • I think this could actually be a bug in git. Has anyone tried if it's present in git 1.8.4 as well? (I'm using git 1.8.3) – GameScripting Nov 19 '13 at 13:50
  • 9
    It's the * text=auto directive in the gitattributes file. It automatically changes file endings, so the files will automatically be marked as "modified" when you check the status. – Cody Django Feb 19 '15 at 22:24
  • 4
    This works, but I do not exactly understand why. Anyone care to explain each command? – Edwin Stoteler Mar 20 '15 at 14:04
  • 27
    @NLwino, `git rm .gitattributes` removes .gitattributes from the index. `git add -A` adds all (including the removal of .gitattributes) to the index, which *should* then only be the removal of .gitattributes, if that was really the problem. `git reset --hard` resets all uncommitted changes, which would include the removal of .gitattributes. Essentially, this ignores .gitattributes (and the `* text=auto` directive) for one commit by deleting it, then resetting the index while it's deleted, therefore putting it back, but after you've already reset the other files, so they weren't modified again. – cloudworks Aug 22 '15 at 07:12
  • 5
    @GameScripting, This solution doesn't work for me. There is no such file as `.gitattributes`: *"fatal: pathspec '.gitattributes' did not match any files"* – Pacerier Oct 20 '15 at 09:03
  • 2
    @pacerier So you probably have a different problem and need another solution :) – GameScripting Oct 20 '15 at 09:06
  • Did not make any new changes to the branch. Did not have any local changes. Nobody else working on the project made any changes, still somehow ended up in this state. The solution worked for me. No idea what caused it. Thanks for the help! – peewee_RotA Jun 23 '16 at 18:30
  • 5
    I do such and it says `fatal: pathspec '.gitattributes' did not match any files `. What am I doing wrong? – mfaani Oct 10 '16 at 16:33
  • 1
    Well; now I understand why someone may not like git. This is far from being "straight forward" or "obvious". I do git reset --hard (meaning that I want to force the action) but it really works only after "git rm .gitattributes"... Hmm... That is weird. Thanks for the solution anyway. It solved my issue. – AlexHalkin Dec 13 '18 at 21:09
  • Worked for me. I needed to commit the removal of the .gitattributes file before running the reset. – ianbeks Apr 20 '20 at 11:07
  • stage seem sufficient, no need to reset – Sergei Krivonos Jul 07 '20 at 22:23
  • Thanks a lot. I have been stumped by this problem for 2 hours. – Deng Xuening May 19 '21 at 14:18
  • Why `git add -A` ? This would add changes I don't want to add – Wassadamo Dec 19 '21 at 07:32
  • Why is this not the accepted answer?!? Even after fixing autocrlf and the contents of the gitattributes file, this is the only thing that worked – Jon R Jul 22 '22 at 15:15
280

I have resolved this problem using following steps

  1. Remove every file from Git's index.

    git rm --cached -r .
    
  2. Rewrite the Git index to pick up all the new line endings.

    git reset --hard
    

Solution was part of steps described on Configuring Git to handle line endings

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Jacek Szybisz
  • 5,485
  • 3
  • 10
  • 3
  • 8
    THIS WORKS when nothing else does! We've tried everything in this and many other threads -- it's a big development team so getting everyone on the same crlf has been a nightmare, but this solves the problem. – tkersh Jan 12 '17 at 01:32
  • 1
    Interesting ... I used "git rm --chached , instead of deleting everything. "git status" reported that file as deleted and untracked. Then "git reset --hard" fix that file *and* all the other files that were being reported as "Changes not staged". (Before using git rm, I hard tried reset hard to no effect). I love such mysterious source control systems. – joeking Feb 17 '17 at 20:15
  • You know, it deletes all your cache. In large projects it can waste a lot of time. – Ohar Apr 12 '17 at 22:29
  • 3
    That is brutal. You could have done the same thing by deleting the repo directory and re-cloning. – ingyhere Mar 03 '18 at 00:55
  • 5
    Consider that you are on Windows and that it is case-insensitive. If you are also working with developers who are on case-sensitive file systems, like Macs or Linux, they may be committing tags, branches or even files in different cases. In that situation your index will show files existing that are overwritten by the OS when it pulls. The only way to fix that would be to institute a naming policy on your Git server (hooks) or sniff out errors in advance. – ingyhere Mar 03 '18 at 00:58
  • Thanks. no other suggestions worked, but this one did. – cloudberry Feb 04 '19 at 07:55
  • When using WSL, the path names are case insensitive and things go wrong. See updates on case-sensitive mount: https://devblogs.microsoft.com/commandline/improved-per-directory-case-sensitivity-support-in-wsl/ Use `find -type d -exec setfattr -n system.wsl_case_sensitive -v 1` to update directories in a repo. – Aaron Sep 16 '19 at 17:48
  • Uhm, my problem was that several of the files to be reset were opened by vscode after a refactoring. After closing them the effects of git reset were clear. Your answer helped me figure it out. Thanks. – Aspiring Dev Nov 22 '19 at 02:46
  • Nice approach. It saved my ass. Thanks very much. – Ken Zhang Feb 26 '20 at 07:01
  • 6
    This does not do the trick for me. I needed to do `git add .` before `git reset --hard` – Derk Jan Speelman Mar 20 '20 at 09:00
132

Git won't reset files that aren't on repository. So, you can:

$ git add .
$ git reset --hard

This will stage all changes, which will cause Git to be aware of those files, and then reset them.

If this does not work, you can try to stash and drop your changes:

$ git stash
$ git stash drop
YuriAlbuquerque
  • 2,178
  • 1
  • 11
  • 19
  • 4
    The files were already tracked. Tried it anyway and it doesn't work either. There must be something really wrong with my repo, but I have no clue what. For the git stash thingy, see my answer to Shahbaz. – Norswap Jul 08 '12 at 12:28
  • What is happening when you do a git status? – YuriAlbuquerque Jul 08 '12 at 12:29
  • 1
    I thought about a solution. Make a commit and a interactive rebase to erase that commit. – YuriAlbuquerque Jul 08 '12 at 15:00
  • I tried that at one point, and it worked, tough I later gave it one more try and came up with the surprising result outlined in the edit of my answer. – Norswap Jul 08 '12 at 15:20
  • 1
    @YuriAlbuquerque, Git does not quite understand [POLA](https://en.wikipedia.org/wiki/Principle_of_least_astonishment). Isn't the whole point of `git reset --hard` to "*[reset both the staging area and the working directory to match](https://www.atlassian.com/git/tutorials/undoing-changes/git-reset)*"? If a file is not staged, obviously we'd want to remove it when we do `reset --hard`. – Pacerier Oct 20 '15 at 09:06
  • @Pacerier, I have no idea why such a design decision was made, but I can guess the rationale is that a untracked file should not be imediately managed by Git. – YuriAlbuquerque Nov 16 '15 at 19:51
  • @YuriAlbuquerque, Git does not seem to have much thought on [design](http://www.slideshare.net/stevepyoung/13-steve-jobs-quotes). – Pacerier Nov 26 '15 at 20:12
126

If you use Git for Windows, this is likely your issue

I've had the same problem and stash, hard reset, clean or even all of them was still leaving changes behind. What turned out to be the problem was the x file mode that was not set properly by git. This is a "known issue" with git for windows. The local changes show in gitk and git status as old mode 100755 new mode 100644, without any actual file differences.

The fix is to ignore the file mode:

git config core.filemode false

More info here

Qwerty
  • 29,062
  • 22
  • 108
  • 136
vezenkov
  • 4,009
  • 1
  • 26
  • 27
  • Thanks. This was helpful. See also https://stackoverflow.com/a/31187212/470749 – Ryan Jul 06 '20 at 21:32
  • This worked for me also when the repository was stored in a NAS with a different filesystem/os than the computer running git (no Windows involved) – furins Aug 10 '23 at 08:41
34

Okay, I've kind of solved the problem.

It seemed that the .gitattributes file, containing:

*.sln        eol=crlf
*.vcproj     eol=crlf
*.vcxproj*   eol=crlf

made the project files appear unstaged. I am clueless why that is, and I'm really hoping that someone privy to the ways of git will give us a nice explanation.

My fix was to remove these files, and to add autocrlf = false under [core] in .git/config.

This does not amount to exactly the same thing as the previous configuration, as it requires every dev to have autocrlf = false. I'd like to find a better fix.

EDIT:

I commented the incriminating lines, uncommented them and it worked. What the ... I don't even ... !

Norswap
  • 11,740
  • 12
  • 47
  • 60
  • 1
    I just had this same exact problem occur and this was the only solution that worked. In my case I switched from a feature branch to my master and pulled some new changes from upstream and it just started happening for 2 files that were modified. It looks like the files may have been switched from Unix to Windows line endings which may have something to do with it. Not sure how or why though. – Steven Surowiec Feb 07 '13 at 19:25
  • +1 Same issue on Windows Git. Already had `autocrlf = false`. I merged in changes from upstream svn repo (`git svn fetch` / `git merge git-svn`) and was left with 1 file marked as modified. The strange thing is that I've had this issue before and all I needed to do was check out another branch (with the `-f` flag), and then switch back. I did that, and it worked, but when I switched to a feature branch, the "change" was back! Your edit at the bottom of the answer was the solution. In my case I commented/uncommented one line at the top of my .gitattributes file: `* text=auto !eol` – Aaron Blenkush Oct 09 '13 at 18:53
  • 1
    That EDIT worked for me as well: comment out the lines in `.gitattributes`, run `git status`, uncomment the lines in `.gitattributes`, run `git status` again – Ignitor Aug 08 '16 at 12:47
  • This is because git is resetting those files, then applying the line endings specified in the `.gitattributes` again. The `git diff` probably shows the famous *wall of red/wall of green* that is typical of line-ending differences. – Dagrooms Jul 10 '17 at 16:57
  • **My solution:** _Before you start:_ Commit your current work. _Then:_ **1.** `git reset --hard` or `git checkout --force ` **2.** `git add --all --renormalize` **3.** `git commit -m "Normalize all the line endings"`. [Reference](https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings#refreshing-a-repository-after-changing-line-endings) – ADTC Dec 01 '21 at 16:26
28

Possible Cause #1 - Line Ending Normalization

One situation in which this can happen is when the file in question was checked into the repository without the correct configuration for line endings (1) resulting in a file in the repository with either the incorrect line endings, or mixed line endings. To confirm, verify that git diff shows only changes in line endings (these may not be visible by default, try git diff | cat -v to see carriage returns as literal ^M characters).

Subsequently, someone probably added a .gitattributes or modified the core.autocrlf setting to normalize line endings (2). Based on the .gitattributes or global config, Git has applied local changes to your working copy that apply the line ending normalization requested. Unfortunately, for some reason git reset --hard does not undo these line normalization changes.

Solution

Workarounds in which the local line endings are reset will not solve the problem. Every time the file is "seen" by git, it will try and reapply the normalization, resulting in the same issue.

The best option is to let git apply the normalization it wants to by normalizing all the line endings in the repo to match the .gitattributes, and committing those changes -- see Trying to fix line-endings with git filter-branch, but having no luck.

If you really want to try and revert the changes to the file manually then the easiest solution seems to be to erase the modified files, and then to tell git to restore them, although I note this solution does not seem to work consistently 100% of the time (WARNING: DO NOT run this if your modified files have changes other than line endings!!):

    git status --porcelain | grep "^ M" | cut -c4- | xargs rm
    git checkout -- .

Note that, unless you do normalize the line endings in the repository at some point, you will keep running into this issue.

Possible Cause #2 - Case Insensitivity

The second possible cause is case insensitivity on Windows or Mac OS/X. For example, say a path like the following exists in the repository:

/foo/bar

Now someone on Linux commits files into /foo/Bar (probably due to a build tool or something that created that directory) and pushes. On Linux, this is actually now two separate directories:

/foo/bar/fileA
/foo/Bar/fileA

Checking this repo out on Windows or Mac may result in modified fileA that cannot be reset, because on each reset, git on Windows checks out /foo/bar/fileA, and then because Windows is case insensitive, overwrites the content of fileA with /foo/Bar/fileA, resulting in them being "modified".

Another case may be an individual file(s) that exists in the repo, which when checked out on a case insensitive filesystem, would overlap. For example:

/foo/bar/fileA
/foo/bar/filea

There may be other similar situations that could cause such problems.

git on case insensitive filesystems should really detect this situation and show a useful warning message, but it currently does not (this may change in the future -- see this discussion and related proposed patches on the git.git mailing list).

Solution

The solution is to bring the case of files in the git index and the case on the Windows filesystem into alignment. This can either be done on Linux which will show the true state of things, OR on Windows with very useful open source utility Git-Unite. Git-Unite will apply the necessary case changes to the git index, which can then be committed to the repo.

(1) This was most likely by someone using Windows, without any .gitattributes definition for the file in question, and using the default global setting for core.autocrlf which is false (see (2)).

(2) http://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line/

Raman
  • 17,606
  • 5
  • 95
  • 112
  • Damn son, took all the way to this one. I had to commit after the first line but I was able to finally checkout master. That was not fun. – Tim Lieberman Aug 09 '17 at 03:02
27

If other answers are not working, trying adding the files, then resetting

$ git add -A
$ git reset --hard

In my case, this helped when there were a bunch of empty files that git was tracking.

Community
  • 1
  • 1
joshuakcockrell
  • 5,200
  • 2
  • 34
  • 47
9

Another cause for this might be case-insensitive file systems. If you have multiple folders in your repo on the same level whose names only differ by case, you will get hit by this. Browse the source repository using its web interface (e.g. GitHub or VSTS) to make sure.

For more information: https://stackoverflow.com/a/2016426/67824

Community
  • 1
  • 1
Ohad Schneider
  • 36,600
  • 15
  • 168
  • 198
  • To find the names of such files run `git ls-tree -r --name-only HEAD | tr A-Z a-z | sort | uniq -d` – Diomidis Spinellis Sep 23 '16 at 06:30
  • Apart from folders, this can also occur with multiple files differing only by case. I saw this with a Windows (non-case-sensitive) repo with origin on a Linux (case-sensitive) host - somehow we had got a copy of one file with differing case in there. – Daniel Bowen Aug 21 '20 at 04:00
  • exactly my issue ! – phatnhse May 02 '22 at 06:47
7

You can stash away your changes, then drop the stash:

git stash
git stash drop
Shahbaz
  • 46,337
  • 19
  • 116
  • 182
  • 1
    You may also be interested in [this](http://stackoverflow.com/questions/52704/how-do-you-discard-unstaged-changes-in-git). – Shahbaz Jul 08 '12 at 12:27
6

Run clean command:

# Remove all untracked files and directories. (`-f` is `force`, `-d` is `remove directories`)

git clean -fd
mrks
  • 5,439
  • 11
  • 52
  • 74
  • 4
    Unfortunately this doesn't resolve issues related to line endings. – Christopher Schneider Apr 10 '17 at 13:06
  • This is only thing that resolve my issue, whatever my issue was. I had no `.gitattributes` file and line endings were not an issue since I'm on a linux box and all of the devs and our server are linux. – Samuel Neff Oct 22 '18 at 19:25
5

None of these methods worked for me, the only solution was to nuke the whole repo and re-clone it. This includes stashing, resetting, adding then resetting, clrf settings, case sensitivity etc. Sigh..

John Hunt
  • 4,265
  • 8
  • 45
  • 59
  • Update, it turned out my mounted case sensitive filesystem wasn't actually case sensitive. After I fixed that this problem was fixable using the techniques mentioned above. – John Hunt Nov 07 '16 at 14:26
4

Check your .gitattributes.

In my case I have *.js text eol=lf in it and git option core.autocrlf was true.

It brings me to the situation when git autoconverts my files line endings and prevent me to fix it and even git reset --hard HEAD didn`t do anything.

I fix it with commenting *.js text eol=lf in my .gitattributes and uncommented it after it.

Looks like it just git magic.

Ohar
  • 297
  • 3
  • 15
  • 1
    This was it for me, [upgrading my project](https://react-native-community.github.io/upgrade-helper/?from=0.61.5&to=0.62.2) introduced `*.bat text eol=crlf` to my project. – Leo Apr 20 '20 at 19:54
  • I had the same problem with `gradlew.bat`, does this mean `eol=crlf` doesn't work on Windows? – TWiStErRob Jan 19 '23 at 17:56
4

I believe that there is an issue with git for Windows where git randomly writes the wrong line endings on checkout and the only workaround is to checkout some other branch and force git to ignore changes. Then checkout the branch you actually want to work on.

git checkout master -f
git checkout <your branch>

Be aware that this will discard any changes you might have intentionally made, so only do this if you have this problem immediately after checkout.

Edit: I might have actually got lucky the first time. It turns out that I got bit again after switching branches. It turned out that the files git was reporting as modified after changing branches was changing. (Apparently because git was not consistently applying the CRLF line ending to files properly.)

I updated to the latest git for Windows and hope the problem is gone.

mrfelis
  • 736
  • 7
  • 18
1

I had the same problem. I did git reset --hard HEAD but still every time I did git status I was seeing some files as modified.

My solution was relatively simple. I just closed my IDE (here it was Xcode) and close my command line (here it was terminal on my Mac OS) and tried it again and it worked .

Yet I was never able to find what originated the problem.

mfaani
  • 33,269
  • 19
  • 164
  • 293
  • In my case it was the IDE (codium) which always updated the file `.classpath` which then appeared again and again as modified. – dr0i Dec 15 '20 at 13:51
1

I hit a similar issue also involving .gitattributes, but for my case involved GitHub's LFS. While this isn't exactly the OP's scenario, I think it provides an opportunity to illustrate what the .gitattributes file does and why it can lead to unstaged changes in the form of "phantom" differences.

In my case, a file already was in my repository, like since the beginning of time. In a recent commit, I added a new git-lfs track rule using a pattern that was in hindsight a bit too broad, and ending up matching this ancient file. I know I didn't want to change this file; I know I didn't change the file, but now it was in my unstaged changes and no amount of checkouts or hard resets on that file was going to fix it. Why?

GitHub LFS extension works primarily through leveraging the hooks that git provides access through via the .gitattributes file. Generally, entries in .gitattributes specify how matching files should be processed. In the OP's case, it was concerned with normalizing line endings; in mine, it was whether to let LFS handle the file storage. In either case, the actually file that git sees when computing a git diff does not match the file that you see when you inspect the file. Hence, if you change how a file is processed via the .gitattributes pattern that matches it, it will show up as unstaged changes in the status report, even if there really is no change in the file.

All that said, my "answer" to the question is that if the change in .gitattributes file is something you wanted to do, you should should really just add the changes and move on. If not, then amend the .gitattributes to better represent what you want to be doing.

References

  1. GitHub LFS Specification - Great description of how they hook into the clean and smudge function calls to replace your file in the git objects with a simple text file with a hash.

  2. gitattributes Documentation - All the details on what is available to customize how git processes your documents.

merv
  • 67,214
  • 13
  • 180
  • 245
1

try to simply git restore .

That's what git says & it's working

Sergei
  • 93
  • 1
  • 6
0

Similar issue, although I'm sure only on surface. Anyway, it may help someone: what I did (FWIW, in SourceTree): stashed the uncommitted file, then did a hard reset.

elder elder
  • 645
  • 1
  • 9
  • 23
0

As other answers have pointed out, the problem is because of line-end auto correcting. I encountered this issue with *.svg files. I used svg file for icons in my project.

To solve this issue, I let git know that svg files should be treated as binary instead of text by adding the below line to .gitattributes

*.svg binary

vuamitom
  • 173
  • 2
  • 8
0

In a similar situation. As a result of many years of torment with many programmers who were able to stuff different encodings of the ends of lines (.asp, .js, .css ... not the essence) into one file. Some time ago refused .gitattributes. Settings for repo left autorclf = true andsafecrlf = warn.

The last problem arose when synchronizing from the archive with different ends of lines. After copying from the archive, in the git status many files are changed with the note

The line will have its original line endings in your working directory. warning: LF will be replaced by CRLF in ...

Tips from How to normalize working tree line endings in Git? helped

git add -u

MrSwed
  • 559
  • 8
  • 15
0

Another possibility that I encountered was that one of the packages in the repository ended up with a detached HEAD. If none of the answer here helps and you encounter a git status message like this you might have the same problem:

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:   path/to/package (new commits)

Going into the path/to/package folder a git status should yield the following result:

HEAD detached at 7515f05

And the following command should then fix the issue, where master should be replaced by your local branch:

git checkout master

And you'll get a message that your local branch will be some amounts of commits behind the remote branch. git pull and you should be out of the woods!

Robin De Schepper
  • 4,942
  • 4
  • 35
  • 56
0

Enviro: Visual Studio 2019 + git + Azure DevOps.

Behavior

Ran into this situation after attempting a hard reset, but mine was not due to line endings.

git was hanging when executing a number of commands; in other words, it would never get back to the command prompt. It would show files in a given command as having been processed, but it would not complete all "phases" of a command.

git clone, as an example:

enter image description here

Solution

Create a new Personal Access Token PAT

Was a security/credential issue related to my existing PAT, but I could not find any logging to tell me that it was failing.

katzbatz
  • 332
  • 2
  • 16
-4

For some reason

git add .

didn't work, but

$ git add -A

worked out!

Daniel Danielecki
  • 8,508
  • 6
  • 68
  • 94