Hoofdstuk 4 · oefening
Dingen ongedaan maken
Ik heb een bestand gewijzigd en wil de oude versie terug
Je hebt een repository met een paar commits, je hebt een bestand gewijzigd en die wijziging was verkeerd. De wijziging aan dat bestand is niet gecommit en ook niet klaargezet. Je wilt het bestand alleen terug zoals het was.
Dit is de meest voorkomende manier van ongedaan maken. Het goede nieuws: het is ook de veiligste, want Git heeft al een kopie van de oude versie.
Kijk voordat je iets aanraakt
De repository in je terminal is een kleine wandelgids. Iemand heeft eraan gewerkt. Begin door Git te vragen wat er verschilt:
git status
git diff
git status groepeert wat is klaargezet, wat is gewijzigd maar niet klaargezet, en wat untracked is. Het toont de gewijzigde regels niet. Voordat je iets ongedaan maakt, wil je die juist zien.
git diff laat ze zien. Het toont de gewijzigde regels, met een - als de regel er eerst was en verdwijnt, of een + als hij nieuw is. Een bestand zonder wijzigingen geeft helemaal geen uitvoer. Daarom is een leeg antwoord van git diff een nuttig antwoord.
In hoofdstuk 3 las je diffs tussen twee opgeslagen commits. Zonder commitnamen, zoals hier, vergelijkt git diff de werkboom met de staging area. Van route.txt is niets klaargezet. De klaargezette versie komt dus nog overeen met de nieuwste commit en deze diff toont de ongewenste bewerking. Dat is genoeg om haar veilig ongedaan te maken.
Je zou moeten zien dat de afstand in route.txt is veranderd van 11km in 110km. Dat is de fout. Het is een echte wandelroute en 110km is geen dagje uit.
Zet het bestand terug
De opdracht heet git restore. Ze overschrijft het bestand in je werkboom met een bekende, goede kopie die Git al heeft.
Welke kopie dat is verdient een zin, want dat zorgt later voor verrassingen. Standaard neemt git restore de versie uit de staging area. Hier is niets van route.txt klaargezet, dus de klaargezette versie komt nog overeen met de nieuwste commit. Herstellen zet daardoor de gecommitte versie terug. Zodra je werk in uitvoering klaarzet, zijn die versies niet meer gelijk. Met de optie --source kun je aangeven welke je bedoelt.
git restore route.txt
git status
git diff
git restore route.txt noemt het ene bestand dat je wilt terugzetten. De tweede git status hoort route.txt niet meer te noemen. git diff hoort helemaal niets te tonen, omdat er geen verschil meer is.
Wat dit vernietigt en wat niet
Wees je hiervan bewust: deze opdracht kan niet-gecommit werk echt weggooien.
git restore gooit je niet-gecommitte wijziging aan dat bestand definitief weg. De bewerking naar 110km staat niet in een commit. Git heeft er dus nooit een kopie van gehad en geen latere les in dit hoofdstuk kan haar terughalen. Dat is de ruil: je krijgt de oude versie terug doordat je de nieuwe opgeeft.
Je geschiedenis beschadigen kan de opdracht niet. Ze raakt geen commits aan, verplaatst geen branch en heeft alleen effect op de paden die je noemt. Een bestand dat je niet noemt blijft met rust.
De regel om te onthouden: git restore is veilig voor gecommit werk en definitief voor niet-gecommit werk. Twijfel je of je de wijziging kwijt wilt, voer dan eerst git diff uit en lees wat je gaat verliezen.
Je voert git restore route.txt uit in een repository waarin je ook notes.md hebt bewerkt. Wat gebeurt er met notes.md?
Hierna: dezelfde situatie, één stap verder, wanneer de wijziging die je ongedaan wilt maken al is klaargezet.