title: Definitive retroactive .gitignore (how to make Git completely/retroactively forget about a file now in .gitignore)
body: <h2>Preface</h2>
  
  <p>This question attempts to clear the confusion regarding applying .gitignore <strong>retroactively</strong>, not just to the present/future.<sup>1</sup></p>
  
  <h2>Rationale</h2>
  
  <p>I've been searching for a way to make my current .gitignore be retroactively enforced, <strong>as if I had created .gitignore in the first commit</strong>.  </p>
  
  <p>The solution I am seeking:  </p>
  
  <ul>
  <li>Will <em>not</em> require manually specifying files</li>
  <li>Will <em>not</em> require a commit</li>
  <li>Will apply retroactively to all commits of all branches</li>
  <li>Will <em>ignore</em> .gitignore-specified files in working dir, <strong>not delete</strong> them (just like an originally root-committed .gitignore file would)</li>
  <li>Will use git, not BFG</li>
  <li>Will apply to .gitignore exceptions like:</li>
  </ul>
  
  <pre><code> *.ext
   !*special.ext
  </code></pre>
  
  <hr>
  
  <h2>Not solutions</h2>
  
  <pre><code>git rm --cached *.ext
  git commit
  </code></pre>
  
  <p>This requires 1. manually specifying files and 2. an additional commit, which will result in newly-ignored file <em>deletion</em> when pulled by other developers. (It is effectively just a <code>git rm</code> - which is a <em>deletion</em> from git tracking - but it leaves the file alone in the local (<em>your</em>) working directory.  <em>Others</em> who <code>git pull</code> afterwards will receive the file <em>deletion</em> commit)</p>
  
  <pre><code>git filter-branch --index-filter 'git rm --cached *.ext'
  </code></pre>
  
  <p>While this <em>does</em> purge files retroactively, it 1. requires manually specifying files and 2. <a href="https://stackoverflow.com/a/57419809/423125"><em>deletes</em> the specified files from the <strong>local</strong> working directory</a> just like plain <code>git rm</code> (and so also for others who <code>git pull</code>)!</p>
  
  <hr>
  
  <h2>Footnotes</h2>
  
  <p><sup>1</sup>There are many similar posts here on SO, with less-than-specifically-defined questions and even more less-than-accurate answers. See <a href="https://stackoverflow.com/q/1274057">this question with 23 answers</a> where the <a href="https://stackoverflow.com/a/1274447">accepted answer with ~4k votes</a> is <strong>incorrect</strong> according to the standard definition of "forget" <a href="https://stackoverflow.com/a/56051380">as noted by one mostly-correct answer</a>, and <a href="https://stackoverflow.com/a/1274126/423125">only</a> 2 <a href="https://stackoverflow.com/a/56051380/423125">answers</a> include the <strong><em>required</em></strong> <code>git filter-branch</code> command.</p>
  
  <p><a href="https://stackoverflow.com/q/936249/423125">This question with 21 answers</a> <strike>is</strike> was marked as a duplicate of the previous one, but the question is defined differently (ignore vs forget), so while the answers may be appropriate, it is <strong>not</strong> a duplicate.</p>
  
  <p><a href="https://stackoverflow.com/q/43463687">This question</a> is the closest I've found to what I'm looking for, but the answers don't work in all cases (paths with spaces...) and perhaps are a bit more complex than necessary regarding creating an external-to-repository .gitignore file and copying it into every commit.</p>