Een bestand uit de geschiedenis verwijderen
git rm zorgt dat een bestand niet meer in nieuwe commits opduikt. Aan de
commits die er al zijn doet het niets: de blob zit nog in de objectdatabase, nog
in elke kloon, nog altijd één git show van je vandaan.
Dat telt op twee momenten — toen het bestand een credential was, en toen het 400 MB was.
⌘K → Bestand uit geschiedenis verwijderen, of rechtsklik het bestand — in
de projectboom, in de bestandenlijst van een commit, of in de commitopsteller. De
commit die een bestand verwijderde is meestal waar iemand doorheeft dat het nog
in de geschiedenis zit, dus de uitweg zit ook in dat menu.
Het pad vinden
Twee ingangen, want ze beantwoorden verschillende vragen.
Typ het — relatief aan de repository, zonder schuine streep vooraan — wanneer je al weet wat je kwam verwijderen.
Blader door de geschiedenis wanneer dat niet zo is. Het somt elk pad op dat ooit gecommit is, zwaarste eerst, met hoeveel versies elk heeft en of het nog getrackt wordt. Verwijderde paden zijn als zodanig gemarkeerd en zijn meestal de paden die je zoekt: een bestand dat weg is uit de werkboom maar nog in elke kloon zit, is precies het geval dat een gewoon bestandsvenster je niet kan tonen, want het bestand is er niet om te kiezen.
Dezelfde lijst beantwoordt de andere reden waarom mensen hier komen — waarom is deze kloon twee gigabyte — want hij is gesorteerd op het aantal bytes dat de blobs van elk pad werkelijk innemen. Een rij aanklikken meet het meteen.

Meten voor je akkoord gaat
Druk op Meten (of kies een rij). Er wordt nog niets geschreven. Je krijgt:
| Herschreven commits | Elke commit vanaf de eerste die het bestand bevatte |
| Branches / tags | Refs die gaan verschuiven |
| Vastgehouden door zijn blobs | Bytes die die versies werkelijk innemen |
| Eerste commit | Waar de herschrijving begint — alles erna krijgt een nieuwe hash |

Is het aantal nul, dan klopt het pad niet. Dat is meestal een spelfout of een mapprefix, geen afwezigheid.
Wat de herschrijving werkelijk doet
Gitcito kopieert elke branch en tag naar
refs/gitcito/pre-purge/<timestamp>/…, en draait dan:
git filter-branch --force \
--index-filter 'git rm --cached --ignore-unmatch -- <path>' \
--prune-empty --tag-name-filter cat -- --branches --tags
--index-filter herschrijft de index rechtstreeks in plaats van elke commit uit
te checken, en dat is het verschil tussen minuten en uren. --branches --tags in
plaats van --all is met opzet: --all zou de back-uprefs meenemen, en dan zou
de herschrijving haar eigen vangnet opeten.
Commits die niets anders bevatten dan het verwijderde bestand vallen weg
(--prune-empty). Tags worden opnieuw naar hun herschreven commits gewezen.
De back-up, en waarom de ruimte nog niet terugkomt
De purge is terug te draaien, en de prijs daarvan is dat de schijfruimte pas wordt teruggegeven als jij dat zegt. Zolang de back-up bestaat zijn de oude commits nog bereikbaar, dus git ruimt ze niet op.
| Actie | Effect |
|---|---|
| Herstellen | Elke branch en tag keert terug naar zijn commit van vóór de purge; het bestand komt met ze mee terug |
| Back-up weggooien | Verwijdert de back-uprefs, laat de reflog verlopen, draait git gc --prune=now — ruimte terug, purge nu definitief |
Twee stappen in plaats van één, want de eerste is de herstelbare helft en de tweede niet.
Roteer het geheim toch
Als een credential ooit gepusht is, maakt je geschiedenis herschrijven het lek niet ongedaan. Iemand kan het gefetcht hebben; forge-servers houden objecten zonder verwijzing nog een tijd vast; een CI-log kan het afgedrukt hebben. De herschrijving stopt de verdere verspreiding — ze draait de blootstelling niet terug.
Roteer de sleutel. Purge daarna, zodat de volgende die kloont hem niet vindt.
Wat het niet zal doen
- Het pusht niet. Herschrijven is lokaal. Het resultaat publiceren betekent een force push naar elke geraakte branch, en iedereen moet opnieuw klonen of hard resetten — de force-push-bewaking is waar die beslissing woont.
- Het weigert bij een vuile werkboom of midden in een merge/rebase. Een herschrijving verzet HEAD keer op keer, en dat rond niet-gecommit werk doen is hoe dat werk verdwijnt.
- Het herschrijft op pad, niet op inhoud. Een geheim verwijderen dat in een
bronbestand geplakt is in plaats van in een eigen bestand te wonen vraagt een
inhoudsfilter — dat is het terrein van
git filter-repo --replace-text, en Gitcito zet daar geen schil omheen. filter-branchis traag bij zeer grote geschiedenissen. Het is wat overal met git meekomt, en daarom gebruikt Gitcito het. Bij een repository met tienduizenden commits isgit filter-repoin de terminal de snellere tool.- De klonen van anderen zijn niet jouw repository. Zij houden de oude geschiedenis tot ze opnieuw klonen.