When .gitignore is Not Enough

In the world of version control with Git, .gitignore files are the go-to solution for excluding files and directories from being tracked.

However, there are cases when you don't want to touch the .gitignore file. Fortunately, Git provides other options for excluding changes from being tracked.

Cases

I would say there are two main cases when you don't want to touch the .gitignore file:

  • When you want to exclude your own file from being tracked (like an .envrc file with your local environment variables and aliases). In this case, use .git/info/exclude.
  • When you want to avoid tracking changes in a file that is already tracked by Git (like a docker-compose.yml config where you set a different local port, because it's already in use). In this case, use git update-index --assume-unchanged.

Using .git/info/exclude

When you want to exclude files from being tracked without affecting other collaborators, .git/info/exclude is your ally. This method is similar to .gitignore but is not committed with the repository, meaning it only affects your local environment. It's particularly useful for personal IDE settings or unique configuration files.

To use this method, simply edit the .git/info/exclude file in your local repository and add the patterns you wish to ignore, following the same syntax as .gitignore. For example:

# Example of .git/info/exclude
*.log
.idea/

This will prevent any .log files and anything in the .idea directory from showing up as untracked in your local repository without impacting other contributors.

Using git update-index --assume-unchanged

Sometimes, you might find yourself needing to work on a file that's already tracked by Git but want your changes to remain untracked. In such cases, git update-index --assume-unchanged can be invaluable. This command tells Git to ignore changes to a tracked file, effectively treating it as if it hasn't changed even if it has.

To mark a file as "assume unchanged," run:

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

And if you need to start tracking changes again, you can reverse it with:

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

It's important to note that this approach is best used sparingly, as it can lead to confusion if forgotten. The file remains in the repository and appears unchanged to Git, which can lead to discrepancies if not carefully managed.

Here's how to check which files are marked as "assume unchanged":

$ git ls-files -v | grep '^h'

Conclusion

While .gitignore is a powerful tool for managing what gets tracked by Git, it's not a one-size-fits-all solution. Understanding and using .git/info/exclude and git update-index --assume-unchanged allows you to manage your repository more flexibly and cater to more specific use cases. With these tools in your arsenal, you can ensure that your Git repository remains clean and contains only what it should.