Chapters

Hide chapters

Advanced Git

Third Edition · Git 2.50 · Console

Section I: Advanced Git

Section 1: 7 chapters
Show chapters Hide chapters

6. Gitignore After the Fact
Written by Jawwad Ahmad

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

When you start a new software project, you might think that the prefab .gitignore you started with will cover every possible situation. But more often than not, you’ll realize that you’ve committed files to the repository that you shouldn’t have. While it seems that all you have to do to correct this is to reference that file in .gitignore, you’ll find that this doesn’t solve the problem as you thought it would.

In this chapter, you’ll cover a few common scenarios where you need to go back and tell Git to ignore those types of mistakes. You’re going to look at two scenarios to fix this locally: Forcing Git to assume a file is unchanged and removing a file from Git’s internal index.

Getting started

To start, extract the repository contained in the starter .zip file inside the starter directory from this chapter’s materials. Or, if you completed all of the challenges from the previous chapter, feel free to continue with that instead.

.gitignore across branches

Git’s easy and cheap branching strategy is amazing, isn’t it? But there are times when flipping between branches without a little forethought can get you into a mess.

How Git tracking works

When you stage a change to your repository, you’re adding the information about that file to Git’s index, or cache. This is a binary structure on disk that tracks everything you’ve added to your repository.

Updating the index manually

If all you want is for Git to ignore this file, you can update the index yourself to tell Git to assume that this file will never, ever change again.

Removing files from the index

When you implicitly or explicitly ask Git to start tracking a file, Git dutifully places that file in your index and starts watching for changes. If you’re quite certain that you don’t want Git to track this file anymore, you can remove this file from the index yourself.

Rebasing isn’t always the solution

Assume you don’t want anyone to know about the existence of IGNORE_ME. You’ve already learned one way to rewrite the history of your repository: Rebasing. But will this solve your current issue?

Using filter-branch to rewrite history

Let’s put the issue with IGNORE_ME aside for the moment; you’ll come back to it at the end of the chapter. Right now, you’ll work through an issue with a similar file, SECRETS, that plays out the dreaded scenario above where you’ve committed files or other information that you never wanted to be public.

Challenge: Remove IGNORE_ME from the repository

Now that you’ve learned how to eradicate any trace of a file from a repository, you can go back and remove all traces of IGNORE_ME from your repository.

Key points

  • .gitignore works by comparing files in the staging area, or index, to what’s in your working tree.
  • .gitignore won’t filter out any files already present in the index.
  • git status --ignored shows you the files that Git is currently ignoring.
  • git update-index --assume-unchanged <filename> tells Git to always assume that the file contained in the index will never change. This is a quick way to work around a file that isn’t being ignored.
  • git rm --cached <filename> removes a file from the index but leaves the original file in your working tree.
  • git rm --cached --ignore-unmatch <filename> will succeed, returning an exit code of 0, if git rm doesn’t match on a file in the index. This is important when you use this command in conjunction with filter-branch.
  • git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch -- <filename>' HEAD will modify any matching commits in the repository to remove <filename> from their contents.
  • The --prune-empty option will remove any commits from the repository that are empty after your filter-branch.

Where to go from here?

What you’ve learned in this chapter will usually serve you well when you’ve committed something to your repository that you didn’t intend to be there.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now