Виправити відокремлену голову Git?


1453

Я робив певну роботу в своєму сховищі і помітив, що файл має місцеві зміни. Я більше не хотів їх, тому я видалив файл, думаючи, що можу просто отримати свіжу копію. Я хотів зробити еквівалент Git

svn up .

Використання git pull, здається, не спрацювало. Якийсь випадковий пошук привів мене до сайту, де хтось рекомендував робити

git checkout HEAD^ src/

( srcце каталог, що містить видалений файл).

Тепер я дізнаюся, що у мене відірвана голова. Я поняття не маю, що це. Як я можу скасувати?


69
git checkout masterповерне вас на головну гілку. Якщо ви хотіли очистити будь-які зміни в робочій копії, ви, ймовірно, хотіли це зробити git reset --hard.
Абе Волкер


якщо ви цього не зробили, ви могли це зробитиgit checkout -- src/
підписання

Спробуйте це: посилання . Коротше кажучиcreate temp branch - checkout temp branch - checkout master - delete temp branch
фідев

@AbeVoelker Що ти мав на увазі в коментарях від working copy changes? Ви маєте на увазі зміни, які ви внесли до файлів після перевірки чергової фіксації (тобто змін, які ви внесли під час відокремленого головного стану)?
Мінь Тран

Відповіді:


2147

Від'єднана голова означає, що ви більше не перебуваєте на гілці, ви перевірили одну історію комітету в історії (у цьому випадку команда попередня для HEAD, тобто HEAD ^).

Якщо ви хочете видалити зміни, пов’язані з відокремленою HEAD

Вам потрібно лише перевірити галузь, на якій ви були, наприклад

git checkout master

Наступного разу, коли ви змінили файл і хочете відновити його до стану, який він знаходиться в індексі, спочатку не видаляйте файл, просто зробіть

git checkout -- path/to/foo

Це відновить файл foo до стану, в якому він знаходиться в індексі.

Якщо ви хочете зберегти зміни, пов'язані з відокремленою ГОЛОВОЮ

  1. Виконати git branch tmp- це збереже ваші зміни в новій гілці, яка називається tmp.
  2. Біжи git checkout master
  3. Якщо ви хочете включити внесені вами зміни master, запустіть git merge tmpз masterгілки. Ви повинні бути на masterгілці після запуску git checkout master.

6
"Це відновить файл foo до стану, який він був до того, як ви внесли в нього будь-які зміни." -> він відновить його до стану, який він є в індексі - редагуйте
Mr_and_Mrs_D

88
Чому ця помилка виникає в першу чергу? Це одна з речей, за які я ненавиджу git - абсолютно випадкова поведінка часом. Ніколи не мали таких проблем з Меркуріалом.
Фіолетова жирафа

97
@VioletGiraffe Це не помилка, ані щось випадкове - це просто стан, у яке входить ваш сховище, коли ви перевіряєте попередню комісію. "Відірвана голова" служить попередженням про те, що ви також можете створити або вказати на гілку, якщо ви збираєтесь виконувати будь-яку роботу з цього пункту. Але якщо ви просто хочете переглянути цей тег або здійснити фіксацію, немає нічого поганого в тому, щоб бути у відокремленій головній державі.
Ніл Нейман

22
Не робіть цього, якщо ви прихилилися до відірваної голови, дивіться інші відповіді. Якщо це так, ви можете Previous HEAD position was 7426948...
перевірити

9
@VioletGiraffe: у вас є ментальна модель того, що відбувається на основі Mercurial, але ви використовуєте Git. Якщо ви не бажаєте підлаштовувати свою ментальну модель, щоб вона відповідала моделі Git, то справи й надалі будуть здаватися випадковими. Це так, ніби ви гуляєте на вулиці з окулярами VR, і ви думаєте, що літаєте літаком, але ви дійсно переходите вулицю. Ви потрапите на автомобілі.
іконоборство

477

Якщо ви змінили файли, які не хочете втрачати, ви можете натиснути на них. Я вчинив їх у відокремленому режимі, після чого ви можете перейти до тимчасової гілки, щоб згодом інтегруватися в головний.

git commit -m "....."
git branch my-temporary-work
git checkout master
git merge my-temporary-work

Витягнуто з:

Що робити з фіксацією, зробленою у відстороненій голові


27
Я вважаю це найкращим рішенням - особливо, якщо ви хочете зберегти зміни, які ви внесли під час перевірки окремої версії.
рекламна робота

10
@adswebwork: Я згоден. Усі інші відповіді пропонують повернутись до попереднього стану та втратити зміни, внесені локально у відокремлений головний стан.
Sk8erPeter

6
чому ні git stash? Оскільки це перше, що мені спадає на думку. створення нової гілки буде зайвим.
підписання

2
ви також можете, git rebase my-temporary-workа потім видалити гілку, git branch -d my-temporary-workщоб вона виглядала так, як ніби ви скористалися правою гілкою.
Золтан

@geekay git stashздається ідеальним інструментом для цієї справи. Чи можете ви, будь ласка, написати відповідь із запропонованими кроками для досягнення цього?
Золтан

156

Рішення без створення тимчасової гілки.

Як вийти («виправити») окремий стан HEAD, коли ви вже щось змінили в цьому режимі і, за бажанням, хочете зберегти свої зміни:

  1. Внесіть зміни, які ви хочете зберегти. Якщо ви хочете взяти будь-які зміни, внесені вами у відірваний стан HEAD, скористайтеся ними. Подібно до:

    git commit -a -m "your commit message"
    
  2. Відмовтеся від змін, які ви не хочете зберігати. Повторне скидання відкине будь-які незапущені зміни, які ви внесли в окремому стані HEAD:

    git reset --hard
    

    (Без цього крок 3 не вдасться, скаржившись на змінені непослані файли у відокремленій HEAD.)

  3. Перевірте своє відділення. Вийдіть із відокремленого стану HEAD, перевіривши галузь, над якою працювали раніше, наприклад:

    git checkout master
    
  4. Візьміть на себе свої комісії. Тепер ви можете взяти на себе зобов’язання, зроблені у відірваному стані HEAD, вибираючи вишню, як показано у моїй відповіді на інше питання .

    git reflog
    git cherry-pick <hash1> <hash2> <hash3> …
    

git reset --hardБув точно мені було потрібно, тому що я хочу, щоб вгору по течії , щоб бути джерелом і локальні зміни повинні бути видалені.
Маркус Зеллер

Чудова відповідь, це спрацювало для мене
MGLondon

130

Відірвана голова означає:

  1. Ви більше не на гілці,
  2. Ви перевірили одну історію в історії

Якщо у вас немає змін: ви можете перейти до головного, застосувавши таку команду

  git checkout master

Якщо у вас є зміни, які ви хочете зберегти:

У випадку, коли відокремлена HEAD, виконує роботу як звичайна, за винятком того, що жодна гілка не оновлюється. Щоб оновити головну гілку з внесеними змінами, зробіть тимчасову гілку там, де ви є (таким чином тимчасова гілка матиме всі здійснені вами зміни у відокремленій ГОЛОВІ), а потім переключіться на головну гілку та об'єднайте тимчасову гілку з Майстер.

git branch  temp
git checkout master
git merge temp

2
ідеально, то після зняття темпу гілки
Даві Менезес

64

Ось що я зробив лише після того, як зрозумів, що опинився на відірваній голові і вже вніс деякі зміни.

Я вчинив зміни.

$ git commit -m "..."
[detached HEAD 1fe56ad] ...

Я згадав хеш (1fe56ad) комітету. Тоді я перевірив гілку, на якій я мав би бути.

$ git checkout master
Switched to branch 'master'

Нарешті я застосував зміни комітету до гілки.

$ git cherry-pick 1fe56ad
[master 0b05f1e] ...

Я думаю, що це трохи простіше, ніж створення тимчасової гілки.


2
Це має бути відповіддю. Він повертає ваші нульові файли.
BlindWanderer

2
Так, це дійсно найпростіше зробити - досить просто запам'ятати, не шукаючи в Інтернеті наступного разу, коли це станеться. Здійснити, відмітити хеш, повернутися до гілки, яку ти мав на меті взяти на себе зобов’язання, і git cherry-pick <hash>.
Мейсон

Дякую за рішення. Це допомогло. Чи можу я також додати, що мені довелося зробити "майстра походження git push", щоб мій господар і походження / майстер вказували на одне і те саме.
ріпа424

1
Це, по суті, таніозна відповідь (опублікована раніше, ніж за рік).
Пітер Мортенсен

Завдяки цьому веселому вибору відновити останню зміну голови
Omega Cube

54

Якщо ви внесли деякі зміни, а потім зрозуміли, що перебуваєте на відокремленій голові, для цього є просте рішення: stash -> checkout 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'

У вас будуть невмілі зміни і нормальна "прикріплена" ГОЛОВА, як би нічого не сталося.


2
Заклали в закладки цього поганого хлопчика - економить, роблячи темп гілки. Працював частування.
Тім Тайлер

1
Я часто опиняюсь у відокремленому стані HEAD після перевірки підмодуля git, а потім внесення змін до нього. Я вважаю, що це найкраще і найпростіше рішення, щоб виправити речі, щоб я міг зберегти свої зміни.
користувач5359531

1
Це не працює, якщо ви вже здійснили зміни в окремому стані?
Данієль

40

Коли ви перевіряєте конкретну комісію git, ви опиняєтесь у відокремленому заголовковому стані ... тобто ваша робоча копія більше не відображає стан названого посилання (наприклад, "головний"). Це корисно для вивчення минулого стану сховища, але не того, що ви хочете, якщо ви насправді намагаєтесь відновити зміни.

Якщо ви внесли зміни до певного файлу і просто хочете їх відкинути, ви можете скористатись такою checkoutкомандою:

git checkout myfile

Це відкине будь-які незапущені зміни та поверне файл у будь-який стан у голові поточного відділення. Якщо ви хочете відмовитись від змін, які ви вже здійснили, ви можете скористатися resetкомандою. Наприклад, це поверне сховище до стану попереднього комітету, відкинувши всі наступні зміни:

git reset --hard HEAD^

Однак, якщо ви обмінюєтесь сховищем з іншими людьми, це git resetможе бути руйнівним (оскільки воно стирає частину історії сховища). Якщо ви вже поділилися змінами з іншими людьми, ви, звичайно, хочете подивитися на них git revert, що генерує "антикомісію" - тобто створює нове зобов'язання, яке "скасовує" зміни, про які йдеться.

У Git Book є детальніше.


1
Як я вже говорив у відповіді @ ralphtheninja, це git checkout path/to/fooможе конфліктувати git checkout some-branch, тому краще було б скористатися, git checkout -- path/to/fooщоб уникнути цих конфліктів.
Дієго Лаго

30

HEAD знаходиться в покажчику, і як результат, він вказує - прямо чи опосередковано - на певний комітет:

Приєднана   HEAD означає, що вона прикріплена до якоїсь гілки (тобто вона вказує на гілку).
Від'єднана HEAD означає, що вона не прикріплена до жодної гілки, тобто вказує безпосередньо на якусь фіксацію.

введіть тут опис зображення

Іншими словами:

  • Якщо це вказує на скоєння прямо , HEAD відривається .
  • Якщо він вказує на коміт непрямо (тобто він вказує на гілку, яка, в свою чергу, вказує на зобов’язання), додається HEAD .

Щоб краще зрозуміти ситуації із прикріпленою / відірваною головою, покажемо кроки, що ведуть до чотиригранної картинки вище.

Ми починаємо з того самого стану сховища (зображення у всіх квадрантах однакові):

введіть тут опис зображення


Тепер ми хочемо виконати git checkout- з різними цілями на окремих картинках (команди зверху затьмарені, щоб підкреслити, що ми збираємось лише застосувати ці команди):

введіть тут опис зображення


Це ситуація після виконання цих команд:

введіть тут опис зображення

Як ви можете бачити, точки Відправляйтеся до мети по git checkoutкоманді - на гілку (перші 3 зображення квадруплета), або (безпосередньо) до фіксації (останнє зображення четвірки).

Зміст робочого каталогу також змінюється таким чином, щоб він відповідав відповідній фіксації (знімку), тобто з командою, яку вказує (прямо чи опосередковано) HEAD.


Тож ми зараз у тій же ситуації, що і на початку цієї відповіді:

введіть тут опис зображення


6
Не читав, але вгору проголосував за гарні фотографії, які ви зробили;).
Карло Вуд

@Carlo, дякую!
MarianD

22

Оскільки "відокремлений стан голови" має вас на тимчасовій гілці, просто використовуйте, git checkout -яка ставить вас на останню гілку, на якій ви були.


1
будьте обережні, ви втратите будь-які зобов’язання, які ви домоглися, коли ви були на відокремленій державі.
Ajak6

@ Ajak6 Ви дійсно не втрачаєте цих зобов'язань. Вони все ще доступні через git reflogі можуть бути перенесені в нову філію або через git cherry-pickіснуючу філію. Дивіться це питання .
tanius

7

Для подальшого уточнення відповіді @Philippe Gerber ось:

git cherry-pick

Раніше cherry-pick, a git checkout masterє необхідним у цьому випадку. Крім того, він потрібен лише commitв detached head.


6

Додаток

Якщо філія, до якої ви хочете повернутися, була останньою замовою, яку ви зробили, ви можете просто скористатися checkout @{-1}. Це поверне вас до попередньої каси.

Крім того, ви можете дозволити цю команду, наприклад, git global --config alias.prevтаким чином, що вам просто потрібно набрати, git prevщоб повернутися до попередньої каси.


4

Перебуваючи в "відірваній голові" означає, що HEAD посилається на певну неназвану комісію (на відміну від названої гілки) (пор .: https://git-scm.com/docs/git-checkout розділ Окрема головка )

Щоб вирішити проблему, потрібно лише вибрати гілку, яку було обрано раніше

git checkout @{-1}


2

Коли ви опинилися в окремій голові та створили нові файли, спочатку переконайтеся, що ці нові файли додані до індексу, наприклад за допомогою:

git add .

Але якщо ви лише змінили чи видалили вже наявні файли, ви можете одночасно додати (-a) та зробити посилання з повідомленням (-m) за допомогою:

git commit -a -m "my adjustment message"

Тоді ви можете просто створити нову гілку з вашим поточним станом за допомогою:

git checkout -b new_branch_name

У вас буде нова гілка, і всі ваші коригування будуть в цій новій гілці. Потім ви можете продовжувати натискати на віддалений та / або замовляти / тягнути / зливатися, як завгодно.


1

Гіт розповів, як це зробити.

якщо ви ввели:

git checkout <some-commit_number>

Збережіть статус

git add .
git commit -m "some message"

Тоді:

 git push origin HEAD:<name-of-remote-branch>

1

Я хотів так змінити свої зміни, я просто виправляю це, роблячи ...

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

які працюють для мене


1

Зазвичай HEADвказує на гілку. Коли він не вказує на гілку, а тоді, коли він вказує на хеш-коміт, 69e51це означає, що у вас є відокремлена HEAD. Щоб вирішити проблему, потрібно вказати на неї дві гілки. Ви можете зробити дві речі, щоб виправити це.

  1. git checkout other_branch // Неможливо, коли вам потрібен код у цій комісії hash
  2. створіть нову гілку та вкажіть хеш-код на новостворену гілку.

HEAD повинен вказувати на гілку, а золотим правилом не є хеш.


саме тому у мене була ця сама помилка. Я перевірив ревізію, а потім знову перевірив його до поточної / останньої редакції замість того, щоб перейти до гілки, яка б належним чином прикріпила голову. Дякую за допомогу.
Рахул Тхакур

1

Відображена голова означає, що ви не перевірили свою філію належним чином або ви просто перевірили одну комісію.

Якщо ви зіткнулися з такою проблемою, спершу приховуйте свої локальні зміни, щоб ви не втратили своїх змін.

Після цього ... перевірте потрібну гілку за допомогою команди:

Скажімо, ви хочете відділення MyOriginalBranch:

git checkout -b someName origin / MyOriginalBranch



0
git pull origin master

працював на мене. Йшлося просто про те, щоб чітко давати назву віддалених та філій.


0

У моєму випадку я забігав git statusі побачив, що у мене в робочому каталозі було декілька незатребуваних файлів.

Мені просто довелося їх очистити (оскільки мені вони не потрібні), щоб запустити ребазу, яку я хотів виконати.


0

Це працює для мене, він призначить нову гілку для відокремленої голови:

git checkout new_branch_name detached_head_garbage_name


0

Від'єднана HEAD означає, що ви зараз не перебуваєте на жодній гілці. Якщо ви хочете зберегти свої зміни та просто створити нову гілку, це зробити:

git commit -m "your commit message"
git checkout -b new_branch

Згодом ви потенційно хочете об'єднати цю нову гілку з іншими гілками. Завжди корисною є команда git "собака" :

git log --all --decorate --oneline --graph
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.