Categories
git

How to stop tracking and ignore changes to a file in Git?

1992

I have cloned a project that includes some .csproj files. I don’t need/like my local csproj files being tracked by Git (or being brought up when creating a patch), but clearly they are needed in the project.

I have added *.csproj to my LOCAL .gitignore, but the files are already in the repo.

When I type git status, it shows my changes to csproj which I am not interested in keeping track of or submitting for patches.

How do I remove the “tracking of” these files from my personal repo (but keep them in the source so I can use them) so that I don’t see the changes when I do a status (or create a patch)?

Is there a correct/canonical way to handle this situation?

3

  • 21

    A very useful question, but I’m curious as to why you wouldn’t want to track changes to the .csproj file, which is very much an important part of any project. Changes to the .csproj.user file or any .Publish.XML files I can totally understand not tracking, but I’m intrigued as to why you wouldn’t want to track the .csproj

    May 3, 2012 at 10:26


  • 9

    Maybe they use a different IDE?

    – Jarrett

    Apr 2, 2013 at 1:17

  • 3

    Ironically, I came to this thread because I’m looking to remove .suo files from a repo but keep them locally. For posterity, .Net development requires you to keep .csproj files in the repo and those changes should always be tracked unless you’d like to feel the wrath of any other developers on your project. If ever unsure, take a look at the gitignore files repo on GitHub: github.com/github/gitignore/blob/master/VisualStudio.gitignore

    – longda

    Sep 22, 2013 at 20:39

2368

Just calling git rm --cached on each of the files you want to remove from revision control should be fine. As long as your local ignore patterns are correct you won’t see these files included in the output of git status.

Note that this solution removes the files from the repository, so all developers would need to maintain their own local (non-revision controlled) copies of the file

To prevent git from detecting changes in these files you should also use this command:

git update-index --assume-unchanged [path]

What you probably want to do: (from below @Ryan Taylor answer)

  1. This is to tell git you want your own independent version of the file or folder. For instance, you don’t want to overwrite (or delete)
    production/staging config files.

git update-index --skip-worktree <path-name>

The full answer is here in this URL: http://source.kohlerville.com/2009/02/untrack-files-in-git/

25

  • 213

    “git rm –cached <file>” would remove <file> from version control, while keeping it in the working repository. Whether it is what you want…

    Jun 2, 2009 at 0:03

  • 54

    But when other will pull the repository, will their own *.csproj file will be removed ? Because if we want the file to be untracked, but not deleted.

    – FMaz008

    Jun 1, 2011 at 13:07

  • 23

    If you are trying to remove ALL the files in a directory, combine it with git ls-files: git ls-files | xargs git rm --cached — that will remove everything from the git index in a given directory without deleting the actual files.

    – Marco

    Nov 10, 2011 at 19:51

  • 135

    git rm --cached -r <dir> works recursively on a folder and all files in it.

    – Krista K

    Feb 15, 2013 at 1:29

  • 48

    This will stop tracking of the file, preserve it locally, but cause it to be deleted for anyone who pulls

    Feb 14, 2014 at 0:58

423

There are 3 options; you probably want #3

  1. This will keep the local file for you, but will delete it for anyone else when they pull.

    git rm --cached <file-name> or git rm -r --cached <folder-name>

  2. This is for optimization, like a folder with a large number of files, e.g. SDKs that probably won’t ever change. It tells Git to stop checking that huge folder every time for changes, locally, since it won’t have any. The assume-unchanged index will be reset and file(s) overwritten if there are upstream changes to the file/folder (when you pull).

    git update-index --assume-unchanged <path-name>
    
  3. This is to tell Git that you want your own independent version of the file or folder. For instance, you don’t want to overwrite (or delete) production/staging config files.

    git update-index --skip-worktree <path-name>
    

    It’s important to know that git update-index will not propagate with Git, so each user will have to run it independently.

8

  • 20

    This answer is the most complete – it offers various solutions with the ramifications of each. The specific case I am working with has a password embedded in a config file. I want to propagate a template file then add the password to my copy. The copy with the password should be ignored and not overwritten.

    Nov 20, 2016 at 16:23

  • 2

    How can i check, in my local, which files apply for ‘assume-unchanged’ or ‘skip-worktree’?

    Sep 19, 2017 at 1:44

  • 4

    @SupawatPusavanno to see which files you previously selected for assume-unchanged or skip-worktree look at this answer stackoverflow.com/questions/42363881/… — it uses grep and git ls-files

    Sep 19, 2017 at 17:15

  • 1

    Very good answer. But git throws error when I try to switch to a different branch:error: “Your local changes to the following files would be overwritten by checkout …..” and the solution is to stash the changes before switching and un-stash when you come back to the branch.

    Dec 13, 2017 at 5:28


  • 1

    @RyanTaylor is it possible to keep your own local version of the file, not pushing your own changes, while still pulling in changes that are pushed to the repo?

    May 18, 2021 at 21:17

260

If you do git update-index --assume-unchanged file.csproj, git won’t check file.csproj for changes automatically: that will stop them coming up in git status whenever you change them. So you can mark all your .csproj files this way- although you’ll have to manually mark any new ones that the upstream repo sends you. (If you have them in your .gitignore or .git/info/exclude, then ones you create will be ignored)

I’m not entirely sure what .csproj files are… if they’re something along the lines of IDE configurations (similar to Eclipse’s .eclipse and .classpath files) then I’d suggest they should simply never be source-controlled at all. On the other hand, if they’re part of the build system (like Makefiles) then clearly they should— and a way to pick up optional local changes (e.g. from a local.csproj a la config.mk) would be useful: divide the build up into global parts and local overrides.

15

  • 8

    csproj is a C# project file, which keeps track of which files are included in your project and other few configurations, it MUST be source controlled for the project to work

    – SparK

    Dec 4, 2013 at 15:20

  • 5

    This is the only right answer here! I’ve been using @araqnids answer for years and it works exactly as requested to solve this problem.

    – NHDaly

    May 27, 2014 at 4:31

  • 1

    Is there some way you can detect that this has been done for a file, or for what files this has been done in a repo? I’m a bit nervous about forgetting that I did this, then wondering why the heck this file isn’t getting updated, later on!

    Nov 27, 2014 at 2:41

  • 4

    @GreenAsJade: git ls-files -v will show files that are assumed unchanged with a lowercase indicator (e.g. h instead of usual H for cached files).

    – Amadan

    Nov 27, 2014 at 3:42


  • 1

    Thanks – this little pearl almost deserves a question of its own! … done stackoverflow.com/questions/27162966/…

    Nov 27, 2014 at 4:12