Close

git reset

De opdracht git reset is een complexe en veelzijdige tool om wijzigingen ongedaan te maken. Er zijn drie primaire vormen van aanroeping. Deze vormen komen overeen met opdrachtregelargumenten: --soft, --mixed, --hard. De drie argumenten komen elk overeen met de drie interne mechanismen voor statusbeheer van Git, de Commit-structuur (HEAD), de Staging-index en de Werkmap.


Git reset en de drie bomen van Git


Om het gebruik van git reset goed te begrijpen, moeten we eerst de systemen voor intern statusbeheer van Git begrijpen. Soms worden deze mechanismen de 'drie bomen' van Git genoemd. Bomen kunnen een verkeerde benaming zijn, aangezien het strikt traditionele gegevensstructuren van bomen niet zijn. Het zijn echter datastructuren gebaseerd op knooppunten en punten die Git gebruikt om een tijdlijn van bewerkingen bij te houden. De beste manier om deze mechanismen te demonstreren is door een changeset aan te maken in een repository en die door de drie bomen heen te volgen.

Om te beginnen maken we een nieuwe repository aan met de onderstaande opdrachten:

$ mkdir git_reset_test
$ cd git_reset_test/
$ git init .
Initialized empty Git repository in /git_reset_test/.git/
$ touch reset_lifecycle_file
$ git add reset_lifecycle_file
$ git commit -m"initial commit"
[main (root-commit) d386d86] initial commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 reset_lifecycle_file

De bovenstaande voorbeeldcode maakt een nieuwe git-repository aan met één leeg bestand, reset_lifecycle_file. Op dit moment heeft de voorbeeldrepository één commit (d386d86) door het toevoegen van reset_lifecycle_file.

Git-logo
gerelateerd materiaal

Git cheat sheet

Logo Bitbucket
Oplossing bekijken

Git leren met Bitbucket Cloud

De werkmap


De eerste boom die we zullen onderzoeken is 'De Werkmap'. Deze boom is gesynchroniseerd met het lokale bestandssysteem en vertegenwoordigt de rechtstreekse wijzigingen die worden aangebracht in de inhoud van bestanden en mappen.

$ echo 'hello git reset' > reset_lifecycle_file
 $ git status 
 On branch main
 Changes not staged for commit: 
 (use "git add ..." to update what will be committed) 
 (use "git checkout -- ..." to discard changes in working directory) 
 modified: reset_lifecycle_file

In onze demo-repository passen we de reset_lifecycle_file aan en voegen we daar wat inhoud aan toe. Het aanroepen van de git-status geeft aan dat Git op de hoogte is van de wijzigingen in het bestand. Deze wijzigingen maken momenteel deel uit van de eerste boomstructuur, 'de Werkmap'. Git-status kan worden gebruikt om wijzigingen in de Werkmap weer te geven. Ze worden in het rood weergegeven met een voorvoegsel van 'gewijzigd'.

Staging-index


De volgende is de boom van de 'Staging-index'. Deze boomstructuur houdt wijzigingen in de Werkmap bij, die met git add zijn gepromoot, en worden opgeslagen in de volgende commit. Deze boom is een complex mechanisme voor intern cachen. Git probeert over het algemeen de implementatiegegevens van de Staging-index voor de gebruiker te verbergen.

Om de status van de Staging-index nauwkeurig te kunnen bekijken, moeten we een minder bekende Git-opdracht gebruiken: git ls-files. De opdracht git ls-files is in wezen een hulpprogramma voor foutopsporing om de status van de boom voor Staging-index te inspecteren.

git ls-files -s
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0   reset_lifecycle_file

Hier hebben we git ls-files uitgevoerd met de optie -s of --stage. Zonder de optie -s is de output van git ls-files gewoon een lijst met bestandsnamen en paden die momenteel deel uitmaken van de index. De optie -s geeft aanvullende metagegevens weer voor de bestanden in de Staging-index. Deze metagegevens zijn de modusbits, de objectnaam en het stage-nummer van de gestagede inhoud. Hier zijn we geïnteresseerd in de objectnaam, de tweede waarde (d7d77c1b04b5edd5acfc85de0b592449e5303770). Dit is een standaard SHA-1-hash voor Git-objecten. Het is een hash van de inhoud van de bestanden. De Commit-geschiedenis slaat het eigen SHA-object op voor het identificeren van pointers naar commits en refs, en de Staging-index heeft zijn eigen object-SHA's voor het bijhouden van versies van bestanden in de index.

Vervolgens promoten we het aangepaste reset_lifecycle_file naar de Staging-index.

$ git add reset_lifecycle_file 

 
$ git status 

 
On branch main Changes to be committed: 

 
(use "git reset HEAD ..." to unstage) 

 
modified: reset_lifecycle_file

Hier hebben we git add reset_lifecycle_file aangeroepen, waarmee het bestand wordt toegevoegd aan de Staging-index. Als je de git-status aanroept, wordt reset_lifecycle_file nu groen weergegeven onder 'Changes to be committed'. Het is belangrijk op te merken dat de git status geen waarheidsgetrouwe weergave is van de Staging-index. De opdrachtuitvoer van git status geeft de wijzigingen weer tussen de Commit-geschiedenis en de Staging-index. Laten we nu eens kijken naar de inhoud van de Staging-index.

$ git ls-files -s 100644 d7d77c1b04b5edd5acfc85de0b592449e5303770 0 reset_lifecycle_file

We kunnen zien dat het SHA-object voor reset_lifecycle_file is bijgewerkt van e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 naar d7d77c1b04b5edd5acfc85de0b592449e5303770.

Commit-geschiedenis


De laatste boom is de Commit-geschiedenis. De opdracht git commit voegt wijzigingen toe aan een permanente momentopname die in de Commit-geschiedenis staat. Deze momentopname bevat ook de status van de Staging-index op het moment van de commit.

$ git commit -am"update content of reset_lifecycle_file"
[main dc67808] update content of reset_lifecycle_file
1 file changed, 1 insertion(+)
$ git status
On branch main
nothing to commit, working tree clean

Hier hebben we een nieuwe commit gemaakt met het bericht 'update content of resetlifecyclefile'. De changeset is toegevoegd aan de Commit-geschiedenis. Als je nu de git-status aanroept, laat dat zien dat er in geen van de bomen wijzigingen in behandeling zijn. Bij het uitvoeren van het git log wordt de Commit-geschiedenis weergegeven. Nu we deze changeset door de drie bomen heen hebben gevolgd, kunnen we beginnen met het gebruik van git reset.

Hoe het werkt


Op het eerste gezicht lijkt het gedrag van git reset op dat van git checkout. Waar git checkout uitsluitend werkt met de HEAD ref-pointer, verplaatst git reset de HEAD ref-pointer en de huidige ref-pointer van de branch. Bekijk het volgende voorbeeld om dit gedrag beter te demonstreren:

4 knooppunten, waarbij het 'main-knooppunt' de laatste is

Dit voorbeeld toont een reeks commits op de branch main. De referentie HEAD en de branch main verwijzen momenteel naar commit d. Laten we nu git checkout b en git reset b uitvoeren en vergelijken.

git checkout b

4 knooppunten, waarvan de 'main' naar het laatste knooppunt wijst en de 'head' naar het tweede knooppunt

Met git checkout verwijst de main ref nog steeds naar d. De HEAD ref is verplaatst en wijst nu naar commit b. De repo bevindt zich nu in een status 'detached HEAD'.

git reset b

2 sets van 2 knooppunten, waarvan de 'head,main' naar de tweede van de eerste set wijst

Ter vergelijking: git reset, verplaatst zowel de HEAD als de branch-refs naar de opgegeven commit.

Naast het bijwerken van de ref-pointers van de commit, zal git reset de status van de drie bomen aanpassen. De ref-pointer wordt altijd gewijzigd en het is een update van de derde boom, de Commit-boom. De opdrachtregelargumenten --soft, --mixed en --hard sturen hoe je de Staging-index- en de Werkmap-bomen kunt aanpassen.

Belangrijkste opties


De standaardaanroep van git reset heeft impliciete argumenten van --mixed en HEAD. Dit betekent dat het uitvoeren van een git reset gelijk is aan het uitvoeren van git reset --mixed HEAD. In deze vorm is HEAD de opgegeven commit. In plaats van HEAD kan elke Git SHA-1 commit-hash worden gebruikt.

diagram van het scope van git resets

'--hard


Dit is de meest directe, GEVAARLIJKE en meest gebruikte optie. Indien --hard is doorgevoerd, dan worden de ref-pointers van de Commit-geschiedenis bijgewerkt naar de opgegeven commit. Vervolgens worden de Staging-index en de Werkmap opnieuw ingesteld zodat ze overeenkomen met die van de opgegeven commit. Alle wijzigingen in de Staging-index en de Werkmap die eerder in behandeling waren, worden opnieuw ingesteld op basis van de status van de Commit-boom. Dit betekent dat al het werk dat nog in behandeling was in de Staging-index en Werkmap verloren gaat.

Om dit aan te tonen, gaan we verder met de drie boomvoorbeelden van repo die we eerder hebben ingesteld. Laten we eerst enkele wijzigingen aanbrengen in de repo. Voer de volgende opdrachten uit in de voorbeeldrepo:

$ echo 'new file content' > new_file
$ git add new_file
$ echo 'changed content' >> reset_lifecycle_file

Met deze opdrachten is er een nieuw bestand met de naam new_file gemaakt en aan de repo toegevoegd. Daarnaast wordt de inhoud van reset_lifecycle_file aangepast. Nu deze wijzigingen zijn doorgevoerd, laten we nu de status van de repo bekijken met behulp van de git status.

$ git status
On branch main
Changes to be committed:
   (use "git reset HEAD ..." to unstage)

new file: new_file

Changes not staged for commit:
   (use "git add ..." to update what will be committed)
   (use "git checkout -- ..." to discard changes in working directory)

modified: reset_lifecycle_file

Hier hebben we git add reset_lifecycle_file aangeroepen, waarmee het bestand wordt toegevoegd aan de Staging-index. Als je de git-status aanroept, wordt reset_lifecycle_file nu groen weergegeven onder 'Changes to be committed'. Het is belangrijk op te merken dat de git status geen waarheidsgetrouwe weergave is van de Staging-index. De opdrachtuitvoer van git status geeft de wijzigingen weer tussen de Commit-geschiedenis en de Staging-index. Laten we nu eens kijken naar de inhoud van de Staging-index.

$ git ls-files -s
100644 8e66654a5477b1bf4765946147c49509a431f963 0 new_file
100644 d7d77c1b04b5edd5acfc85de0b592449e5303770 0 reset_lifecycle_file

We kunnen zien dat new_file aan de index is toegevoegd. We hebben reset_lifecycle_file bijgewerkt, maar de Staging-index SHA (d7d77c1b04b5edd5acfc85de0b592449e5303770) blijft ongewijzigd. Dit gedrag wordt verwacht omdat git add niet wordt gebruikt om deze wijzigingen naar de Staging-index te promoten. Deze wijzigingen zijn te vinden in de Werkmap.

Laten we nu git reset --hard uitvoeren en de nieuwe status van de repository onderzoeken.

$ git reset --hard
HEAD is now at dc67808 update content of reset_lifecycle_file
$ git status
On branch main
nothing to commit, working tree clean
$ git ls-files -s
100644 d7d77c1b04b5edd5acfc85de0b592449e5303770 0 reset_lifecycle_file

Hier hebben we een 'hard reset' uitgevoerd met de optie --hard. Git geeft de output weer die aangeeft dat HEAD naar de laatste commit, dc67808, verwijst. Vervolgens controleren we de status van de repo met de git status. Git geeft aan dat er geen wijzigingen in behandeling zijn. We bekijken ook de status van de Staging-index en bekijken we of deze is teruggezet naar een punt voordat new_file werd toegevoegd. Onze aanpassingen aan reset_lifecycle_file en de toevoeging van new_file zijn vernietigd. Dit gegevensverlies kan niet ongedaan worden gemaakt. Dit is van cruciaal belang om in gedachten te houden.

'--mixed


Dit is de standaard bedieningsmodus. De ref-pointers zijn bijgewerkt. De Staging-index wordt teruggezet naar de status van de opgegeven commit. Alle wijzigingen die ongedaan zijn gemaakt in de Staging-index worden verplaatst naar de Werkmap. Laten we doorgaan.

$ echo 'new file content' > new_file
$ git add new_file
$ echo 'append content' >> reset_lifecycle_file
$ git add reset_lifecycle_file
$ git status
On branch main
Changes to be committed:
    (use "git reset HEAD ..." to unstage)

new file: new_file
modified: reset_lifecycle_file


$ git ls-files -s
100644 8e66654a5477b1bf4765946147c49509a431f963 0 new_file
100644 7ab362db063f9e9426901092c00a3394b4bec53d 0 reset_lifecycle_file

In het bovenstaande voorbeeld hebben we enkele wijzigingen aangebracht in de repository. Nogmaals, we hebben een new_file toegevoegd en de inhoud van reset_lifecycle_file aangepast. Deze wijzigingen worden vervolgens toegepast op de Staging-index met git add. Nu de repo zich in deze toestand bevindt, zullen we nu de reset uitvoeren.

$ git reset --mixed
$ git status
On branch main
Changes not staged for commit:
    (use "git add ..." to update what will be committed)
    (use "git checkout -- ..." to discard changes in working directory)

modified: reset_lifecycle_file

Untracked files:
    (use "git add ..." to include in what will be committed)

new_file


no changes added to commit (use "git add" and/or "git commit -a")
$ git ls-files -s
100644 d7d77c1b04b5edd5acfc85de0b592449e5303770 0 reset_lifecycle_file

Hier hebben we een 'mixed reset' uitgevoerd. Nogmaals, --mixed is de standaardmodus en hetzelfde effect als het uitvoeren van een git reset. Als we de output van git status en git ls-files onderzoeken, blijkt dat de Staging-index is teruggezet naar een toestand waarin reset_lifecycle_file het enige bestand in de index is. De object-SHA voor reset_lifecycle_file is teruggezet naar de vorige versie.

Het belangrijkste om op te merken is dat de git status ons laat zien dat er wijzigingen zijn in reset_lifecycle_file en dat er een bestand is dat niet wordt bijgehouden: new_file. Dit is het expliciete gedrag van --mixed. De Staging-index is opnieuw ingesteld en de openstaande wijzigingen zijn verplaatst naar de Werkmap. Vergelijk dit eens met de --hard reset waarbij de Staging-index werd gereset en ook de Werkmap werd gereset, waardoor deze updates verloren gingen.

'--soft


Wanneer het argument --soft wordt doorgegeven, worden de ref-pointers bijgewerkt en stopt de reset daar. De Staging-index en de Werkmap blijven onaangeroerd. Dit gedrag kan moeilijk duidelijk aan te tonen zijn. Laten we doorgaan met ons demo-repo en het klaarmaken voor een soft reset.

$ git add reset_lifecycle_file 

 
$ git ls-files -s 

 
100644 67cc52710639e5da6b515416fd779d0741e3762e 0 reset_lifecycle_file 

 
$ git status 

 
On branch main

 
Changes to be committed: 

 
(use "git reset HEAD ..." to unstage) 

 
modified: reset_lifecycle_file 

 
Untracked files: 

 
(use "git add ..." to include in what will be committed) 

 
new_file

Ook hier hebben we git add gebruikt om het aangepaste reset_lifecycle_file te te promoten naar de Staging-index. We bevestigen dat de index is bijgewerkt met de output van git ls-files. De output van de git status geeft nu 'Changes to be committed' weer in het groen. De new_file uit onze vorige voorbeelden zweeft in de Werkmap rond als een niet-getraceerd bestand. Laten we snel rm new_file uitvoeren om het bestand te verwijderen, aangezien we het niet nodig hebben voor de volgende voorbeelden.

Nu de repository zich in deze toestand bevindt, voeren we een soft reset uit.

$ git reset --soft
$ git status
On branch main
Changes to be committed:
    (use "git reset HEAD ..." to unstage)

modified: reset_lifecycle_file
$ git ls-files -s
100644 67cc52710639e5da6b515416fd779d0741e3762e 0 reset_lifecycle_file

We hebben een 'soft reset' uitgevoerd. Als we de repostatus onderzoeken met git status en git ls-files, blijkt dat er niets is veranderd. Dit is verwacht gedrag. Een soft reset zal enkel de Commit-geschiedenis resetten. Git reset wordt standaard aangeroepen met HEAD als doel-commit. Aangezien onze Commit-geschiedenis al op HEAD stond en we impliciet zijn teruggezet naar HEAD, is er eigenlijk niets gebeurd.

Voor een beter begrip en een beter gebruik van --soft hebben we een doel-commit nodig die niet HEAD is. Er staat reset_lifecycle_file klaar in de Staging-index. Laten we een nieuwe commit aanmaken.

$ git commit -m"prepend content to reset_lifecycle_file"

Op dit moment zou onze repo drie commits moeten hebben. We gaan terug in de tijd naar de eerste commit. Hiervoor hebben we de ID van de eerste commit nodig. Deze kan gevonden worden door de output van git log te bekijken.

$ git log
commit 62e793f6941c7e0d4ad9a1345a175fe8f45cb9df
Author: bitbucket 
Date: Fri Dec 1 15:03:07 2017 -0800
prepend content to reset_lifecycle_file

commit dc67808a6da9f0dec51ed16d3d8823f28e1a72a
Author: bitbucket 
Date: Fri Dec 1 10:21:57 2017 -0800

update content of reset_lifecycle_file

commit 780411da3b47117270c0e3a8d5dcfd11d28d04a4

Author: bitbucket 
Date: Thu Nov 30 16:50:39 2017 -0800

initial commit

Houd er rekening mee dat ID's van Commit-geschiedenis voor elk systeem uniek zijn. Dit betekent dat de commit-ID's in dit voorbeeld anders zijn dan wat je op je computer ziet. De commit-ID waarin we geïnteresseerd zijn voor dit voorbeeld is 780411da3b47117270c0e3a8d5dcfd11d28d04a4. Dit is de ID die overeenkomt met de 'initiële commit'. Zodra we deze ID hebben gevonden, gebruiken we deze als doelwit voor onze soft reset.

Voordat we terug in de tijd gaan, moeten we eerst de huidige status van de repo controleren.

$ git status && git ls-files -s
On branch main
nothing to commit, working tree clean
100644 67cc52710639e5da6b515416fd779d0741e3762e 0 reset_lifecycle_file

Hier voeren we een combinatieopdracht uit van git status en git ls-files -s. Dit laat ons zien dat er nog wijzigingen in de repo zijn, en reset_lifecycle_file in de Staging-index heeft een versie van 67cc52710639e5da6b515416fd779d0741e3762e. Laten we met dit in gedachten een soft reset uitvoeren terug naar onze eerste commit.

$git reset --soft 780411da3b47117270c0e3a8d5dcfd11d28d04a4
$ git status && git ls-files -s
On branch main
Changes to be committed:
    (use "git reset HEAD ..." to unstage)

modified: reset_lifecycle_file
100644 67cc52710639e5da6b515416fd779d0741e3762e 0 reset_lifecycle_file

De bovenstaande code voert een 'soft reset' uit en roept ook een combinatie van de opdrachtengit status en git ls-files aan, waarmee de status van de repository wordt weergegeven. We kunnen de output van de repostatus bekijken en enkele interessante observaties noteren. Ten eerste geeft de git status aan dat er wijzigingen zijn in reset_lifecycle_file en worden deze gemarkeerd om aan te geven dat het om wijzigingen gaat die gestaged zijn voor de volgende commit. Ten tweede geeft de input van git ls-files aan dat de Staging-index niet is gewijzigd en blijft de SHA 67cc52710639e5da6b515416fd779d0741e3762e behouden die we eerder hadden.

Laten we de git log bekijken om verder te verduidelijken wat er is gebeurd tijdens deze reset:

$ git log commit 780411da3b47117270c0e3a8d5dcfd11d28d04a4 Author: bitbucket  Date: Thu Nov 30 16:50:39 2017 -0800 initial commit

De output van de log toont nu aan dat er één commit in de Commit-geschiedenis is. Dit helpt om duidelijk te maken wat --soft heeft gedaan. Zoals bij alle aanroepen van git reset, wordt als eerste actie van de reset de commit-boom opnieuw ingesteld. Onze vorige voorbeelden, met --hard en --mixed, waren beide tegen de HEAD en hebben de Commit-boom niet terug in de tijd verplaatst. Bij een soft reset is dit alles wat er gebeurt.

Dit kan dan verwarrend zijn waarom de git status aangeeft dat er gewijzigde bestanden zijn. --soft heeft niets te maken met de Staging-index, dus de updates van onze Staging-index volgden ons terug in de tijd tijdens de commit-geschiedenis. Dit kan bevestigd worden door de output van git ls-files -s, waaruit blijkt dat de SHA voor reset_lifecycle_file ongewijzigd is. Ter herinnering: de git status geeft niet de toestand van 'de drie bomen' weer, maar het toont in wezen een verschil tussen de drie bomen. In dit geval wordt weergegeven dat de Staging-index voorloopt op de wijzigingen in de Commit-geschiedenis, alsof we ze al gestaged hebben.

Resetten versus terugzetten


Als git revert een 'veilige' manier is om wijzigingen ongedaan te maken, kun je git reset als de gevaarlijke methode beschouwen. Er is een werkelijk risico om werk te verliezen met git reset. Git reset zal nooit een commit verwijderen, maar commits kunnen 'verweesd' worden, wat betekent dat er geen directe toegang is vanaf een ref. Deze verweesde commits kunnen meestal gevonden en hersteld worden met git reflog. Git zal alle verweesde commits permanent verwijderen nadat de interne vuilnisophaler is gestart. Git is standaard geconfigureerd om de vuilnisophaler elke 30 dagen te laten draaien. Commit-geschiedenis is een van de 'drie git-bomen', de andere twee, Staging-index en Werkmap, zijn niet zo permanent als Commits. Wees voorzichtig wanneer je deze tool gebruikt, want het is een van de weinige Git-opdrachten waarmee je mogelijk werk verliest.

Waar terugzetten bedoeld is om een openbare commit veilig ongedaan te maken, is git reset ontworpen om lokale wijzigingen in de Staging-index en Werkmap ongedaan te maken. Vanwege hun verschillende doelen zijn de twee opdrachten verschillend geïmplementeerd: bij resetten wordt een changeset volledig verwijderd, terwijl bij terugdraaien de oorspronkelijke changeset behouden blijft en een nieuwe commit wordt gebruikt om het ongedaan maken toe te passen.

Reset openbare geschiedenis niet


Je moet git reset nooit gebruiken als momentopnamen na naar een openbare repository zijn gepusht. Na het publiceren van een commit moet je ervan uitgaan dat andere ontwikkelaars ervan afhankelijk zijn.

Het verwijderen van een commit die andere teamleden voortdurend hebben ontwikkeld, levert ernstige problemen op voor de samenwerking. Als ze proberen te synchroniseren met je repository, zal het lijken alsof een deel van de projectgeschiedenis abrupt is verdwenen. De onderstaande volgorde laat zien wat er gebeurt als je probeert een openbare commit opnieuw in te stellen. De origin/main-branch is de versie van de centrale repository van je lokale main-branch.

Diagram van wat er gebeurt na de reset: wat resulteert in twee main-branches

Zodra je nieuwe commits toevoegt na de reset, zal Git denken dat je lokale geschiedenis anders is dan die van origin/main, en de merge-commit die nodig is om je repository's te synchroniseren, zal je team waarschijnlijk verwarren en frustreren.

Het punt is, zorg ervoor dat je git reset <commit> gebruikt voor een lokaal experiment dat fout is gegaan, niet voor gepubliceerde wijzigingen. Als je een openbare commit moet herstellen, is de opdracht git revert speciaal voor dit doeleinde ontworpen.

Voorbeelden


git reset <file>

Verwijder het opgegeven bestand uit het staging-gebied, maar laat de werkmap ongewijzigd. Hiermee wordt het stagen van een bestand ongedaan gemaakt zonder eventuele wijzigingen te overschrijven.

git reset

Stel het testgebied opnieuw in zodat het overeenkomt met de meest recente commit, maar laat de werkmap ongewijzigd. Hiermee worden alle bestanden ongestaged zonder wijzigingen te overschrijven, zodat je de gestagede momentopname helemaal opnieuw kunt samenstellen.

git reset --hard

Reset het staging-gebied en de werkmap om overeen te komen met de meest recente commit. Naast het ongedaan maken van wijzigingen, geeft de markering --hard aan Git de opdracht om ook alle wijzigingen in de werkmap te overschrijven. Anders gezegd: hiermee worden alle vrijblijvende veranderingen vernietigd, dus zorg ervoor dat je echt je lokale ontwikkelingen weg wilt gooien voordat je het gebruikt.

git reset  

Verplaats de huidige branchtip naar achteren om een commit te maken, stel het staging-gebied opnieuw in zodat het overeenkomt, maar laat de werkmap met rust. Alle wijzigingen die sinds de <commit> zijn aangebracht, bevinden zich in de werkmap, zodat je de projectgeschiedenis opnieuw kunt committen met behulp van schonere, meer atomische momentopnamen.

git reset --hard  

Verplaats de tip van de huidige branch naar achteren naar <commit> en reset het staging-gebied en de werkmap om overeen te komen. Hiermee worden niet alleen de wijzigingen zonder commits vernietigd, maar ook alle wijzigingen die daarna worden doorgevoerd.

Een bestand ontstagen


De opdracht git reset komt vaak voor tijdens het voorbereiden van de gestagede momentopname. In het volgende voorbeeld wordt ervan uitgegaan dat je twee bestanden hebt, genaamd hello.py en main.py, die je al hebt toegevoegd aan de repository.

# Edit both hello.py and main.py

# Stage everything in the current directory
git add .

# Realize that the changes in hello.py and main.py
# should be committed in different snapshots

# Unstage main.py
git reset main.py

# Commit only hello.py
git commit -m "Make some changes to hello.py"

# Commit main.py in a separate snapshot
git add main.py
git commit -m "Edit main.py"

Zoals je ziet helpt git reset om je commits zeer gericht te houden door je wijzigingen die niets met de volgende commit te maken hebben, te laten ontstagen.

Lokale commits verwijderen


Het volgende voorbeeld toont een meer geavanceerde usecase. Het laat zien wat er gebeurt als je al een tijdje aan een nieuw experiment werkt, maar besluit het helemaal weg te gooien nadat je een paar momentopnamen hebt gemaakt.

# Create a new file called `foo.py` and add some code to it

# Commit it to the project history
git add foo.py
git commit -m "Start developing a crazy feature"

# Edit `foo.py` again and change some other tracked files, too

# Commit another snapshot
git commit -a -m "Continue my crazy feature"

# Decide to scrap the feature and remove the associated commits
git reset --hard HEAD~2

De opdracht git reset HEAD~2 verplaatst de huidige branch met twee commits naar achteren, waardoor de twee momentopnamen die we zojuist hebben gemaakt, in feite worden verwijderd uit de projectgeschiedenis. Onthoud dat dit soort resets alleen mogen worden gebruikt voor niet-gepubliceerde commits. Voer bovenstaande bewerking nooit uit als je je commits al naar een gedeelde repository hebt gepusht.

Samenvatting


Git reset is een krachtige opdracht die wordt gebruikt om lokale wijzigingen in de status van een Git-repo ongedaan te maken. Git reset werkt met 'De drie bomen van Git'. Deze bomen zijn de Commit-geschiedenis (HEAD), de Staging-index en de Werkmap. Er zijn drie opdrachtregelopties die overeenkomen met de drie bomen. De opties --soft, --mixed en --hard kunnen worden doorgegeven aan git reset.\

In dit artikel hebben we verschillende andere Git-opdrachten gebruikt om de resetprocessen te demonstreren. Meer informatie over deze opdrachten vind je op hun afzonderlijke pagina's op: git status, git log, git add, git checkout, git reflog, en git revert.


Deel dit artikel
Volgend onderwerp

Aanbevolen artikelen

Bookmark deze resources voor meer informatie over soorten DevOps-teams of voor voortdurende updates over DevOps bij Atlassian.

Mensen die samenwerken met een muur vol tools

Bitbucket-blog

Toelichting DevOps

DevOps-leertraject

Demo Den Feature-demo's met Atlassian-experts

Hoe Bitbucket Cloud werkt met Atlassian Open DevOps

Meld je aan voor onze DevOps-nieuwsbrief

Thank you for signing up