In een van mijn ontwikkelingsafdelingen heb ik enkele wijzigingen aangebracht in mijn codebase. Voordat ik de features waar ik aan werkte kon voltooien, moest ik mijn huidige branch omschakelen naar master om een aantal features te demonstreren. Maar door gewoon een “git checkout master” te gebruiken, bleven de wijzigingen behouden die ik ook in mijn ontwikkelingsbranch had aangebracht, waardoor een deel van de functionaliteit in master werd verbroken. Dus wat ik deed, was de wijzigingen op mijn ontwikkelingstak vastleggen met een vastleggingsbericht “tijdelijke vastlegging” en vervolgens de master afrekenen voor de demo.
Nu ik klaar ben met de demo en weer aan het werk ben aan mijn ontwikkelingsbranch, wil ik de “tijdelijke commit” die ik heb gemaakt verwijderen, terwijl ik de wijzigingen die ik heb aangebracht behoudt. Is dat mogelijk?
Antwoord 1, autoriteit 100%
Het is zo simpel als dit:
git reset HEAD^
Opmerking: sommige shells behandelen ^
als een speciaal teken (bijvoorbeeld sommige Windows-shells of ZSH met globbing ingeschakeld), dus in die gevallen moet u wellicht "HEAD^"
citeren.
git reset
zonder een --hard
of --soft
verplaatst je HEAD
om naar de gespecificeerde commit, zonder bestanden te wijzigen. HEAD^
verwijst naar de (eerste) parent-commit van je huidige commit, wat in jouw geval de commit is vóór de tijdelijke.
Merk op dat een andere optie is om gewoon door te gaan, en dan op het volgende vastleggingspunt in plaats daarvan uit te voeren:
git commit --amend [-m … etc]
die in plaats daarvan de meest recente commit bewerkt, met hetzelfde effect als hierboven.
Merk op dat dit (zoals bij bijna elk git-antwoord) problemen kan veroorzaken als je de slechte commit al naar een plek hebt gepusht waar iemand anders het vandaan heeft gehaald. Probeer dat te vermijden
Antwoord 2, autoriteit 11%
Er zijn twee manieren om dit aan te pakken. Wat gemakkelijker is, hangt af van uw situatie
Resetten
Als de commit die je kwijt wilt de laatste commit was, en je hebt geen extra werk gedaan, kun je gewoon git-reset
gebruiken
git reset HEAD^
Brengt je branch terug naar de commit net voor je huidige HEAD. Het verandert echter niet echt de bestanden in uw werkboom. Als gevolg hiervan worden de wijzigingen die in die commit waren, weergegeven als gewijzigd – het is als een ‘uncommit’-commando. In feite heb ik een alias om precies dat te doen.
git config --global alias.uncommit 'reset HEAD^'
Dan kun je in de toekomst gewoon git uncommit
gebruiken om een back-up te maken van één commit.
Plakken
Het platdrukken van een commit betekent het combineren van twee of meer commits in één. Ik doe dit best vaak. In jouw geval heb je een half voltooide functie vastgelegd, en dan zou je het afmaken en opnieuw vastleggen met het juiste, permanente vastleggingsbericht.
git rebase -i <ref>
Ik zeg hierboven omdat ik duidelijk wil maken dat dit een willekeurig aantal commits kan zijn. Voer git log
uit en zoek de commit die je wilt verwijderen, kopieer de SHA1 en gebruik deze in plaats van <ref>
. Git brengt je naar de interactieve rebase-modus. Het toont alle commits tussen je huidige status en wat je ook in plaats van <ref>
plaatst. Dus als <ref>
10 commits geleden is, zal het je alle 10 commits tonen.
Voor elke commit staat het woord pick
. Zoek de commit waar je vanaf wilt en verander deze van pick
in fixup
of squash
. Door fixup
te gebruiken, wordt dat commit-bericht gewoon weggegooid en worden de wijzigingen samengevoegd met zijn directe voorganger in de lijst. Het sleutelwoord squash
doet hetzelfde, maar stelt je in staat om het commit-bericht van de nieuw gecombineerde commit te bewerken.
Merk op dat de commits opnieuw worden vastgelegd in de volgorde waarin ze in de lijst verschijnen wanneer je de editor verlaat. Dus als je een tijdelijke commit hebt gemaakt, dan ander werk aan dezelfde branch hebt gedaan en de functie in een latere commit hebt voltooid, dan zou het gebruik van rebase je in staat stellen om de commits opnieuw te sorteren en ze te pletten.
WAARSCHUWING:
Rebasen wijzigt de geschiedenis – doe dit NIET met commits die je al met andere ontwikkelaars hebt gedeeld.
Opbergen
Om dit probleem in de toekomst te voorkomen, kunt u overwegen git stash
te gebruiken om tijdelijk niet-toegewezen werk op te slaan.
git stash save 'some message'
Hiermee worden uw huidige wijzigingen aan de zijkant in uw stashlijst opgeslagen. Hierboven staat de meest expliciete versie van het stash-commando, waarbij een opmerking mogelijk is om te beschrijven wat u aan het opbergen bent. Je kunt ook gewoon git stash
uitvoeren en niets anders, maar er wordt geen bericht opgeslagen.
Je kunt door je stashlijst bladeren met…
git stash list
Dit laat je al je stash zien, op welke takken ze zijn gedaan, en het bericht en aan het begin van elke regel, en de identifier voor die stash die er zo uitziet stash@{#}
waarbij # zijn positie is in de reeks stashes.
Om een stash te herstellen (wat op elke branch kan worden gedaan, ongeacht waar de stash oorspronkelijk is gemaakt), voer je gewoon uit…
git stash apply stash@{#}
Nogmaals, daar is # de positie in de reeks van stashes. Als de stash die u wilt herstellen in de positie 0
– dat wil zeggen, als het de meest recente stash was. Dan kunt u gewoon de opdracht uitvoeren zonder de stashpositie op te geven, Git neemt aan dat u de laatste bedoelt: git stash apply
.
Dus, bijvoorbeeld als ik vind dat ik aan de verkeerde tak werkt – mag ik de volgende volgorde van opdrachten uitvoeren.
git stash
git checkout <correct_branch>
git stash apply
In uw geval bent u een beetje meer door takken verplaatst, maar hetzelfde idee is nog steeds van toepassing.
Ik hoop dat dit helpt.
Antwoord 3, Autoriteit 8%
Ik denk dat u dit zoekt
git reset --soft HEAD~1
Het maakt de meest recente commit ongedaan tijdens het houden van de veranderingen die in die commit op basis worden gemaakt.
Antwoord 4, Autoriteit 4%
Ja, u kunt uw commit verwijderen zonder de wijzigingen te verwijderen:
git reset @~
Antwoord 5, Autoriteit 2%
U bent op zoek naar een git reset HEAD^ --soft
of git reset HEAD^ --mixed
.
Er zijn 3 modi naar de opdracht Reset zoals vermeld in de DOCS :
git reset HEAD^ --soft
Maak de git commit
ongedaan maken. Wijzigingen bestaan nog steeds in de werkboom (de projectmap) + de index (- gesteld)
git reset HEAD^ --mixed
Ongedaan maken git commit
+ git add
. Veranderingen bestaan nog steeds in de werkboom
git reset HEAD^ --hard
Zoals u deze wijzigingen nooit hebt aangebracht in de codebase. Veranderingen zijn verdwenen uit de werkboom.
Antwoord 6
2020 eenvoudige manier:
git reset <commit_hash>
(de plegen hash van de laatste commit die u wilt behouden).
Als de commit werd geduwd, kunt u dan doen:
git push -f
U bewaart de nu niet-gecommitteerde wijzigingen lokaal
Antwoord 7
In mijn geval duwde ik al naar de repo. Ouch!
U kunt een specifieke commit terugdraaien terwijl u de wijzigingen in uw lokale bestanden bewaart door:
git revert -n <sha>
Op deze manier was ik in staat om de veranderingen te behouden die ik nodig hadden en een commit die al was geduwd.
Antwoord 8
Voor degenen die ZSH gebruiken, moet u het volgende gebruiken:
git reset --soft HEAD\^
hier uitgelegd: https://github.com/robbyrussell/oh-my -zsh / problemen / 449
Indien de URL dood wordt, is het belangrijke deel:
Ontsnap aan de ^ in uw opdracht
U kunt alternatief kunnen gebruiken, zodat u er telkens niet hoeft te ontsnappen.
Antwoord 9
Git 2.9 (precies 2.9.2.Windows.1) gebruiken
git reset HEAD^
aanwijzingen voor meer; Weet je niet zeker wat hier wordt verwacht. Raadpleeg hieronder screenshot
vond andere oplossing git reset HEAD~#numberOfCommits
Gebruiken die we kunnen kiezen om het aantal lokale commits te selecteren dat u wilt resetten door uw wijzigingen intact te houden. Vandaar dat we een kans krijgen om alle lokale commits weg te gooien, evenals een beperkt aantal lokale commits.
Verwijs hieronder screenshots met git reset HEAD~1
in actie:
Antwoord 10
Nog een manier om het te doen.
Voeg commit toe aan de bovenkant van tijdelijke commit en Doe dan:
git rebase -i
Om twee commits in één te samenvoegen (opdracht opent het tekstbestand met expliciete instructies, bewerkt het).
Antwoord 11
In sommige gevallen wil ik alleen de wijzigingen op specifieke bestanden ongedaan maken over de eerste commit om ze toe te voegen aan een tweede commit en een schoner git-logboek hebben.
In dit geval is wat ik doe het volgende:
git checkout HEAD~1 <path_to_file_to_put_in_different_commit>
git add -u
git commit --amend --no-edit
git checkout HEAD@{1} <path_to_file_to_put_in_different_commit>
git commit -m "This is the new commit"
Natuurlijk werkt dit goed, zelfs in het midden van een rebase -i
met een bewerkingsoptie op de committeel om te splitsen.