원점 / HEAD는 어떻게 설정됩니까?


144

참조 원점을 추적하도록 분기를 설정했습니다. git checkout <branchname>지점으로 전환하고 a 지점이 지점에서 git status얼마나 앞이나 뒤에 있는지 보여 주지만 origin/HEAD여전히을 가리키고 origin/master있지는 않습니다.origin/<branchname>

그래서 제 질문은 어떤 상황에서 원산지 / HEAD가 움직일까요?

편집하다:

원산지 / HEAD를 이동 하는 방법 에 대한 답변에 감사 하지만, "유기적"으로 이동하는 것에 관심이 있습니다.

예를 들어 분기를 전환하면 git은 체크 아웃하는 분기를 HEAD로 지정하므로 원점 / HEAD가 같은 방식으로 움직이지 않는다는 것에 놀랐습니다.


이 질문은와 같은 리모컨의 로컬 기호 참조에 관한 것 refs/origin/HEAD입니다. 리포지토리 자체의 심볼릭 참조 HEAD가 어떻게 설정되는지에 관한 것이 아닙니다 .
clacke

답변:


173

먼저 질문에 약간의 오해가 있음을 참고하십시오. origin / HEAD는 remote의 기본 분기 , 즉 origin을 호출하는 해당 원격 저장소 에있는 HEAD를 나타냅니다 . 리포지토리에서 분기를 전환해도 영향을 미치지 않습니다. 원격 브랜치에서도 마찬가지입니다. 당신은 할 수 masterorigin/master당신의 repo에서 origin/master의 로컬 복사본 나타내는 master원격 저장소에 지점을.

원산지의 HEAD는 원격 저장소에서 실제로 변경 해야하는 경우에만 변경됩니다. 기본적으로 절대 발생하지 않아야합니다. 기본 지점은 공개 지점이 안정적인 지점 (아마도 마스터)에서 일정하게 유지되기를 원합니다. origin / HEAD는 원격 저장소에서 HEAD의 로컬 사본을 나타내는 로컬 참조입니다. (이름은 심판 / 원격 / 원산지 / HEAD입니다.)

위의 내용은 실제로 알고 싶었던 것에 대답하지만, 명시 적으로 요청한 질문에 대답하기 위해 ... 원본 / HEAD는 저장소를 복제 할 때 자동으로 설정되며 그에 관한 것입니다. 기괴하게도 다음 과 같은 명령으로 설정 되지 않았습니다git remote update . 수동으로 변경하면 변경되는 유일한 방법은 믿습니다. (변경으로 나는 다른 브랜치를 가리킨다; 분명히 브랜치가 변경되면 커밋 / 가져 오기 / 원격 업데이트에서 발생할 수있는 변경을 가리키는 커밋.)


편집 : 아래 논의 된 문제는 Git 1.8.4.3 에서 수정되었습니다 . 이 업데이트를 참조하십시오 .


그러나 작은 경고가 있습니다. HEAD는 커밋을 직접 가리 키지 않고 분기를 가리키는 기호 참조이지만 git 원격 전송 프로토콜은 참조에 대한 커밋 만보고합니다. 따라서 Git은 HEAD와 다른 모든 참조가 가리키는 커밋의 SHA1을 알고 있습니다. 그런 다음 동일한 커밋을 가리키는 분기를 찾아 HEAD의 가치를 추론해야합니다. 이것은 두 개의 가지가 거기를 가리키면 모호하다는 것을 의미합니다. (가능한 경우 마스터를 선택한 다음 알파벳순으로 먼저 돌아갑니다.) 다음과 같은 결과가 표시됩니다 git remote show origin.

$ git remote show origin
* remote origin
  Fetch URL: ...
  Push  URL: ...
  HEAD branch (remote HEAD is ambiguous, may be one of the following):
    foo
    master

이상하게도, HEAD의 개념이 이런 식으로 인쇄되면 원격에서 변경 사항이있을 경우 (예 : foo가 제거 된 경우) 변경되지만 실제로 업데이트되지는 않습니다 refs/remotes/origin/HEAD. 이것은 정말 이상한 상황으로 이어질 수 있습니다. 위 예제에서 origin / HEAD가 실제로 foo를 가리키고 나서 origin의 foo 분기가 제거되었다고 가정하십시오. 그런 다음이 작업을 수행 할 수 있습니다.

$ git remote show origin
...
HEAD branch: master
$ git symbolic-ref refs/remotes/origin/HEAD
refs/remotes/origin/foo
$ git remote update --prune origin
Fetching origin
 x [deleted]         (none)     -> origin/foo
   (refs/remotes/origin/HEAD has become dangling)

따라서 원격 쇼는 HEAD가 마스터임을 알고 있지만 아무것도 업데이트하지 않습니다. 오래된 푸 지사가 제대로 정리하고, HEAD는 (존재하지 않는 지점을 가리키는) 매달려된다, 그것은 여전히 마스터를 가리 키도록 업데이트하지 않습니다. 이 문제를 해결하려면 git remote set-head origin -a위와 같이 원점의 HEAD를 자동으로 결정한 다음 실제로 원점 / HEAD를 적절한 원격 분기를 가리 키도록 설정합니다.


@jefromi 멋진 답변! 단지 발언 : HEAD는 커밋 [...] 대신 직접 분기를 가리키는 상징적 인 참조 라고 쓰지만 완전성을 위해 "분리 된 HEAD 상태"를 언급하는 것이 좋습니다.
jub0bs

2
@ Jubobs 감사합니다! 내 답변을 업데이트 해야하는 경우 언제든지 간단히 편집하십시오 .2 년 전의 사실과 현재의 사실을 분류하지 않고 실제로 어떻게 작동하는지에 대한 간략한 요약을 읽을 수있는 시간을 절약 할 수 있습니다. .
Cascabel

이 글을 5 번 이상 읽었지만 아직 조금도 이해하지 못합니다
krb686

7
git remote set-head origin -a나를 위해 일을했다
Shujito

75

지역 저장소의 소유자로 설정 한 것입니다. 다음과 같이 변경하십시오.

git remote set-head origin some_branch

그리고 origin / HEAD는 master 대신 지점을 가리 킵니다. 그러면 다른 사람이 아닌 리포지토리에만 적용됩니다. 원격 저장소에 다른 항목이 구성되어 있지 않으면 기본적으로 마스터를 가리 킵니다.

원격 설정 헤드를 수동으로 입력하면 이에 대한 유용한 정보를 얻을 수 있습니다.

편집 : 강조 : 강조하지 않고 "이동"하는 유일한 방법 은 마스터 브랜치의 이름을 바꾸는 것과 같은 경우 일 것입니다. 그래서 나는 유기적으로 움직이지 않는다고 말할 것입니다.


1
편집 강조는 여기에서 완전히 정확하지 않습니다. 마스터 브랜치에없는 로컬 복사본에서 복제하는 경우에도 변경 될 수 있습니다.
mphair

나는 복제 "이동"을 고려하지 않지만, 우리가 그것에 동의하지 않을 수 있다고 생각합니다 :)
eis

24

원점 / HEAD를 "유기적으로"움직이는 것은 무엇입니까?

  • git clone HEAD가 시작되는 지점으로 한 번 설정
    • 복제 후 기본 체크 아웃으로 사용됩니다. git clone

HEAD on origin은 무엇을 나타 냅니까?

  • 베어 저장소 (종종 "서버"레포지토리)는, 기본 분기 마커 역할 이유로 인해 사용 git clone하는 방식으로 사용이
  • Bare가 아닌 리포지토리 (로컬 또는 원격)에서는 리포지토리의 현재 체크 아웃을 반영합니다.

원산지 / HEAD는 무엇입니까?

  • git clone 가져 와서 설정
  • 경우는 나을 git fetch업데이트는 다른 참조를 좋아하지만, 그렇지 않습니다
  • git remote set-head origin -a 가져 와서 설정
    • 원격에서 "기본 분기"로 간주하는 것에 대한 로컬 지식을 업데이트하는 데 유용

하찮은 일

  • origin/HEAD 리모컨에 연결하지 않고도 다른 값으로 설정할 수도 있습니다. git remote set-head origin <branch>
    • 테스트를 제외하고는 유스 케이스가 없습니다.
  • 불행히도 아무것도 리모콘에서 HEAD를 설정할 수 없습니다
  • 이전 버전의 git은 원격에서 HEAD가 가리키는 브랜치 HEAD를 알지 못했고 마지막으로 커밋 해시를했습니다. 따라서 동일한 해시를 가리키는 브랜치 이름을 선택했습니다

나는 참조를 잃어 버렸고 origin/HEAD귀하의 솔루션이 도움이되었습니다. 감사!
java_dude

git fetch(로컬) 바로 가기를 구성 할 수 있기 때문에 업데이트에 동의하지 않습니다 . 문서 인용 : "원격에 대한 기본 지점을 가질 필요는 없지만, 특정 지점 대신 원격의 이름을 지정할 수 있습니다". 원격 변경이 로컬로 구성된 바로 가기를 업데이트하면 이상 할 것입니다.
Micha Wiedenmann

@MichaWiedenmann 왜 로컬로 구성된 바로 가기입니까? 로컬로 구성된 바로 가기의 origin/HEAD이름이 잘못되었습니다. 그리고 그 git clone사용뿐만 아니라 "로컬로 구성된 지점"모순에 대한 기본값으로 원격 이름입니다. Bare가 아닌 저장소에서는 remote의 current를 사용하는 것도 의미가 없습니다 HEAD.
Robert Siemer

10

면책 조항 : 이것은 Jefromi의 답변에 대한 업데이트 이며, 나는 호기심을 절약하기 위해 쓰고 있습니다.

나는 remote HEAD is ambiguousJefromi가 그의 대답에서 언급 한 메시지를 (Git 2.0.1에서) 복제하려고 헛되이 노력했다 . https://github.com/git/git 을 복제 하고 로그를 검색하여 약간의 파기를했습니다 . 예전에는

Determining HEAD is ambiguous since it is done by comparing SHA1s.

In the case of multiple matches we return refs/heads/master if it
matches, else we return the first match we encounter. builtin-remote
needs all matches returned to it, so add a flag for it to request such.

(Commit 4229f1fa325870d6b24fe2a4c7d2ed5f14c6f771, 2009 년 2 월 27 일자로 발견됨 git log --reverse --grep="HEAD is ambiguous")

그러나 문제의 모호성은 이후에 해제되었습니다 .

One long-standing flaw in the pack transfer protocol used by "git
clone" was that there was no way to tell the other end which branch
"HEAD" points at, and the receiving end needed to guess.  A new
capability has been defined in the pack protocol to convey this
information so that cloning from a repository with more than one
branches pointing at the same commit where the HEAD is at now
reliably sets the initial branch in the resulting repository.

(커밋 9196a2f8bd46d36a285bdfa03b4540ed3f01f671, 2013 년 11 월 8 일,와 함께 발견 git log --grep="ambiguous" --grep="HEAD" --all-match)

편집 ( torek 덕분에 ) :

$ git name-rev --name-only 9196a2f8bd46d36a285bdfa03b4540ed3f01f671
tags/v1.8.4.3~3

즉, Git v1.8.4.3 이상을 사용 하는 경우 모호한-원격 -HEAD 문제가 발생하지 않아야합니다.


1
자식 소스의 태그를 기반으로이 수정 사항은 자식 버전 1.8.4.3 이상에 적용됩니다.
torek

@RobertSiemer 확실하지 않지만 그렇게 생각합니다.
jub0bs

8

우리가 이야기하고 있는 두 개의 독립적 인 자식 저장소 가 있다는 것을 기억하십시오 . 코드가있는 로컬 리포지토리와 다른 곳에서 실행되는 리모콘.

지점을 변경할 때 HEAD는 현재 지점을 가리 킵니다. 이 모든 것은 로컬 git repo에서 발생합니다. 다른 개발자가 소유하거나 사무실의 서버 또는 github 또는 파일 시스템의 다른 디렉토리 등에 앉아있는 원격 저장소가 아닙니다.

귀하의 컴퓨터 (로컬 저장소)는 원격 자식 저장소의 HEAD 포인터를 변경하는 사업이 없습니다. 예를 들어 다른 개발자가 소유 할 수 있습니다.

한 가지 더, 컴퓨터가 origin / XXX라고 부르는 것은 마지막 페치 시점의 원격 상태에 대한 컴퓨터의 이해입니다.

그렇다면 "유기적으로"오리진 / HEAD를 어떻게 업데이트할까요? 원격 git repo에서의 활동 일 것입니다. 현지 리포지토리가 아닙니다.

사람들은 언급했다

git symbolic-ref HEAD refs / head / my_other_branch

일반적으로 개발 팀에서 사용할 공유 중앙 git 저장소가 서버에있을 때 사용됩니다. 원격 컴퓨터에서 실행되는 명령입니다. 원격 git repo의 활동으로 볼 수 있습니다.


1
조금 반복적이라면 죄송합니다. git이 분산 버전 제어 시스템이라는 사실을 지적하고 싶습니다. 따라서 두 저장소는 독립적입니다.
Pablo Maurin

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.