분리 된 HEAD를 마스터 / 원점과 어떻게 조정할 수 있습니까? a 를 수행했습니다 .

Git의 분기 복잡성에 익숙하지 않습니다. 나는 항상 단일 브랜치에서 작업하고 변경 사항을 커밋 한 다음 주기적으로 원격 원점으로 푸시합니다.

최근 어딘가에, 커밋 준비를 끝내기 위해 일부 파일을 재설정하고 나중에 rebase -i최근 로컬 커밋을 제거하기 위해 a 를 수행했습니다 . 나는 지금 잘 이해하지 못하는 상태에 있습니다.

내 작업 영역에서 git log내가 기대하는 것을 정확하게 보여줍니다. 나는 가고 싶지 않은 커밋과 새로운 커밋 등 올바른 기차를 타고 있습니다.

그러나 방금 원격 저장소로 푸시했으며 다른 점이 있습니다. 리베이스에서 죽인 커밋이 푸시되었고 로컬로 커밋 된 새 커밋이 없습니다.

“마스터 / 원본”이 HEAD와 분리되어 있다고 생각하지만 그 의미, 명령 줄 도구로 시각화하는 방법 및 수정 방법에 대해 100 % 명확하지 않습니다.



답변

먼저 HEAD가 무엇인지 명확히하자 무엇인지, 분리되었을 때의 의미를 .

HEAD는 현재 체크 아웃 된 커밋의 심볼 이름입니다. HEAD가 분리되지 않은 경우 ( “정상” 1 상황 : 분기가 체크 아웃 된 경우) HEAD는 실제로 분기의 “ref”를 가리키고 분기는 커밋을 가리 킵니다. 따라서 HEAD는 지점에 “연결”됩니다. 새 커밋을 만들면 HEAD가 가리키는 분기가 새 커밋을 가리 키도록 업데이트됩니다. HEAD는 지점을 가리 키기 때문에 자동으로 수행됩니다.

  • git symbolic-ref HEAD 수확량 refs/heads/master
    “마스터”라는 지점이 체크 아웃되었습니다.
  • git rev-parse refs/heads/master 수율 17a02998078923f2d62811326d130de991d1a95a
    커밋은 마스터 브랜치의 현재 팁 또는 “헤드”입니다.
  • git rev-parse HEAD또한 수율 17a02998078923f2d62811326d130de991d1a95a
    이것은 “심볼 심판”이라는 의미입니다. 다른 참조를 통해 객체를 가리 킵니다.
    (심볼 ref는 원래 심볼릭 링크로 구현되었지만 나중에 심 링크가없는 플랫폼에서 사용할 수 있도록 추가 해석을 통해 일반 파일로 변경되었습니다.)

우리는이 HEADrefs/heads/master17a02998078923f2d62811326d130de991d1a95a

HEAD가 분리되면 분기를 통해 간접적으로 가리키는 대신 커밋을 직접 가리 킵니다. 분리 된 HEAD를 명명되지 않은 분기에있는 것으로 생각할 수 있습니다.

  • git symbolic-ref HEAD 실패 fatal: ref HEAD is not a symbolic ref
  • git rev-parse HEADyields 17a02998078923f2d62811326d130de991d1a95a
    상징적 인 참조가 아니기 때문에 커밋 자체를 직접 가리켜 야합니다.

우리는 HEAD17a02998078923f2d62811326d130de991d1a95a

분리 된 HEAD로 기억해야 할 중요한 점은 커밋이 참조되지 않은 경우 (참조가 도달 할 수없는 경우) 다른 커밋을 체크 아웃 할 때 “매달리게”됩니다. 결국, 이러한 댕글 링 커밋은 가비지 수집 프로세스를 통해 정리됩니다 (기본적으로 2 주 이상 유지되며 HEAD의 reflog에서 참조하여 더 오래 유지 될 수 있음).

1
HEAD가 분리 된 상태에서 “정상적인”작업을하는 것은 완벽합니다. 리플 로그에서 기록을 삭제하지 않기 위해하는 일을 추적해야합니다.


인터랙티브 리베이스의 중간 단계는 분리 된 HEAD (부분적으로 활성 브랜치 reflog의 오염을 피하기 위해)로 수행됩니다. 전체 리베이스 작업을 마치면 리베이스 작업의 누적 결과로 원래 분기를 업데이트하고 HEAD를 원래 분기에 다시 연결합니다. 제 생각에는 리베이스 프로세스를 완전히 완료 한 적이 없습니다. 그러면 rebase 작업으로 가장 최근에 처리 된 커밋을 가리키는 분리 된 HEAD가 남게됩니다.

상황을 복구하려면 분리 된 HEAD가 현재 가리키는 커밋을 가리키는 분기를 작성해야합니다.

git branch temp
git checkout temp

(이 두 명령은로 축약 될 수 있습니다 git checkout -b temp)

그러면 HEAD가 새 temp분기에 다시 연결됩니다 .

다음으로, 현재 커밋 (및 히스토리)과 정상 작동하는 분기를 비교해야합니다.

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

(아마도 로그 옵션을 시험 해보고 싶을 것입니다 : add -p, --pretty=…전체 로그 메시지를 보려면 떠나십시오 .)

temp지점이 좋아 보인다면이 master를 가리 키도록 업데이트 (예 🙂 할 수 있습니다.

git branch -f master temp
git checkout master

(이 두 명령은로 축약 될 수 있습니다 git checkout -B master temp)

그런 다음 임시 분기를 삭제할 수 있습니다.

git branch -d temp

마지막으로, 당신은 아마 다시 설립 된 역사를 추진하고 싶을 것입니다 :

git push origin master

--force원격 브랜치를 새 커밋으로 “빨리 전달”할 수없는 경우 (예 : 기존 커밋을 삭제하거나 다시 쓰거나, 약간의 히스토리를 다시 쓰지 못함) 푸시하려면이 명령의 끝에 추가해야 할 수도 있습니다.

리베이스 작업 도중에 있다면 정리해야합니다. 디렉토리를 찾아 리베이스가 진행 중인지 확인할 수 있습니다 .git/rebase-merge/. 해당 디렉토리를 삭제하여 진행중인 리베이스를 수동으로 정리할 수 있습니다 (예 : 활성 리베이스 작업의 목적과 컨텍스트를 더 이상 기억하지 않는 경우). 일반적으로을 사용 git rebase --abort하지만 피할 수있는 추가 재설정을 수행합니다 (HEAD를 원래 분기로 다시 이동하고 원래 커밋으로 다시 설정하여 위에서 수행 한 작업 중 일부를 취소합니다).


답변

그냥 이렇게 :

git checkout master

또는 유지하려는 변경 사항이있는 경우 다음을 수행하십시오.

git checkout -b temp
git checkout -B master temp


답변

나는이 문제에 부딪 쳤고 가장 인기있는 답변을 읽을 때 :

HEAD는 현재 체크 아웃 된 커밋의 심볼 이름입니다.

나는 생각했다 : 아하! 경우 HEAD기호 이름이 저지를 체크 아웃 currenlty을 위해, 나는에 대해 그것을 조정할 수 있습니다 master에 대해 그것을 리베이스로 master:

git rebase HEAD master

이 명령은

  1. 체크 아웃 master
  2. 식별의 부모 커밋 HEAD시점에 다시 HEAD에서 분기master
  3. 그 커밋을 재생합니다 master

결과적으로 모든 커밋 은 다음에 포함 HEAD되지 않은 결과입니다 . 체크 아웃 된 상태로 유지됩니다.mastermastermaster


리모컨에 관하여 :

리베이스에서 내가 죽인 커밋 몇 개가 밀려 났고 로컬에 커밋 된 새로운 커밋이 없습니다.

더 이상 로컬 히스토리를 사용하여 원격 히스토리를 전달할 수 없습니다. git push -f원격 기록을 덮어 쓰려면 강제 푸시 ( )해야합니다. 공동 작업자가있는 경우 일반적으로 모든 사람이 같은 페이지에 있도록이를 조정하는 것이 좋습니다.

masterremote로 푸시 하면와 같은 커밋을 가리 키도록 origin원격 추적 분기 origin/master가 업데이트됩니다 master.


답변

분리 된 헤드에 대한 기본 설명은 여기를 참조하십시오.

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

그것을 시각화하는 명령 줄 :

git branch

또는

git branch -a

다음과 같이 출력됩니다.

* (no branch)
master
branch1

* (no branch)당신이 분리 된 머리에 있는 쇼.

git checkout somecommit등 을 수행하여이 상태에 도달했을 수 있으며 다음과 같이 경고했을 것입니다.

‘분리 된 HEAD’상태입니다. 둘러보고 실험적으로 변경하고 커밋 할 수 있으며 다른 체크 아웃을 수행하여 분기에 영향을주지 않고이 상태에서 커밋을 버릴 수 있습니다.

생성 한 커밋을 유지하기 위해 새 브랜치를 만들려면 checkout 명령과 함께 -b를 다시 사용하여 지금 만들거나 나중에 할 수 있습니다. 예:

자식 체크 아웃 -b new_branch_name

이제 마스터로 가져 오려면

DO가 git reflog도 단지 또는 git log당신의 커밋을 확인합니다. 지금 git checkout master그리고 git merge커밋.

git merge HEAD@{1}

편집하다:

추가하려면 git rebase -i필요하지 않은 커밋을 삭제 / 죽일뿐만 아니라 편집에도 사용하십시오. 커밋 목록에서 “편집”을 언급하면 ​​커밋을 수정 한 다음 a git rebase --continue를 발행 할 수 있습니다. 이렇게하면 분리 된 HEAD에 들어오지 않았을 것입니다.


답변

분리 된 커밋을 자체 브랜치에 가져 오기

간단히 실행 git checkout -b mynewbranch .

그런 다음를 실행 git log하면 커밋이 이제이 HEAD새 분기에 있음을 알 수 있습니다.


답변

마스터 브랜치를 가지고 있고 “개발”으로 돌아가거나 기능을 원한다면 다음과 같이하십시오.

git checkout origin/develop

참고 : origin / develop 확인하십시오 .

HEAD 상태 가 분리 되었습니다 . 주변을 둘러보고 실험적으로 변경하고 커밋 할 수 있으며 다른 체크 아웃을 수행하여 분기에 영향을 미치지 않고이 상태에서 커밋을 버릴 수 있습니다 …

그때

git checkout -b develop

효과가있다 🙂


답변

현재 분리 된 HEAD를 푸시하려면 ( git log이전에 확인 ) 다음을 시도하십시오.

git push origin HEAD:master

분리 된 HEAD를 원점에서 마스터 브랜치로 보냅니다. 푸시가 거부되면 git pull origin master먼저 변경 사항을 원점에서 가져 오십시오. 의도적 인 리베이스를 수행하고 원산지 / 마스터를 현재 분리 된 브랜치로 바꾸려고했기 때문에 원산지 변경 사항에 신경 쓰지 않고 거부 된 경우 강제로 할 수 있습니다 ( -f). 이전 커밋에 대한 액세스 권한을 잃어버린 경우 언제든지 git reflog모든 분기의 히스토리를 볼 수 있습니다 .


변경 사항을 유지하면서 마스터 브랜치로 돌아가려면 다음 명령을 시도하십시오.

git rebase HEAD master
git checkout master

참조 : 힘내 “아니 현재 어느 지점에.” 변경 사항을 유지하면서 지점으로 돌아갈 수있는 쉬운 방법이 있습니까?