Ik was wat aan het werk in mijn repository en merkte dat een bestand lokale wijzigingen had. Ik wilde ze niet meer, dus ik heb het bestand verwijderd, denkend dat ik gewoon een nieuwe kopie kan afrekenen. Ik wilde het Git-equivalent van
. doen
svn up .
Het gebruik van git pull
leek niet te werken. Wat willekeurig zoeken leidde me naar een site waar iemand aanraadde om te doen
git checkout HEAD^ src/
(src
is de map met het verwijderde bestand).
Nu kom ik erachter dat ik een losstaand hoofd heb. Ik heb geen idee wat dat is. Hoe kan ik het ongedaan maken?
Antwoord 1, autoriteit 100%
Detached head betekent dat je niet langer op een branch zit, je hebt een enkele commit in de geschiedenis uitgecheckt (in dit geval de commit voorafgaand aan HEAD, d.w.z. HEAD^).
Als u uw wijzigingen wilt verwijderendie zijn gekoppeld aan de losgemaakte HEAD
Je hoeft alleen af te rekenen in het filiaal waar je zat, bijvoorbeeld
git checkout master
De volgende keer dat u een bestand hebt gewijzigd en het wilt herstellen naar de staat waarin het zich in de index bevindt, moet u het bestand niet eerst verwijderen, maar gewoon doen
git checkout -- path/to/foo
Dit zal het bestand foo herstellen naar de staat waarin het zich in de index bevindt.
Als u uw wijzigingen behoudendie zijn gekoppeld aan de losgemaakte HEAD
- Voer
git branch tmp
uit – dit slaat je wijzigingen op in een nieuwe branch genaamdtmp
. - Voer
git checkout master
- Als je de wijzigingen die je hebt gemaakt in
master
wilt opnemen, voer jegit merge tmp
uit vanuit de branchmaster
. Je zou in demaster
branch moeten zijn na het uitvoeren vangit checkout master
.
uit
Antwoord 2, autoriteit 21%
Als je bestanden hebt gewijzigd die je niet wilt verliezen, kun je ze pushen. Ik heb ze in de detached-modus vastgelegd en daarna kun je naar een tijdelijke branch gaan om later in master te integreren.
git commit -m "....."
git branch my-temporary-work
git checkout master
git merge my-temporary-work
Geëxtraheerd uit:
Wat te doen met commit gemaakt in een vrijstaande kop
Antwoord 3, autoriteit 7%
Een oplossing zonder een tijdelijke vestiging te maken.
Hoe u de losgemaakte HEAD-status kunt afsluiten (“repareren”) wanneer u al iets in deze modus hebt gewijzigden, optioneel, uw wijzigingen wilt opslaan:
-
Voeg wijzigingen door die u wilt behouden.Als u een van de wijzigingen die u in de vrijstaande HEAD-status hebt aangebracht, wilt overnemen, moet u ze vastleggen. Vind ik leuk:
git commit -a -m "your commit message"
-
Wijzigingen negeren die u niet wilt behouden.De harde reset verwijdert alle niet-vastgelegde wijzigingen die u in de ontkoppelde HEAD-status heeft aangebracht:
git reset --hard
(Zonder dit zou stap 3 mislukken, klagen over gewijzigde niet-vastgelegde bestanden in de losgemaakte HEAD.)
-
Bekijk je filiaal.Verlaat de vrijstaande HEAD-status door het filiaal waar je eerder aan hebt gewerkt te bekijken, bijvoorbeeld:
git checkout master
-
Neem je commits over.Je kunt nu de commits die je hebt gemaakt in de vrijstaande HEAD-status overnemen door cherry-picking, zoals getoond in mijn antwoord op een andere vraag.
git reflog git cherry-pick <hash1> <hash2> <hash3> …
Antwoord 4, autoriteit 6%
Vrijstaande kop betekent:
- Je zit niet meer op een filiaal,
- Je hebt een enkele commit in de geschiedenis uitgecheckt
Als je geen wijzigingen hebt:je kunt overschakelen naar master door de volgende opdracht toe te passen
git checkout master
Als u wijzigingen heeft die u wilt behouden:
In het geval van een ontkoppelde HEAD, werken commits zoals normaal, behalve dat geen benoemde branch wordt bijgewerkt. Om de master branch bijgewerkt te krijgen met je vastgelegde wijzigingen, maak je een tijdelijke branch waar je bent (op deze manier heeft de tijdelijke branch alle de vastgelegde wijzigingen die je hebt aangebracht in de ontkoppelde HEAD), schakel dan over naar de master-branch en merge de tijdelijke branch met de master.
git branch temp
git checkout master
git merge temp
Antwoord 5, autoriteit 3%
HEAD is een pointer, en het wijst — direct of indirect— naar een bepaalde commit:
Bijgevoegd HEAD betekent dat het is gekoppeld aan een tak(d.w.z. het wijstnaar een tak).
DetachedHEAD betekent dat het nietis gekoppeld aan een branch, d.w.z. het verwijst directnaar een commit.
Met andere woorden:
- Als het verwijst naar een commit direct, is de HEAD losgemaakt.
- Als het indirectnaar een commit wijst (dwz het verwijst naar een branch, die op zijn beurt naar een commit wijst), is de HEAD bijgevoegd.
Laten we, om situaties met bevestigde/losgemaakte HEAD beter te begrijpen, de stappen laten zien die leiden naar het viertal afbeeldingen hierboven.
We beginnen met dezelfde staat van de repository (afbeeldingen in alle kwadranten zijn hetzelfde):
Nu willen we git checkout
uitvoeren — met verschillende doelen in de individuele afbeeldingen (commando’s erboven worden gedimd weergegeven om te benadrukken dat we alleen die gaantoepassen commando’s):
Dit is de situatie nahet uitvoeren van deze commando’s:
Zoals je kunt zien, wijst de HEAD naar het doelvan het git checkout
commando — naar een tak(eerste 3 afbeeldingen van de quadruplet), of (direct) aan een commit(de laatste afbeelding van de quadruplet).
De inhoud van de werkdirectory wordt ook gewijzigd om in overeenstemming te zijn met de juiste commit (snapshot), d.w.z. met de commit die (direct of indirect) door de HEAD wordt verwezen.
Dus nu bevinden we ons in dezelfde situatie als aan het begin van dit antwoord:
Antwoord 6, autoriteit 3%
Dit is wat ik net deed nadat ik me realiseerde dat ik een afstandelijk hoofd had en al enkele wijzigingen had aangebracht.
Ik heb de wijzigingen doorgevoerd.
$ git commit -m "..."
[detached HEAD 1fe56ad] ...
Ik herinnerde me de hash (1fe56ad) van de commit. Toen heb ik het filiaal bekeken waar ik had moeten zijn.
$ git checkout master
Switched to branch 'master'
Eindelijk heb ik de wijzigingen van de commit toegepast op de branch.
$ git cherry-pick 1fe56ad
[master 0b05f1e] ...
Ik denk dat dit een beetje makkelijker is dan het maken van een tijdelijke branch.
Antwoord 7, autoriteit 3%
Als je wijzigingen hebt aangebracht en je realiseert je dat je op een afstandelijk hoofd zit, kun je het volgende doen: stash -> kassa-master -> stash pop:
git stash
git checkout master # Fix the detached head state
git stash pop # Or for extra safety use 'stash apply' then later
# after fixing everything do 'stash drop'
Je hebt je niet-vastgelegde wijzigingen en je normale “bijgevoegde” HEAD, alsof er niets is gebeurd.
Antwoord 8, autoriteit 2%
Als je een specifieke commit uitcheckt in git
, kom je terecht in een detached headstaat…dat wil zeggen, je werkkopie weerspiegelt niet langer de staat van een benoemde referentie (zoals “master”). Dit is handig om de vroegere staat van de repository te onderzoeken, maar niet wat u wilt als u daadwerkelijk probeert wijzigingen ongedaan te maken.
Als je wijzigingen hebt aangebracht in een bepaald bestand en je wilt ze gewoon weggooien, kun je de opdracht checkout
als volgt gebruiken:
git checkout myfile
Hiermee worden alle niet-vastgelegde wijzigingen genegeerd en wordt het bestand teruggezet naar de staat die het in de head van uw huidige branch heeft. Als je wijzigingen wilt negeren die je al hebt vastgelegd, kun je de opdracht reset
gebruiken. Dit zal bijvoorbeeld de repository resetten naar de staat van de vorige commit, waarbij eventuele volgende wijzigingen worden genegeerd:
git reset --hard HEAD^
Als je de repository echter met andere mensen deelt, kan een git reset
storend werken (omdat het een deel van de geschiedenis van de repository wist). Als je al wijzigingen met andere mensen hebt gedeeld, wil je over het algemeen in plaats daarvan naar git revert
kijken, dat een “anticommit” genereert — dat wil zeggen, het creëert een nieuwe commit die de wijzigingen in “ongedaan maakt”. vraag.
Het Git Bookbevat meer details.
Antwoord 9
Sinds “detached head state” je op een tijdelijke branch heeft, gebruik je gewoon git checkout -
waarmee je op de laatste branch waar je was.
Antwoord 10
je hebt waarschijnlijk git reset --hard origin/your-branch
gedaan.
Probeer gewoon git checkout your-branch
Antwoord 11
Om het antwoord van @Philippe Gerber verder te verduidelijken, hier is het:
Voor cherry-pick
is in dit geval een git checkout master
nodig. Verder is het alleen nodig met een commit
in detached head
.
Antwoord 12
Detached head betekent dat je je branch niet goed hebt uitgecheckt of dat je net een enkele commit hebt uitgecheckt.
Als u een dergelijk probleem tegenkomt, verbergtdan eerst uw lokale wijzigingen, zodat u uw wijzigingen niet kwijtraakt.
Daarna… reken je gewenste branch af met het commando:
Stel dat je een filiaal MyOriginalBranch wilt:
git checkout -b someName origin/MyOriginalBranch
Antwoord 13
In “detached head” staan betekent dat HEAD verwijst naar een specifieke niet nader genoemde commit (in tegenstelling tot een benoemde branch) (cf: https://git-scm.com/docs/git-checkoutsectie Vrijstaande kop).
In werkelijkheid betekent dit dat je een commit hebt uitgecheckt, maar er is geen branchnaam aan gekoppeld.
Je kunt ervoor kiezen om alleen een nieuwe branch te maken die is gekoppeld aan je commit door
git branch new-branch-name
.
Hiermee kunt u uw huidige status in een nieuw filiaal opslaan.
Of u wilt misschien terugkeren naar de vorige staat en om dit te doen, moet u de vertakking selecteren die eerder werd geselecteerd door
git checkout @{ -1}
Antwoord 14
Aanvulling
Als het filiaal waarnaar u wilt terugkeren de laatste kassa was die u heeft gemaakt, kunt u eenvoudig checkout @{ -1}
gebruiken. Hiermee gaat u terug naar uw vorige kassa.
Verder kun je dit commando een alias geven met bijvoorbeeld git global --config alias.prev
zodat je gewoon git prev
hoeft in te typen om terug te gaan naar de vorige kassa.
Antwoord 15
Git heeft me verteld hoe ik het moet doen.
als je hebt getypt:
git checkout <some-commit_number>
Sla de status op
git add .
git commit -m "some message"
Dan:
git push origin HEAD:<name-of-remote-branch>
Antwoord 16
Normaal gesproken verwijst HEAD
naar een vertakking. Als het in plaats daarvan niet naar een branch wijst als het naar een commit-hash zoals 69e51
verwijst, betekent dit dat je een losgekoppelde HEAD hebt. U moet het twee een vertakking aanwijzen om het probleem op te lossen. Je kunt twee dingen doen om het op te lossen.
- git checkout other_branch // Niet mogelijk als je de code in die commit
hash
- maak een nieuwe branch aan en verwijs de commit-hash naar de nieuw aangemaakte branch.
nodig hebt
HEAD moet naar een branch wijzen, niet een commit-hash is de gouden regel.
Antwoord 17
Als je in een detached head-situatie zit en nieuwe bestanden hebt aangemaakt, zorg er dan eerst voor dat deze nieuwe bestanden aan de index worden toegevoegd, bijvoorbeeld met:
git add .
Maar als je alleen bestaande bestanden hebt gewijzigd of verwijderd, kun je tegelijkertijd (-a) toevoegen en vastleggen met een bericht (-m) via:
git commit -a -m "my adjustment message"
Dan kun je eenvoudig een nieuwe branch maken met je huidige status met:
git checkout -b new_branch_name
Je hebt een nieuwe branch en al je aanpassingen zullen in die nieuwe branch zitten. Je kunt dan doorgaan naar de afstandsbediening en/of afrekenen/trekken/samenvoegen zoals je wilt.
Antwoord 18
Toen ik me realiseerde dat ik een losstaand hoofd had zonder te weten hoe ik het voor elkaar kreeg (zoals drie commits verwijderd), ontdekte ik ook dat ik probeerde te merge
, rebase
of cherry-pick
veroorzaakte honderden samenvoegconflicten, dus nam ik een andere benadering:
-
(Ervan uitgaande dat alles is vastgelegd (werkboom is “schoon”))
-
Bewaar mijn commit-berichten:
git log > /tmp/log
-
Mijn werkboom opslaan:
mkdir /tmp/backup && cp -a all_my files_and_directories /tmp/backup
-
Terug naar
master
:git checkout master
-
Verwijder alle werkbestanden en mappen:
rm ...
-
Gebruik de back-up:
cp -a /tmp/backup/. .
-
git add
engit commit
met behulp van berichten van opgeslagen/tmp/log
, misschien herhalend met verschillende subsets van bestanden…
Het nadeel is dat je je commit-geschiedenis verliest als een bestand meerdere keren is gewijzigd sinds master
, maar uiteindelijk had ik een schone master
.
Antwoord 19
Ik wilde mijn wijzigingen behouden, dus ik los dit gewoon op door…
git add .
git commit -m "Title" -m "Description"
(so i have a commit now example: 123abc)
git checkout YOURCURRENTBRANCH
git merge 123abc
git push TOYOURCURRENTBRANCH
die voor mij werken
Antwoord 20
Deze aanpak zal mogelijk een deel van de commit-geschiedenis weggooien, maar het is gemakkelijker als het samenvoegen van de oude master-branch en de huidige status lastig is, of als je het gewoon niet erg vindt om een deel van de commit-geschiedenis.
Om de dingen gewoon te houden zoals ze zijn, zonder samen te voegen, de huidige losgekoppelde HEAD in de master branch veranderen:
- Maak handmatig een back-up van de repository, voor het geval er onverhoopt iets misgaat.
- Voeg de laatste wijzigingen door die u wilt behouden.
- Maak een tijdelijke vertakking (laten we het
detached-head
noemen) die de bestanden in hun huidige status zal bevatten:
git checkout -b detached-head
- (a) Verwijder de master-branch als je deze niet hoeft te behouden
git branch -D master
- (b) OF hernoem als je het wilt behouden
git branch -M master old-master
- Hernoem de tijdelijke vertakking naar de nieuwe hoofdvertakking
git branch -M detached-head master
Credit: aangepast van dit Medium-artikeldoor Gary Lai.
Antwoord 21
git pull origin master
werkte voor mij. Het ging gewoon om het expliciet geven van de naam op afstand en filiaal.
Antwoord 22
De vrijstaande HEAD betekent dat u zich momenteel niet op een tak bevindt. Als je je huidige wijzigingen wilt BEHOUDEN en gewoon een nieuwe branch wilt maken, dan is dit wat je doet:
git commit -m "your commit message"
git checkout -b new_branch
Daarna wil je deze nieuwe branch eventueel samenvoegen met andere branches. Altijd handig is het git “a dog”commando:
git log --all --decorate --oneline --graph
Antwoord 23
Dit werkt voor mij, het zal een nieuwe tak toewijzen voor losstaand hoofd:
git checkout new_branch_name detached_head_garbage_name
Antwoord 24
Ik zat in een vergelijkbare situatie.
Om de een of andere reden kreeg ik een losstaand hoofd – ik had commits gemaakt op hetzelfde pad als de branch waar ik dacht dat ik op zat – bijv. HEAD was een kind van de branch-tag maar om de een of andere reden was de branch-tag op een historisch commit… mogelijk omdat ik had gepusht??
Ik kon niet pushen omdat ik niet werd beschouwd als op het filiaal waar ik dacht dat ik was.
Ik wilde niets aan mijn geschiedenis veranderen of cherrypicking doen en ik had net ongeveer 8 weken aan het filiaal gewerkt, dus reset --hard
maakte me een beetje nerveus !
De oplossing was gewoon om het volgende te doen:
git branch -f myStuckBranch HEAD
git checkout myStuckBranch
Je moet afrekenen, ook al wijzen HEAD en myStuckBranch nu naar hetzelfde, omdat je nog steeds wordt beschouwd als een losstaand hoofd (niet op een tak)
Ik ben geen expert met git (ik heb voornamelijk mercurial gebruikt, wat nooit voor deze rare situatie zou zorgen) maar mijn begrip van dit commando is dat het alleen zegt
“verander myStuckBranch om naar HEAD te wijzen”.
Ik merk dat ik regelmatig dit commando gebruik om wijzigingen van master samen te voegen na het ophalen zonder mijn werkdirectory te hoeven verwisselen – anders probeert het de oude (oninteressante) versie van master te gebruiken:
git fetch
git branch -f master origin/master -- err yeah don't just ignore what's been going on remotely - eg point my master at the real master
git merge master -- merge the changes into my local branch
Het is een beetje vervelend om dat de hele tijd handmatig te moeten doen, maar het is nog steeds beter dan je werkdirectory te moeten wijzigen om alleen maar een andere branch bij te werken om de wijzigingen ervan samen te voegen.
Antwoord 25
Met git rebasekun je je HEAD naar de gewenste commit verplaatsen
Stel dat u uw filiaal in een vrijstaande staat heeft, zoals dit:
* bfcb8f9 Commit 4
* 540a123 Commit 3
* 4356d64 Commit 2
| * fecb8d2 Commit 2
|/
| * 8012f45 Commit 2x
|/
| * 6676d15 (HEAD -> master) Commit 2 --amend
|/
* 1818f91 Commit 1
De ontkoppelde kop is gemaakt door per ongeluk te rebasen, verwijzend naar een ontkoppelde commit, die eerder was gemaakt vanwege een git commit –amendcommando.
Als je je HEAD-ref naar de meest recente commit wilt verplaatsen, pas dan een rebase toe met de gewenste HASH-commit waarnaar je wilt verwijzen. In dit voorbeeld is de hash van de meest recente commit:
git rebase bfcb8f9
en hierdoor blijft je branch met zijn HEAD naar de gewenste commit (de meest recente in dit geval):
* bfcb8f9 (HEAD -> master) Commit 4
* 540a123 Commit 3
* 4356d64 Commit 2 --amend
| * fecb8d2 Commit 2
|/
| * 8012f45 Commit 2x
|/
| * 6676d15 Commit 2
|/
* 1818f91 Commit 1
Antwoord 26
In mijn geval trad de ontkoppelde HEAD-waarschuwing op toen ik dat deed
git checkout origin/some_branch
in plaats van
git checkout some_branch
Dus gewoon git checkout some_branch
loste het probleem in mijn geval op.