Multi-Level File Ignoring System in Git

File ignoring in a repository can be configured at several levels, each with its own characteristics:

  1. Global level: Ignoring files for all repositories on the computer. This is configured in a configuration file that applies to all user repositories.

  2. Repository level: Ignoring files for a specific repository that applies to all users working on that project. Settings are stored in a .gitignore file located in the root folder of the repository.

  3. User level: Ignoring files only for a specific user and their working directory in the repository. These settings are specified through the .git/info/exclude file, which is not included in version control and is only available locally to that user.

This multi-level system allows for flexible management of file exceptions from version control depending on your needs.

Configuring gitignore at the global level

You need to create a .gitignore file just like you would for each repository. It is usually created in the home directory but can be placed anywhere on the computer.

After creating the file, you need to inform Git where the global gitignore file is located:

git config --global core.excludesfile <path_to_file>/.gitignore

gitignore settings at the repository level

The .gitignore file is a rule for all project participants that tells Git which files to ignore in the repository. These settings apply to all users working with this repository.

This is the .gitignore file located at the root of the repository. It should primarily contain rules that have a direct relevance to the project and its architecture. For instance, if all project participants have a directory with local data or passwords, or if temporary files are created in the same location by everyone. If these rules are relevant to all project participants, then the ignoring rules should be placed in the .gitignore that will be shared with the repository.

A long time ago, I thought that everyone had their own .gitignore and that it shouldn’t be committed, but it turns out it should be, so that all project participants have the same files and folders ignored.

Configuring gitignore at the user level

This approach allows a user to ignore files and directories in Git exclusively for their local working copy of the repository. This is useful if a user needs to exclude temporary files generated by themselves (for example, editor files, local builds, logs, etc.) from indexing without affecting the settings of other project participants.

The main advantages of using .git/info/exclude:

  1. Locality: This file only acts in the current repository on the local machine and does not affect other users.
  2. Isolation: Ignoring settings remain private and do not interfere with collaboration in the repository.

This approach is suitable for users who want to keep their local settings without violating the team’s common agreements.

Examples of Rules and Exceptions in the gitignore File

Rules in the .gitignore can be both simple and complex, allowing for precise configuration of Git behavior.

Here are examples of various file ignoring rules in Git and their explanations:

# comment — this line is ignored
 
# do not process files ending with .a
*.a
 
# BUT track the file lib.a, even though we ignore all .a files with the previous rule
!lib.a
 
# ignore only the TODO file located in the root directory; does not apply to files with the same name in subdirectories, e.g., subdir/TODO
/TODO
# ignore all files in the build/ directory
build/
# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt
# ignore all .txt files in the doc/ directory and its subdirectories
doc/**/*.txt

In the .gitignore file, you need to specify relative paths. These paths are specified relative to the root directory of your repository (the directory that contains the .git folder).

To ignore a file or folder in the root directory:

secret.txt 
/build/

This ignores the secret.txt file and the build folder, which are located in the root of the repository.

What to Do If Files Continue to be Tracked After Adding to gitignore

If you have added a folder to .gitignore, but git status still shows changes in the files of that folder, it is because Git is already tracking those files (i.e., they were added to the repository before you added them to .gitignore).

Git will not automatically stop tracking files that have already been added. To fix this, you need to follow a few steps:

1. Stop tracking files that are already in the repository

Use the git rm command with the --cached flag to remove files from the index (i.e., stop tracking them) without physically deleting them from the disk:

git rm -r --cached folder_name/

This command will remove all files from the specified folder from the index (the index is the area where Git stores information about which files are tracked). The files will remain on the disk, but Git will stop tracking them.

2. Commit the changes

Once you stop tracking the files, you need to commit the changes:

git commit -m "Stopped tracking folder"

Now Git will stop tracking the files in this folder, and .gitignore will start working correctly for this folder.

Temporarily Ignoring Changes to a File

In Git, there is a command that allows you to temporarily stop tracking changes in an already tracked file.

When using this command for a specific file, Git will “assume” that this file remains unchanged and will not display it in the list of modified files when you run the git status command, even if local changes were made to the file.

This is useful when you need to change a file only for local work without affecting the main version of the file in the repository

You can temporarily ignore changes to a file using the command:

git update-index --assume-unchanged <file>

To disable it, use the command:

git update-index --no-assume-unchanged <file>

View what is in the .gitignore file at the repository level:

git status --ignored