Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / DevOps

Git – 4 Ways to Ignore Files

5.00/5 (4 votes)
30 Jun 2023CPOL5 min read 20.7K  
Using .gitignore is not a good solution for every use case. There are alternatives.
If you have a config file like web.config that needs to be TRACKED by Git, but want LOCAL CHANGES IGNORED, that situation cannot be solved with .gitignore. We show alternative ways to achieve that.

1. Problem

During work with version management tools like Git, there are typically two situations in which you want your version management tool GIT to IGNORE CHANGES to your work directory or files themselves:

  1. Spam files
  2. Local version files

In case 1) typically you have an output of the build process, intermediary files, or the final result of the build. These are files you want UNTRACKED, that is Git should not track those files at all. So, you want them UNTRACKED.

In case 2) typically you have files that have a local version different than the tracked version, but you do not want your local changes to be committed to Git. An example is if you use a config file like web.config which contains your database connection string. You want that file TRACKED since that is an important part of your application, but you want changes to your local system to be ignored since your local version will contain your local settings that are different for each developer on the project. So, you want them TRACKED, LOCAL CHANGES IGNORED.

2. There are Four Ways to Ignore Files in Git

Here are four methods to ignore files in Git:

  1. Usage of .gitignore (GLOBALY UNTRACKED)
  2. Usage of .git/info/exclude (LOCALY UNTRACKED)
  3. Usage of assume-unchanged (TRACKED, LOCAL CHANGES IGNORED)
  4. Usage of skip-worktree (TRACKED, LOCAL CHANGES IGNORED)

3. Sample Project

We have set up a small project to demo this article:

Image 1

We used the GUI tool SourceTree to add and commit files:

Image 2

4. Method A - Usage of .gitignore

4.1. Overview

The usage of .gitignore file is very popular and well-described elsewhere, so I will not go into details. Just to mention, this method is planned to be applied to files that you want GLOBALY UNTRACKED. File in .gitignore is completely ignored by Git on all systems using that repository.
You need to add .gitignore file and add to that file files you want to be ignored. You will need to add and commit .gitignore to the Git.

This method can be applied to files that are untracked and you want them to be ignored. It is not appropriate to try this method on files that are already tracked by Git. Adding a file tracked by Git to .gitignore will not provide any result. One might think, if I add the tracked file to .gitignore, it will not be tracked from that point on, but it does not work that way.

4.2. Example

Let us assume we have a spam1.txt file that we do not want to track. SourceTree will report it is there:

Image 3

Image 4

You need to add .gitignore file and add to that file files you want to be ignored. You will need to add and commit .gitignore to the Git. Here is how the situation looks now:

Image 5

Image 6

Image 7

So, SourceTree no longer sees spam1.txt. It does see an additional file .gitignore. So file spam1.txt is GLOBALY UNTRACKED.

5. Method B - Usage of .git/info/exclude

5.1. Overview

You need to add .git/info/exclude file and add to that file files you want to be ignored. The format is the same as the format of .gitignore file.

This method is very similar to .gitignore method, just file .git/info/exclude is not itself part of the repository so its influence is local. This method is planned to be applied to files that you want LOCALLY UNTRACKED.

5.2 Example

Let us assume we have a spam2.txt file that we do not want to track. SourceTree will report it is there:

Image 8

Image 9

You need to add .git/info/exclude file and add to that file files you want to be ignored. The format is the same as the format of .gitignore file. Here is how the situation looks now:

Image 10

Image 11

Image 12

The SourceTree no longer sees spam2.txt file. So file spam2.txt is LOCALLY UNTRACKED.

6. Method C - Usage of assume-unchanged

6.1. Overview

The assume-unchanged option was envisioned as a performance aid but is often mentioned in the context of workarounds to ignore files. You explicitly tell Git not to check if the file has been changed. This method is planned to be applied to files that you want TRACKED, LOCAL CHANGES IGNORED.

Here are the commands you will need for this method:

To ignore local changes to tracked files:
git update-index --assume-unchanged [<file>...]

To track local changes again:
git update-index --no-assume-unchanged [<file>...]

To list all files assumed unchanged:
git ls-files -v | grep '^[[:lower:]]'

Just to mention that some articles on the internet [3] strongly discourage the usage of this method.

6.2 Example

Let us add config1.txt file and commit it to the repository.

Image 13

Image 14

Then make some changes to the file config1.txt and SourceTree will report that the file has been edited:

Image 15

On the command prompt, you need to add a command to assume that the file is unchanged. The source tree will no longer report that the file was edited.

Image 16

Image 17

The SourceTree no longer sees config1.txt file as modified, although that file has actually been locally modified, So, file config1.txt is TRACKED, LOCAL CHANGES IGNORED.

7. Method D - Usage of skip-worktree

7.1. Overview

The skip-worktree option is recommended by many on the internet as the right way to ignore files. You explicitly tell Git not to check if the file has been changed. This method is planned to be applied to files that you want TRACKED, LOCAL CHANGES IGNORED.

Here are the commands you will need for this method:

To ignore local changes to tracked files:
git update-index --skip-worktree  [<file>...]

To track local changes again:
git update-index --no-skip-worktree [<file>...]

To list all files marked with skip-worktree:
git ls-files -v | grep ^S

7.2. Example

Let us add config2.txt file and commit it to the repository.

Image 18

Image 19

Then make some changes to the file config3.txt and SourceTree will report that the file has been edited:

Image 20

On the command prompt, you need to add the command skip-worktree. The source tree will no longer report that the file was edited.

Image 21

Image 22

The SourceTree no longer sees config2.txt file as modified, although that file has actually been locally modified, So, file config2.txt is TRACKED, LOCAL CHANGES IGNORED.

8. Conclusion

Use case for having files TRACKED, LOCAL CHANGES IGNORED is very strong. Just to mention the web.config file that every developer ASP.NET will have locally modified with at least a database connection string. Usage of .gitignore in this case will not solve the problem. The appropriate method is the usage of skip-worktree option in Git.

Git has many options, but the command line interface is not user-friendly. It is a big disappointment that even GUI SourceTree does not offer for example context menu options to set file “local changes untracked” flag.

9. References

10. History

  • 30th June, 2023: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)