programing

내 Git repo가 분리된 HEAD 상태에 들어간 이유는 무엇입니까?

newstyles 2023. 6. 13. 22:03

내 Git repo가 분리된 HEAD 상태에 들어간 이유는 무엇입니까?

저는 오늘 결국 머리가 분리되었는데, 이는 에 설명된 것과 같은 문제입니다: git push는 제가 지역적인 변화가 있음에도 불구하고 모든 것을 최신으로 알려줍니다.

제가 아는 한, 제가 평소와 다른 일을 한 것은 없습니다. 단지 제 지역 사무소에서 커밋하고 밀어붙이는 것뿐입니다.

그래서 어떻게 내가detached HEAD?

지점 이름이 아닌 커밋을 체크아웃하면 헤드가 분리됩니다.가지 끝을 나타내는 SHA1은 여전히 분리된 HEAD를 제공합니다.로컬 지점 이름의 체크아웃만 해당 모드를 방지합니다.

분리된 HEAD로 커밋 참조

HEAD가 분리되면 명명된 분기가 업데이트되지 않는 것을 제외하고 커밋은 정상적으로 작동합니다.(이것은 익명의 지점이라고 생각하시면 됩니다.)

alt 텍스트

예를 들어, "원격 분기"를 먼저 추적하지 않고 체크아웃하면 HEAD가 분리될 수 있습니다.

git 참조: 헤드를 분리하지 않고 분기 전환

의미:git checkout origin/main(또는 이전 시대의) 결과는 다음과 같습니다.

Note: switching to 'origin/main'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at a1b2c3d My commit message

그렇기 때문에 더 이상 사용하지 말고 새 명령을 사용해야 합니다.

와 함께git switch원격 분기를 "연결"(전환)하려는 동일한 시도는 즉시 실패합니다.

git switch origin/main
fatal: a branch is expected, got remote branch 'origin/main'

에 더 git switch:

Git 2.23(2019년 8월)을 사용하면 더 이상 혼란스러운 명령어를 사용할 필요가 없습니다.

git switch 또한 다음을 제외하고 분기를 체크아웃하고 HEAD를 분리할 수 있습니다.

  • 은 명시적인 명니다입적시를 가지고 .--detach

위해 커밋하기HEAD~3분기를 임시 또는 하는 경우:

git switch --detach HEAD~3
HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits'
  • 실수로 원격 추적 분기를 분리할 수 없습니다.

참조:

C:\Users\vonc\arepo>git checkout origin/master
Note: switching to 'origin/master'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

새로운 기능을 사용하는 경우git switch명령:

C:\Users\vonc\arepo>git switch origin/master
fatal: a branch is expected, got remote branch 'origin/master'

원격 분기를 추적하는 새 로컬 분기를 생성하려는 경우:

git switch <branch> 

한다면<branch>를 찾을 수 원격에 을 찾을수없정하확나원의격추에존분적다기재니가합히만지▁it▁incall▁(다▁is존니▁a재분합추).<remote>) 와

git switch -c <branch> --track <remote>/<branch>

더 이상 실수하지 마!
더 이상 원하지 않는 분리 HEAD가 없습니다!

그리고 만약 당신이git switch <tag>git switch --detach <tag>Git 2.36은 누락된 옵션을 기억하는 데 도움이 됩니다.

나는 방금 우연히 이것을 재현했습니다.

  1. 원격 분기를 나열합니다.

    git branch -r
          origin/Feature/f1234
          origin/master
    
  2. 로컬에서 하나를 체크아웃하고 싶어서 붙여넣기:

    git checkout origin/Feature/f1234
    
  3. Presto! 분리된 HEAD 상태

    You are in 'detached HEAD' state. [...])
    

솔루션 #1:

을 포함하지 .origin/할 때: 브치스앞에확인때할서펙랜때▁at:브▁spec▁when할확:

git checkout Feature/f1234

솔루션 #2:

더하다-b에서 변수입니다.

git checkout -b origin/Feature/f1234또는

git checkout -b Feature/f1234.

해라

git reflog 

과거에 HEAD 및 분기 포인터가 이동한 내역을 제공합니다.

예:

88ea06b HEAD@{0}: 체크아웃: DEPLOVENT에서 remote/origin/SomeNiceFeature e47bf80 HEAD@{1}: Pull origin DEPLOVENT:빨리 감기

이 목록의 맨 위는 분리된 헤드 상태를 만날 수 있는 한 가지 이유입니다.원격 추적 분기를 체크아웃하는 중입니다.

Detached HEAD현재 체크아웃된 항목이 로컬 분기가 아님을 의미합니다.

다음과 같은 결과를 초래할 몇 가지 시나리오Detached HEAD선택 사항:

  • 원격 지점을 체크아웃하는 경우 다음과 같이 말합니다.origin/master읽기 전용 분기입니다.따서커밋생에서 때origin/master자유롭게 연결됩니다. 즉, 분기에 연결되지 않습니다.

  • 특정 태그를 체크아웃하거나 커밋하는 경우.여기서 새 커밋을 수행하면 다시 자유롭게 이동합니다. 즉, 분기에 연결되지 않습니다.분기가 체크아웃되면 항상 새 커밋이 자동으로 끝에 배치됩니다.

    새한 후 돌가서특커또태체시여하작해면웃커시서다있아니새수습작으로 할 수 .git checkout -b new_branch_name이렇게 하면 다음을 방지할 수 있습니다.Detached HEAD이제 커밋이 아닌 분기가 체크아웃된 상태로 상태를 지정합니다.

분기와 동일한 이름의 태그가 있는 경우 발생할 수 있습니다.

예: "release/0"인 경우.1"은 태그 이름입니다.

git checkout release/0.1

"release/0"에서 분리된 HEAD를 생성합니다.1." release/0.1이 지점 이름일 것으로 예상하면 혼동됩니다.

이름을 변경하는 경우detached HEAD지점에서 식별되지 않고 잊혀질 HEAD로 이름을 지정할 것입니다.

우리는 사람들로서 지점 이름을 쉽게 기억할 수 있습니다.있습니다git checkout new-button-feature/git checkout main.main그리고.new-button-feature기억하기 쉽습니다.그리고 우리는 그냥 할 수 있습니다.git branch모든 지점의 목록을 가져옵니다.하지만 커밋만 가지고도 같은 일을 하려면 당신이 해야 할 일입니다.git reflog그것은 매우 지루합니다.수천 개의 커밋이 있지만 브랜치는 거의 없기 때문입니다.

분리된 커밋의 식별자는 해당 SHA일 뿐입니다.(지점이 .git checkout d747dd10e450871928a56c9cb7c6577cf61fdf31다음을 얻을 수 있습니다.

참고: 'd747ddd10e450871928a56c9cb7c6577cf61fdf31'을 확인합니다.

'헤드 분리' 상태입니다.

...

그런 다음 몇 가지를 변경하고 커밋을 수행한 경우에도 지점에 있지 않습니다.

당신은 SHA의 약속을 기억할 것 같습니까?안 그럴 거예요!

깃은 이런 일이 일어나는 것을 원하지 않습니다.따라서 HEAD가 분기와 연관되어 있지 않으므로 새 분기를 체크아웃하려는 경향이 있다는 것을 알려줍니다.그 결과 아래 메시지에는 다음과 같은 메시지가 표시됩니다.

작성한 커밋을 유지하기 위해 새 분기를 작성하려면 체크아웃 명령과 함께 -b를 다시 사용하여(지금 또는 나중에) 작성할 수 있습니다.예:

git checkout -b


좀 더 깊이 들어가자면, 지점은 현명한 방식으로 지어집니다.사용자가 커밋할 때 헤드가 업데이트됩니다.반면에 태그는 그런 것이 아닙니다.태그를 체크아웃하면 다시 분리된 HEAD에 있게 됩니다.주요 이유는 해당 태그에서 새 커밋을 만들면 해당 커밋이 분기나 태그가 아닌 어떤 항목에서도 참조되지 않는다는 점에서 여전히 분리된 HEAD로 간주되기 때문입니다.

첨부된 HEAD는 지점에 있을 때만 발생할 수 있습니다.

자세한 내용은 여기를 참조하십시오.

HEAD는 포인터이며 특정 커밋을 직접 또는 간접적으로 가리킵니다.

부착된 HEAD는 어떤 분기(즉, 분기를 가리킴)에 부착된 것을 의미합니다.

분리된 HEAD는 분기에 연결되어 있지 않음을 의미합니다. 즉, 어떤 커밋을 직접 가리킵니다.

다른 각도에서 보면, 만약 당신이 나뭇가지 위에 있다면, 그리고 그것을 하는 것.cat .git/HEAD다음을 얻을 수 있습니다.

ref: refs/heads/Your-current-branch-name

럼당신이그▁you.cat refs/heads/Your-current-branch-name그러면 지점이 가리키고 있거나 참조하고 있는 커밋의 SHA도 볼 수 있습니다.

과 하만만당분이리헤된드에당있과신면었다지약신▁however과▁and.cat .git/HEAD당신은 단지 약속의 SHA를 받을 뿐 그 이상은 없습니다.

639ce5dd952a645b7c3fcbe89e88e3dd081a9912

머리가 어떤 가지도 가리키고 있지 않다는 뜻입니다.그것은 단지 커밋을 직접적으로 가리키고 있을 뿐입니다.


이 모든 결과로, 지점 이름을 사용하여 체크아웃하지 않고 커밋을 체크아웃할 때마다 해당 커밋이 기본 지점의 최신 커밋일지라도 헤드가 로컬 지점을 가리키지 않기 때문에 여전히 분리된 HEAD에 있습니다.따라서 태그를 체크아웃하는 것만으로도 분리된 HEAD에 있게 됩니다.게다가 컴퓨터로 가져온 원격 분기를 체크아웃해도 헤드가 분리됩니다.git checkout origin main또한 분리된 머리가 될 수도 있습니다...

요약

다음과 같은 경우 헤드가 분리됩니다.

  • 커밋을 확인합니다.
  • 태그 확인
  • 원격 분기 체크아웃

지역 지점을 확인한 경우, 첨부된 헤드에만 있습니다.


조시 캐스웰과 새거 자하가 이 문제를 해결하는 데 도움을 주셔서 특별한 감사를 드립니다.

파일을 다시 체크아웃하고 구문을 제대로 이해하지 못해 변경한 내용을 취소하려는 경우 쉽게 발생할 수 있습니다.

은 의출을확수다있의 을 볼 수.git log마지막으로 성공한 커밋 이후 로그의 꼬리를 여기에 붙여넣으면 우리 모두가 당신이 한 일을 볼 수 있습니다.아니면 붙여넣고 친절하게 부탁할 수도 있습니다.#git프리노드 IRC에서.

간단한 우연한 방법은 다음과 같습니다.git checkout head 서로종류o▁as.HEAD.

사용해 보십시오.

git init
touch Readme.md
git add Readme.md
git commit
git checkout head

이는

Note: checking out 'head'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 9354043... Readme

깃이 분리된 헤드 상태로 전환하는 또 다른 방법은 원격 분기에 커밋하려고 시도하는 것입니다.다음과 같은 것:

git fetch
git checkout origin/foo
vi bar
git commit -a -m 'changed bar'

이 작업을 수행하면 오리진/푸를 다시 확인하려고 하면 분리된 헤드 상태로 돌아갑니다!

솔루션은 오리진/foo를 추적하는 자체 로컬 foo 분기를 만든 다음 선택적으로 푸시하는 것입니다.

이것은 아마도 당신의 원래 문제와 무관할 것이지만, 이 페이지는 "git untached head"에 대한 구글 히트에서 높은 순위를 차지하고 있으며, 이 시나리오는 심각하게 문서화되지 않았습니다.

분리된 HEAD

HEAD는 현재 체크아웃된 분기 또는 커밋에 대한 포인터로, 다음 질문에 답합니다.지금 저장소의 위치는 어디입니까? HEAD로컬 분기를 체크아웃했는지 여부에 따라 첨부(기본값) 또는 분리된 두 가지 상태 중 하나일 수 있습니다.

: 어게제이됐을요까렇게가떻?:▁a요됐▁op▁with▁op▁up을까▁did▁how▁i▁end렇이게?detached HEAD?

HEAD를 분리 상태로 유지하는 것보다 작업

최종적으로detached HEAD상태는 다양한 이유로 인해 발생할 수 있습니다. 아래에는 5가지 일반적인 경우가 있습니다(다음 중 하나를 수행한 경우가 있습니다).

  • 하는 것 를사여특커정하체밋다니합웃크아을용해시다▁checking,▁using)
    $ git checkout 14ko3
    
  • 지점을원지을명로체크합니다웃아으적시점.
    $ git checkout origin/master
    
  • 23)를즉 된플래그를전분분사여(Git 2.23)용기로환하리▁switching▁(전환▁usingg.
    $ git switch master --detached
    
  • 태를확는중입다니하인그,▁a다▁tag.
    $ git checkout v1.0.1
    
  • 변화를 인 리베이스)를것, 즉 대형또리베이스수행화변사정리스포이베기된함는이항경충하돌는또▁performing수▁an행▁((▁cont▁rebivease▁reb▁interact▁regularase),)or스대ting스리▁i이▁a화▁changes형베정기▁conflicaining.
    $ git rebase master feature-1 --interactive
    

분리된 상태에서는 기존 분기에 영향을 미치지 않고 실험 변경을 수행할 수 있습니다.아래의 차이점을 설명하는 인포그래픽 참조committing부착 상태와 분리된 상태.

분리된 HEAD 상태와 부착된 HEAD 상태 비교

일반적으로 잘못 알고 있는 것은 현재 'HEAD 분리됨' 상태의 메시지가 잘못된 톤으로 표시된다는 것입니다. 실제로는 어떻게 표시되는지 설명합니다.HEAD현재 스냅샷을 참조하고 있습니다.

분리된 상태에서 연결된 상태로 이동

분리된 상태에서 연결된 상태로 이동하려면 현재 위치에서 새 분기를 만들거나 기존 분기로 다시 전환할 수 있습니다.

참고: 분리된 상태에서 생성된 커밋은 새 분기에서 변경 내용을 유지하지 않고 다른 기존 분기로 전환하면 결국 삭제됩니다(가비지 수집 후).

출처: 위의 발췌문은 이 주제에 대한 전체 길이의 게시물에서 발췌한 것입니다.Git에서 HEAD는 무엇입니까?

에 할 때git checkout <commit-hash>또는 원격 분기로 헤드가 분리되어 새 커밋을 생성하려고 합니다.

분기 또는 태그로 연결할 수 없는 커밋은 30일 후에 가비지가 수집되어 저장소에서 제거됩니다.

이 문제를 해결하는 또 다른 방법은 새로 만든 커밋 및 체크아웃을 위한 새 분기를 만드는 것입니다. git checkout -b <branch-name> <commit-hash>

이 문서에서는 분리된 HEAD 상태로 전환하는 방법을 설명합니다.

VonC의 의견에 이어, 동일한 '분리된 HEAD' 문제를 어떻게 해결했는지에 대한 짧은 버전이 있습니다.

  1. 했습니다.origin/feature/dev
  2. 런에서 컬로에서행실내▁ingit fetch 내 은 이 원격 될 입니다. ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜ
  3. 지금실을 실행합니다.git switch feature/dev그리고 우리는 끝입니다!

지점 이름을 얻는 방법을 모색하고 있지만 다음을 얻고 있는 다른 사람들을 위해.HEAD은 다음과 같습니다: 신생각, 제낸것다같음습다니과은대해가같다▁instead.

const { execSync } = require('child_process');

const getBranchName = () => {
  let branch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
  if (branch === 'HEAD') branch = execSync(`git branch -a --contains HEAD | sed -n 2p | awk '{ printf $1 }'`).toString().trim();
  return branch;
}

저의 경우 다음과 같은 방식으로 발생합니다.

  • 새 분기를 생성합니다(feb_debugging).
  • 려달을 합니다.git fetch
  • 새 분기(feb_debugging)가 당겨졌습니다.
  • 제는을 사용합니다.git checkout origin/feb_debugging

헤드는 지금...

수리를 위해 체크아웃을 한 번 더 해야 합니다.

  • git checkout feb_debugging
  • 지금 git에서 feb_debugging branch에 있다고 합니다.

사용할 수 없는 경우git switchgit checkout [backup] 대신 'git checkout -b [backup]'을 사용합니다.

언급URL : https://stackoverflow.com/questions/3965676/why-did-my-git-repo-enter-a-detached-head-state