Jak mogę pogodzić odłączony HEAD z master / origin?

1558

Jestem nowy w gałęziach Git. Zawsze pracuję nad jednym oddziałem i zatwierdzam zmiany, a następnie okresowo wypycham do mojego zdalnego źródła.

Gdzieś ostatnio zrobiłem reset niektórych plików, aby pozbyć się ich ze stopniowania zmian, a później rebase -ipozbyłem się kilku ostatnich lokalnych zatwierdzeń. Teraz jestem w stanie, którego nie do końca rozumiem.

W moim obszarze roboczym git logpokazuje dokładnie to, czego się spodziewałem - jadę właściwym pociągiem z zobowiązaniami, których nie chciałem odejść, i nowymi, itp.

Ale właśnie przepchnąłem do zdalnego repozytorium, a co jest inne - kilka zmian, które zabiłem w bazie, zostało wypchniętych, a nowych popełnionych lokalnie nie ma.

Myślę, że „master / origin” jest odłączony od HEAD, ale nie jestem w 100% jasny, co to znaczy, jak wizualizować go za pomocą narzędzi wiersza poleceń i jak to naprawić.

Ben Zotto
źródło
Czy nacisnąłeś commits przed rebase?
manojlds 24.04.11
@manojlds: Nie jestem pewien, co masz na myśli. Wcisnąłem trochę czasu przed naliczeniem, ale nie wcześniej.
Ben Zotto
Tak jak poprzednio wypychałeś zatwierdzenia, które usunąłeś w rebase -i. Z twojej odpowiedzi nie sądzę.
manojlds 24.04.11
@manojlds: Poprawnie. Zabijałem tylko commity, które były nowsze niż ostatnie pushy. (Chociaż, jak wspomniałem, odtąd pchałem, ponieważ myślałem, że wszystko jest w porządku)
Ben Zotto
Czy możesz wyjaśnić, co I did a reset of some files to get them out of commit stagingczęściowo zrobiłeś ? przepraszam za pytania :)
manojlds

Odpowiedzi:

2521

Najpierw wyjaśnijmy, czym jest HEAD i co to znaczy, kiedy jest odłączony.

HEAD to symboliczna nazwa aktualnie wyrejestrowanego zatwierdzenia. Kiedy HEAD nie jest odłączony ( sytuacja „normalna” 1 : masz gałąź wyewidencjonowaną), HEAD faktycznie wskazuje na „ref” gałęzi, a gałąź wskazuje na zatwierdzenie. HEAD jest więc „przymocowany” do gałęzi. Po dokonaniu nowego zatwierdzenia gałąź, na którą wskazuje HEAD, jest aktualizowana, aby wskazywała na nowe zatwierdzenie. HEAD podąża automatycznie, ponieważ wskazuje tylko gałąź.

  • git symbolic-ref HEADwydajności refs/heads/master
    Oddział o nazwie „master” jest wyewidencjonowany.
  • git rev-parse refs/heads/masterwydajność 17a02998078923f2d62811326d130de991d1a95a
    Zatwierdzenie to bieżąca wskazówka lub „głowa” gałęzi master.
  • git rev-parse HEADprzynosi również 17a02998078923f2d62811326d130de991d1a95a
    To właśnie oznacza być „symbolicznym ref”. Wskazuje obiekt poprzez inne odniesienie.
    (Symboliczne odwołania zostały pierwotnie zaimplementowane jako dowiązania symboliczne, ale później zmieniono je na zwykłe pliki z dodatkową interpretacją, aby mogły być używane na platformach, które nie mają dowiązań symbolicznych).

Mamy HEADrefs/heads/master17a02998078923f2d62811326d130de991d1a95a

Kiedy HEAD jest odłączony, wskazuje bezpośrednio na zatwierdzenie - zamiast pośrednio wskazywać na jeden poprzez gałąź. Możesz myśleć o odłączonej GŁOWIE jako o nienazwanej gałęzi.

  • git symbolic-ref HEAD nie działa z fatal: ref HEAD is not a symbolic ref
  • git rev-parse HEADfeds 17a02998078923f2d62811326d130de991d1a95a
    Ponieważ nie jest to symboliczny odnośnik, musi wskazywać bezpośrednio na samo zatwierdzenie.

Mamy HEAD17a02998078923f2d62811326d130de991d1a95a

Ważną rzeczą, o której należy pamiętać przy odłączonym HEAD jest to, że jeśli zatwierdzenie, na które wskazuje, jest w inny sposób niepowiązane (żaden inny odnośnik nie może do niego dotrzeć), wtedy stanie się „wiszące”, kiedy kasujesz jakieś inne zatwierdzenie. W końcu takie zwisające zatwierdzenia zostaną przycięte w procesie wyrzucania elementów bezużytecznych (domyślnie są one przechowywane przez co najmniej 2 tygodnie i mogą być przechowywane dłużej przez odwołanie się do reflog HEAD).

1 Wykonywanie „normalnej” pracy z odłączoną GŁOWĄ jest całkowicie w porządku, wystarczy śledzić to, co robisz, aby uniknąć wyrzucania historii z rejestru.


Pośrednie etapy interaktywnego rebase są wykonywane z odłączonym HEAD (częściowo, aby uniknąć zanieczyszczenia reflogu aktywnej gałęzi). Jeśli zakończysz operację pełnego bazowania, zaktualizuje ona twoją oryginalną gałąź o skumulowany wynik operacji bazowania i ponownie przyłączy HEAD do oryginalnej gałęzi. Domyślam się, że nigdy nie ukończyłeś w pełni procesu rebase; pozostawi to odłączony HEAD wskazujący na zatwierdzenie, które zostało ostatnio przetworzone przez operację rebase.

Aby wyjść z tej sytuacji, powinieneś utworzyć gałąź, która wskazuje na zatwierdzenie aktualnie wskazywane przez odłączony HEAD:

git branch temp
git checkout temp

(te dwa polecenia mogą być skrócone jako git checkout -b temp)

Spowoduje to ponowne podłączenie HEAD do nowego tempoddziału.

Następnie powinieneś porównać bieżące zatwierdzenie (i jego historię) z normalną gałęzią, nad którą miałeś pracować:

git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
git diff master temp
git diff origin/master temp

(Prawdopodobnie będziesz chciał poeksperymentować z opcjami dziennika: dodaj -p, odłóż, --pretty=…aby zobaczyć cały komunikat dziennika itp.)

Jeśli Twój nowy tempoddział wygląda dobrze, możesz zaktualizować (np.), masterAby go wskazać:

git branch -f master temp
git checkout master

(te dwa polecenia mogą być skrócone jako git checkout -B master temp)

Następnie możesz usunąć gałąź tymczasową:

git branch -d temp

Wreszcie, prawdopodobnie będziesz chciał przeforsować przywróconą historię:

git push origin master

Konieczne może być dodanie --forcena końcu tego polecenia, aby wypchnąć, jeśli zdalna gałąź nie może być „szybko przekazana” do nowego zatwierdzenia (tj. Upuściłeś lub przepisałeś istniejące zatwierdzenie lub w inny sposób przepisałem trochę historii).

Jeśli byłeś w trakcie operacji rebase, prawdopodobnie powinieneś to wyczyścić. Możesz sprawdzić, czy trwa proces rebase, szukając katalogu .git/rebase-merge/. Możesz ręcznie wyczyścić trwający rebase, po prostu usuwając ten katalog (np. Jeśli nie pamiętasz już celu i kontekstu aktywnej operacji rebase). Zwykle byś użył git rebase --abort, ale to powoduje dodatkowe resetowanie, którego prawdopodobnie chcesz uniknąć (przenosi HEAD z powrotem do oryginalnej gałęzi i resetuje go z powrotem do pierwotnego zatwierdzenia, co cofnie część pracy, którą wykonaliśmy powyżej).

Chris Johnsen
źródło
6
Ciekawe z man git-symbolic-ref: „W przeszłości .git/HEADbyło dowiązanie symboliczne refs/heads/master. Kiedy chcieliśmy przejść do innej gałęzi, zrobiliśmy to ln -sf refs/heads/newbranch .git/HEAD, a kiedy chcieliśmy dowiedzieć się, na której gałęzi się znajdujemy, zrobiliśmy to readlink .git/HEAD. Ale dowiązania symboliczne nie są w pełni przenośne , więc są teraz przestarzałe, a odniesienia symboliczne (jak opisano powyżej) są domyślnie używane ”.
Dmitry Minkovsky
10
Zgadzam się z @AntonioSesto: w przypadku większości projektów (nawet dość dużych) nie potrzebujesz zadziwiającej złożoności, jaką jest Git. Mój mózg buntuje się przy zmaganiu się z czymś, co jest tak wyraźnie przeprojektowane. Nie potrzebuję tego i nie chcę tego.
Jasper Sprengers,
36
To dobra odpowiedź, ale myślę, że gałąź temp nie jest potrzebna (chociaż zwykle używam jej osobiście). git branch -f master HEAD && git checkout masterwystarczy - zakładając, że Twoim celem jest utrzymanie obecnej głowy, ale wyznaczenie jej jako master. Inne cele również mają sens i wymagają innych przepisów.
Adrian Ratnapala
38
Lol na komentarzu kręci się o długości. Podczas gdy reszta z nas po prostu skanuje, aż dojdziemy do linii z napisem „Aby wyjść z twojej sytuacji [...]”, i idźmy stamtąd - pamiętając, że istnieje przydatna, dobrze wyjaśniona historia, którą możemy przeczytać w deszczowy dzień. Opcja , aby przeczytać więcej cię nie boli, ale to nie stać, aby pomagać innym.
underscore_d
5
Właśnie dlatego nienawidzę gita.
Monica Heddneck
626

Po prostu zrób to:

git checkout master

Lub, jeśli masz zmiany, które chcesz zachować, wykonaj następujące czynności:

git checkout -b temp
git checkout -B master temp
Daniel Alexiuc
źródło
57
To niebezpieczna reakcja. Osoby dochodzące do tej odpowiedzi mają różne stany i odpowiedzi „po prostu zrób to, aby to naprawić” nie odpowiadają na pytania. Ten może łatwo zniszczyć pracę.
Archonic
15
! „Git Checkout Master” spowoduje utratę wszystkich zmian, jeśli odłączona głowa nie jest częścią Master !!
Tony
3
@Blauhirn Prawdopodobnie sprawdziłeś zatwierdzenie, a nie oddział. Gałąź nadal wskazuje ten sam zatwierdzenie, ale jesteś w innym „trybie”.
Daniel Alexiuc,
1
git resetpowinien zawierać ostrzeżenie „Jeśli nie masz pojęcia, co robisz, przestań”. Właśnie wyzdrowiałem z godziny terroru, myśląc, że straciłem ostatni tydzień pracy. Dzięki!
Opus1217,
1
Zgadzam się z @Archonic Ważne jest, aby zrozumieć, jak działa git przed ślepym uruchomieniem jakichkolwiek poleceń. Możesz zaoszczędzić czas, nie czytając dużej odpowiedzi, ale możesz stracić więcej czasu, jeśli stracisz pracę.
Yusufali2205
132

Natknąłem się na ten problem i kiedy przeczytałem w głosowanej odpowiedzi:

HEAD to symboliczna nazwa aktualnie wyrejestrowanego zatwierdzenia.

Pomyślałem: Ah-ha! Jeśli HEADjest symboliczną nazwą aktualnego zatwierdzenia kasy, mogę ją pogodzić, masterzmieniając ją na master:

git rebase HEAD master

To polecenie:

  1. wymeldowuje się master
  2. identyfikuje zatwierdzenia rodzica z HEADpowrotem do punktu HEADodbiegającegomaster
  3. odtwarza te zatwierdzenia na początku master

Rezultatem końcowym jest to, że wszystkie zatwierdzenia, które były w, HEADale nie masterbyły, również są w master. masterpozostaje sprawdzone.


W odniesieniu do pilota:

kilka zobowiązań, które zabiłem w bazie, zostało wypchniętych, a nowych popełnionych lokalnie nie ma.

Historia zdalna nie może być już przewijana do przodu przy użyciu historii lokalnej. Będziesz musiał użyć force-push ( git push -f), aby zastąpić zdalną historię. Jeśli masz współpracowników, zwykle warto z nimi skoordynować, aby wszyscy byli na tej samej stronie.

Po masterprzekazaniu do zdalnego origingałąź zdalnego śledzenia origin/masterzostanie zaktualizowana, aby wskazywała to samo zatwierdzenie, co master.

Dmitrij Minkowski
źródło
3
git: „Po pierwsze, przewijanie głowy, aby odtworzyć na niej swoją pracę ... Szybko przesłany master do HEAD.” ja: „miło!”
Benjamin,
81

Spójrz tutaj na podstawowe wyjaśnienie odłączonej głowy:

http://git-scm.com/docs/git-checkout

Linia poleceń do wizualizacji:

git branch

lub

git branch -a

otrzymasz wynik jak poniżej:

* (no branch)
master
branch1

Te * (no branch)pokazy jesteś w jednorodzinnym głowy.

Mogłeś dojść do tego stanu, wykonując git checkout somecommititp., I ostrzegłoby Cię to:

Jesteś w stanie „odłączony HEAD”. Możesz się rozejrzeć, wprowadzić eksperymentalne zmiany i zatwierdzić je, a także możesz odrzucić wszelkie zatwierdzenia dokonane w tym stanie bez wpływu na oddziały, wykonując kolejną kasę.

Jeśli chcesz utworzyć nowy oddział, aby zachować utworzone przez siebie zatwierdzenia, możesz to zrobić (teraz lub później), używając ponownie opcji -b z poleceniem kasy. Przykład:

git checkout -b nowa_nazwa_gałęzi

Teraz, aby doprowadzić ich do mistrza:

Zrób git refloglub nawet po prostu git logzanotuj swoje zobowiązania. Teraz git checkout masteri git mergezobowiązania.

git merge HEAD@{1}

Edytować:

Aby dodać, użyj git rebase -inie tylko do usuwania / zabijania niepotrzebnych zmian, ale także do ich edycji. Po prostu wspomnij „edytuj” na liście zatwierdzeń, a będziesz mógł zmienić swoje zatwierdzenie, a następnie wydać polecenie, git rebase --continueaby kontynuować. Zapewniłoby to, że nigdy nie pojawiłeś się w ODŁĄCZONEJ GŁOWIE.

manojlds
źródło
Dzięki za szczegóły i świetne wskazówki informacyjne tutaj. Wydaje się, że wyraźne scalenie nie było konieczne, ale zwizualizowało to niektóre koncepcje, do których wrócę. Dzięki.
Ben Zotto,
6
Co robi „@ {1}”?
ebi
35

Pobierz odłączony zatwierdzenie do własnego oddziału

Po prostu biegnij git checkout -b mynewbranch.

Następnie uruchom git log, a zobaczysz, że zatwierdzenie jest teraz HEADw tej nowej gałęzi.

Rose Perrone
źródło
Jeśli to zrobię, czy mynewbranchcoś się do mnie przyłączy?
Benjohn,
1
Tak, przywiązuje się do miejsca, w którym byłaby zamocowana odłączona głowa, i właśnie tego chciałem. Dzięki!
Benjohn,
22

jeśli masz tylko gałąź master i chcesz wrócić do „rozwoju” lub funkcji, wykonaj następujące czynności:

git checkout origin/develop

Uwaga: sprawdzanie pochodzenia / rozwoju .

Jesteś w stanie odłączonym HEAD . Możesz się rozejrzeć, wprowadzić eksperymentalne zmiany i zatwierdzić je, a także możesz odrzucić wszelkie zatwierdzenia dokonane w tym stanie bez wpływu na oddziały, wykonując kolejną kasę ...

następnie

git checkout -b develop

To działa :)

amdev
źródło
7
Dla mnie zadziałało nie „git checkout origin / develop”, ale „git checkout develop”. Użycie „origin / develop” zawsze powodowało brak zmian, tym samym pozostając w „HEAD odłączony w origin / develop”. Pominięcie części „początkowej” naprawiło wszystko.
DrStrangepork
18

Jeśli chcesz wypchnąć bieżącą odłączoną GŁOWĘ (sprawdź git logwcześniej), spróbuj:

git push origin HEAD:master

aby wysłać odłączony HEAD do gałęzi master w miejscu pochodzenia. Jeśli twoje wypychanie zostanie odrzucone, spróbuj git pull origin masternajpierw uzyskać zmiany od pochodzenia. Jeśli nie przejmujesz się zmianami pochodzącymi z pierwotnego źródła i został on odrzucony, ponieważ zrobiłeś celową zmianę bazy i chcesz zastąpić origin / master swoją obecnie odłączoną gałęzią - możesz to wymusić ( -f). Jeśli straciłeś dostęp do poprzednich zatwierdzeń, zawsze możesz uruchomić, git reflogaby zobaczyć historię ze wszystkich oddziałów.


Aby wrócić do gałęzi master, zachowując zmiany, wypróbuj następujące polecenia:

git rebase HEAD master
git checkout master

Zobacz: Git: „Obecnie nie w żadnym oddziale”. Czy istnieje prosty sposób na powrót do oddziału przy zachowaniu zmian?

kenorb
źródło
2
To rzeczywiście wysyła odłączone zatwierdzenia do źródła / wzorca. Aby dołączyć głowę do lokalnego oddziału, zrób to: stackoverflow.com/a/17667057/776345
Paschalis,
Kiedy to robię, otrzymuję To repozytorium jest skonfigurowane dla Git LFS, ale na twojej ścieżce nie znaleziono „git-lfs”. Jeśli nie chcesz już używać Git LFS, usuń ten haczyk, usuwając .git / hooks / post-checkout.
user2568374,
16

Znalazłem to pytanie podczas wyszukiwania You are in 'detached HEAD' state.

Po przeanalizowaniu tego, co zrobiłem, aby się tu dostać, w porównaniu z tym, co zrobiłem w przeszłości, odkryłem, że popełniłem błąd.

Mój normalny przepływ to:

git checkout master
git fetch
git checkout my-cool-branch
git pull

Tym razem zrobiłem:

git checkout master
git fetch
git checkout origin/my-cool-branch
# You are in 'detached HEAD' state.

Problem polega na tym, że przypadkowo:

git checkout origin/my-cool-branch

Zamiast:

git checkout my-cool-branch

Naprawą (w mojej sytuacji) było po prostu uruchomienie powyższej komendy, a następnie kontynuowanie przepływu:

git checkout my-cool-branch
git pull
user664833
źródło
11

Poniższe działało dla mnie (używając tylko głównego oddziału):

git push origin HEAD:master
git checkout master        
git pull

Pierwszy wypycha odłączoną GŁOWĘ do zdalnego źródła.

Drugi przechodzi do głównego oddziału.

Trzeci odzyskuje HEAD, który przywiązuje się do mistrza oddziału.

Problemy mogą pojawić się przy pierwszym poleceniu, jeśli push zostanie odrzucony. Ale nie byłby to już problem odłączonej głowy, ale chodzi o to, że odłączony HEAD nie jest świadomy niektórych zdalnych zmian.

Daniel Porumbel
źródło
nie działało, mam: to repozytorium jest skonfigurowane dla Git LFS, ale na twojej ścieżce nie znaleziono „git-lfs”. Jeśli nie chcesz już używać Git LFS, usuń ten haczyk, usuwając .git / hooks / pre-push. ORAZ Nie jesteś obecnie w oddziale. Podaj gałąź, z którą chcesz się połączyć.
user2568374,
11

Właśnie natrafiłem dziś na ten problem i jestem pewien, że rozwiązałem go, wykonując:

git branch temp
git checkout master
git merge temp

Byłem na komputerze służbowym, kiedy wymyśliłem, jak to zrobić, a teraz mam ten sam problem na moim komputerze osobistym. Będę musiał poczekać do poniedziałku, kiedy wrócę do komputera roboczego, aby zobaczyć dokładnie, jak to zrobiłem.

adamwineguy
źródło
@StarShine Kenorb naprawił to. Teraz zapisuje odłączone zatwierdzenia w nowej gałęzi, temp, przełącza na master i scala temp w master.
Cees Timmerman
Nie wiem, dlaczego ppl to przegłosowuje, naprawiło to mój problem ze statystyką, ale możesz chcieć dołączyć polecenie delete temp branch.
GlassGhost
8

Jeśli masz całkowitą pewność, że HEAD jest dobrym stanem:

git branch -f master HEAD
git checkout master

Prawdopodobnie nie możesz naciskać na pochodzenie, ponieważ twój mistrz odszedł od pochodzenia. Jeśli masz pewność, że nikt inny nie korzysta z repozytorium, możesz wymusić:

git push -f

Najbardziej przydatne, jeśli jesteś w gałęzi funkcji, której nikt inny nie używa.

geon
źródło
6

Wszystko, co musisz zrobić, to „git checkout [nazwa-gałęzi]”, gdzie [nazwa-gałęzi] to nazwa oryginalnej gałęzi, z której przeszedłeś w stan odłączonej głowy. (Odłączony od asdfasdf) zniknie.

Na przykład w oddziale „dev” kasujesz zatwierdzenie asdfasd14314 ->

'git checkout asdfasd14314'

jesteś teraz w stanie odłączonej głowy

„gałąź git” wyświetli coś w stylu ->

* (detached from asdfasdf)
  dev
  prod
  stage

ale aby wyjść z odłączonego stanu głowy i wrócić do dev ->

'git checkout dev'

a następnie „gałąź git” wyświetli ->

* dev
  prod
  stage

ale dzieje się tak oczywiście, jeśli nie masz zamiaru utrzymywać żadnych zmian w stanie odłączonej głowy, ale często robię to, nie zamierzając wprowadzać żadnych zmian, ale tylko spojrzeć na poprzednie zatwierdzenie

Adam Freeman
źródło
6

Jak zauważył Chris, miałem następującą sytuację

git symbolic-ref HEAD nie działa z fatal: ref HEAD is not a symbolic ref

Jednak git rev-parse refs/heads/masterwskazywał na dobry popełnić skąd mogę odzyskać (w moim przypadku ostatniego zatwierdzenia i widać, że zobowiązują się za pomocągit show [SHA]

Potem zrobiłem wiele nieporządnych rzeczy, ale wydaje się, że to naprawiłem,

git symbolic-ref HEAD refs/heads/master

I głowa jest przywiązana!

Varun Garg
źródło
1
Dzięki! Moja głowa się oderwała. Mógłbym to nadrobić, ale zdarzyło się, że wskazywały na ten sam zatwierdzenie, a nie na głowę, wskazując na zatwierdzenie. Dobra wskazówka = D
RagingRoosevelt
4

Zamiast robić git checkout origin/master

po prostu zrób git checkout master

następnie git branchpotwierdzi swój oddział.

Goran Ch.
źródło
4

Miałem ten problem dzisiaj, kiedy zaktualizowałem submoduł, ale nie było go w żadnej gałęzi. Już się popełniłem, więc ukrywanie, kasa, rozpakowywanie nie działało. Skończyło się na tym, że wybrałem zatwierdzenie odłączonej głowy. Więc natychmiast po tym, jak popełniłem (gdy wypychanie nie powiodło się), zrobiłem:

git checkout master
git cherry-pick 99fe23ab

Myślałem: jestem na oderwanej głowie, ale chcę być mistrzem. Zakładając, że mój stan odłączenia nie różni się bardzo od master, gdybym mógł zastosować moje zatwierdzenie do master, byłbym ustawiony. Właśnie to robi cherry-pick.

prewett
źródło
3

Jeśli zrobiłeś kilka zatwierdzeń na masterie i po prostu chcesz mastertam „scalić wstecz” (tzn. Chcesz masterwskazać HEAD), linijka będzie:

git checkout -B master HEAD
  1. To tworzy nową gałąź o nazwie master, nawet jeśli już istnieje (która jest jak przeprowadzka masteri tego właśnie chcemy).
  2. Nowo utworzona gałąź jest ustawiona na wskazywanie HEAD, gdzie jesteś.
  3. Nowa gałąź jest wyewidencjonowana, więc jesteś włączony master.

Uznałem to za szczególnie przydatne w przypadku sub-repozytoriów, które również często znajdują się w stanie odłączonym.

quazgar
źródło
3

Miałem ten sam problem i rozwiązałem go, wykonując następujące kroki.

Jeśli chcesz zachować zmiany

  1. Najpierw musisz uruchomić git checkout masterpolecenie, aby wrócić do gałęzi master.
  2. Jeśli chcesz zachować zmiany, po prostu uruchom git checkout -b changesi git checkout -B master changes

Jeśli nie potrzebujesz zmian

  1. Aby usunąć wszystkie nieśledzone pliki ze swojego oddziału, uruchom git clean -df.

  2. Następnie musisz usunąć wszystkie niestabilne zmiany w repozytorium. Aby to zrobić, musisz biecgit checkout --

  3. Na koniec musisz przywrócić gałąź do gałęzi głównej za pomocą git checkout masterpolecenia.

Aravinda Meewalaarachchi
źródło
3

Dla mnie było to tak proste, jak ponowne usunięcie lokalnego oddziału, ponieważ nie miałem żadnych lokalnych zatwierdzeń, które chciałbym wcisnąć:

Więc zrobiłem:

git branch -d branchname

A następnie ponownie sprawdzając oddział:

git checkout branchname
Klaus
źródło
1

Kiedy osobiście znajduję się w sytuacji, gdy okazuje się, że dokonałem pewnych zmian, gdy nie jestem w master(tj. HEADJest odłączony tuż nad masteri nie ma żadnych pośrodku między nimi) ukrywanie może pomóc:

git stash # HEAD has same content as master, but we are still not in master
git checkout master  # switch to master, okay because no changes and master
git stash apply  # apply changes we had between HEAD and master in the first place
Ben Usman
źródło
1

Krótko mówiąc, odłączony stan HEAD oznacza, że nie jesteś wyewidencjonowany w HEAD (lub tip) dowolnej gałęzi .

Zrozum z przykładem

Gałąź w większości przypadków jest sekwencją wielu zatwierdzeń, takich jak:

Zatwierdzenie 1: master -> branch_HEAD (123be6a76168aca712aea16076e971c23835f8ca)

Zatwierdź 2: master -> 123be6a76168aca712aea16076e971c23835f8ca -> branch_HEAD (100644a76168aca712aea16076e971c23835f8ca)

Jak widać powyżej w przypadku sekwencji zatwierdzeń, twoja gałąź wskazuje na twoje ostatnie zatwierdzenie. W takim przypadku, jeśli wykonasz transakcję w celu zatwierdzenia 123be6a76168aca712aea16076e971c23835f8ca, to będziesz w stanie odłączonej głowy, ponieważ HEAD twojego oddziału wskazuje na 100644a76168aca712aea16076e971c23835f8ca i technicznie jesteś wyewidencjonowany w HEAD żadnego oddziału. W związku z tym jesteś w stanie odłączonym HEAD.

Wyjaśnienie teoretyczne

Na tym blogu wyraźnie stwierdzono, że repozytorium Git jest drzewem zatwierdzeń, z każdym zatwierdzeniem wskazującym na jego przodka, przy czym każdy wskaźnik zatwierdzenia jest aktualizowany, a te wskaźniki do każdej gałęzi są przechowywane w podkatalogach .git / refs. Tagi są przechowywane w .git / refs / tags, a gałęzie są przechowywane w .git / refs / heads. Jeśli spojrzysz na któryś z plików, zobaczysz, że każdy znacznik odpowiada jednemu plikowi z 40-znakowym hashem zatwierdzenia i jak wyjaśniono powyżej przez @Chris Johnsen i @Yaroslav Nikitenko, możesz sprawdzić te referencje.

Keshav
źródło
0

Wpadłem w naprawdę głupi stan, wątpię, czy ktokolwiek uzna to za przydatne ... ale na wszelki wypadek

git ls-remote origin
0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b        HEAD
6f96ad0f97ee832ee16007d865aac9af847c1ef6        refs/heads/HEAD
0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b        refs/heads/master

które ostatecznie naprawiłem

git push origin :HEAD
KCD
źródło
0

To działało dla mnie idealnie:

1. git stashaby zapisać lokalne modyfikacje

Jeśli chcesz odrzucić zmiany,
git clean -df
git checkout -- .
git clean usuwa wszystkie nieśledzone pliki (ostrzeżenie: chociaż nie usuwa zignorowanych plików wymienionych bezpośrednio w .gitignore, może usuwać zignorowane pliki znajdujące się w folderach), a git checkout usuwa wszystkie nieustawione zmiany.

2. git checkout masteraby przejść do głównej gałęzi (Zakładając, że chcesz użyć master)
3. git pullwyciągnąć ostatnie zatwierdzenie z gałęzi master
4. git statusaby sprawdzić, czy wszystko wygląda świetnie

On branch master
Your branch is up-to-date with 'origin/master'.
jmojico
źródło
0

W moim przypadku uruchomiłem git statusi zobaczyłem, że mam kilka nieśledzonych plików w moim katalogu roboczym.

Aby rebase działał, musiałem je tylko wyczyścić (ponieważ ich nie potrzebowałem).

falsarella
źródło
0

Jeśli używasz EGit w Eclipse: załóż, że twój master jest główną gałęzią programistyczną

  • zatwierdzić zmiany w oddziale, zwykle nowym
  • następnie wyciągnij z pilota
  • następnie kliknij prawym przyciskiem myszy węzeł projektu, wybierz zespół, a następnie wybierz historię wyświetlania
  • następnie kliknij prawym przyciskiem myszy wzorzec, wybierz sprawdź
  • jeśli poinformuje Cię Eclipse, istnieją dwa urządzenia nadrzędne, jeden lokalny jeden zdalny, wybierz zdalny

Po tym powinieneś być w stanie ponownie dołączyć do master-origin.

Junchen Liu
źródło
-1

Miałem ten sam problem. Przechowuję swoje zmiany za pomocą git stashi mocno resetuję gałąź lokalnie do poprzedniego zatwierdzenia (myślałem, że to spowodowało), a następnie zrobiłem git pulli nie dostaję teraz tej głowy. Nie zapomnij git stash applyponownie wprowadzić zmian.

SamL
źródło
-2
git checkout checksum  # You could use this to peek previous checkpoints
git status # You will see HEAD detached at checksum
git checkout master # This moves HEAD to master branch
David Yang
źródło