git: 지점이 X 커밋으로 앞서 있습니다.
어떻게 이런 일이 발생할까요?
저는 현재 하나의 레포에서 혼자 작업하고 있기 때문에, 다음은 제 워크플로우입니다.
- 파일 변경
- 저지르다
- 만족할 때까지 1-2회 반복
- 마스터로 푸시
▁a▁i때는할▁then▁do▁when가.git status이것은 제 지점이 X개의 커밋(아마도 제가 했던 것과 같은 수의 커밋)으로 앞서 있다는 것을 알려줍니다.코드를 누르면 로컬로 캐시된 파일(.git 폴더)이 실제로 업데이트되지 않기 때문입니까? git pull이 이상한 메시지를 '수정'하는 것처럼 보이지만, 왜 이런 일이 일어나는지 여전히 궁금합니다. 제가 git를 잘못 사용하고 있는 것이 아닐까요?
메시지에 인쇄되는 분기 포함
우리 지역 지점이 마스터보다 앞서 있습니다.
현재 분기를 어디로 푸시/해제하시겠습니까?
GitHub로 이동하여 작업 중인 컴퓨터로 이동하고 있습니다. 로컬 복사본은 항상 완전히 최신 상태입니다. 저만 작업하고 있기 때문입니다.
그것은 실제로 원격 레포를 확인하지 않습니다.
저는 그렇게 생각했습니다. 저는 그것에 대한 제 이해가 정확한지 확인하려고 했습니다.
당신은 그것에 추가적인 주장을 전달하고 있습니까?
제가 볼 수 있는 것은 아닙니다. 제 쪽에서 재미있는 구성이 진행되고 있는 것은 아닐까요?
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
다음 작업을 수행한 후 이 메시지가 표시되면git pull remote branch그것을 따라 해보세요.git fetch (으)로 실행합니다.git fetch -prepo에서 합니다.
브랜치의 하는 것 , Fetch를 할 때 것은 . 이는 다음 작업을 수행할 때 반드시 발생하지는 않습니다.git pull remote branch.
사용하다
git pull --rebase
--rebase 옵션은 git가 로컬 커밋을 따로 이동하고 원격과 동기화한 다음 새 상태에서 커밋을 적용하려고 시도한다는 의미입니다.
이 3가지 간단한 명령어를 사용
1단계:git checkout <branch_name>
2단계:git pull -s recursive -X theirs
3단계:git reset --hard origin/<branch_name>
더 자세한 정보: https://stackoverflow.com/a/39698570/2439715
즐거운 시간 되세요.
이것은 나에게 효과가 있었습니다.
git reset --hard origin/master
출력은 다음과 같아야 합니다.
On branch dev HEAD is now at ae1xc41z Last commit message
당신이 메시지를 잘못 읽고 있는 것 같습니다. 당신의 지점은 앞에 있지 않습니다.master그것은 master보다 앞서 있습니다origin/master마지막으로 원격 리포지토리의 상태를 기록하는 원격 추적 분기입니다.push,pull또는fetch이는 여러분이 무엇을 했는지 정확히 말해줍니다. 여러분은 리모콘을 앞섰고, 그것은 여러분에게 밀라고 상기시킵니다.
누군가 당신이 당신의 메시지를 잘못 읽고 있을지도 모른다고 말했습니다, 당신은 그렇지 않습니다.이 문제는 사실 당신과 관련이 있습니다.<project>/.git/config다음과 유사한 섹션으로 구성됩니다.
[remote "origin"]
url = <url>
fetch = +refs/heads/*:refs/remotes/origin/*
는 .git/config의 '앞에 ."라는메시지가 됩니다.N커밋." 발생으로 인한 짜증.
아니면 그렇게 되길 바랍니다.:)
무대 서버에서 풀만 하는 문제가 발생했습니다.그리고 하드 리셋은 리모트와 동일하게 HEAD를 청소하는 데 도움이 되었습니다.
git reset --hard origin/master
이제 다시 한 번 말씀드리겠습니다.
On branch master
Your branch is up-to-date with 'origin/master'.
참고: 이 질문은 제가 이 답변을 작성할 당시에는 꽤 오래된 질문이었습니다. 이 글은 이러한 많은 문제를 해결한 Git 버전의 첫 출시 3년 전에 게시되었습니다.하지만 현대적인 답변을 설명자와 함께 추가할 가치가 있어 보입니다.기존에 승인된 답변은 실행을 제안합니다.git fetch -p요즘은1 덜 필요하지만 좋은 생각입니다.Git 버전 1.8.2가 나오기 전에 훨씬 더 필요했습니다. Git은 원래 질문 이후 3년 후에 출시되었습니다.
1더-p또는--prune옵션은 필수가 아니며 링크된 답변에서만 제안됩니다.기능에 대해서는 아래의 긴 섹션을 참조하십시오.
어떻게 이런 일이 발생할까요?
원래 질문은 다음과 같습니다.
어떻게 이런 일이 발생할까요?
문제의 이것은 그 후에git push origin master작전이 실행되다git status됩니다.On branch master에 뒤에Your branch is ahead of 'origin/master' by 1 commit.그 질문에 제대로 답하려면, 우리는 그것을 조각조각 분해할 필요가 있습니다.
첫째, 각(로컬) 지점에는 업스트림 설정이 있습니다.
이 주장은 사실 너무 강합니다.Git 저장소에 있는 각 로컬 지점에는 Git가 업스트림이라고 부르는 설정이 하나씩 있을 수 있습니다.또는 해당 분기에 업스트림이 없을 수 있습니다.Git의 이전 버전은 이것을 업스트림 설정이라고 부르는 것에 대해 그다지 일관성이 없었지만, 현대 Git에서는 더 일관성이 있습니다.우리는 또한.git branch --set-upstream-to그리고.git branch --unset-upstream업스트림을 설정하거나 삭제할 수 있습니다.
것들이.--set-upstream-to그리고.--unset-upstream현재 분기에 영향을 줍니다.현재 지점이 현재 지점입니다.on,time,t제git status말한다on branch xyzzy뭐라고 쓰여있든 간에이 분기를 선택합니다.git checkout 2 이후—Git 2.23 이후—git switch어떤2 지점에서 확인하셨는지, 그게 바로 당신이 3맡고 있는 지점입니다.
사용하는 경우--unset-upstream현재 분기의 업스트림을 제거합니다.업스트림이 없으면 앞에 있거나 뒤에 있거나 분기된 메시지가 중지됩니다.그러나 이 메시지는 유용한 것으로 간주되므로 메시지가 발생하지 않도록 하기 위해 업스트림만 제거하면 안 됩니다. (메시지가 유용하지 않다면 무시해도 좋습니다. 결국 오류는 아닙니다.)
실행하는 경우git branch --set-upstream-to=origin/xyzzy현재 을 지점업다을설음정로다합니으림스로 합니다.origin/xyzzy이름이 지정된 분기의 경우xyzzy이것이 일반적으로 올바른 설정입니다.분기를 만드는 일부 작업은 (일반적으로 올바른) 업스트림을 자동으로 설정하고 일부 작업은 그렇지 않으므로 올바른 업스트림을 자동으로 설정하는 분기 생성 작업을 사용한 경우에는 아무 작업도 수행할 필요가 없습니다.다른 업스트림을 원하는 경우 또는 업스트림을 설정하지 않은 분기 생성 작업을 사용한 경우 이를 사용하여 업스트림을 변경할 수 있습니다.
업스트림을 설정할 수 있는 것은 다음과 같습니다.
- 분기: 로른(으) 지사:
git branch --set-upstream-to=experiment만의 지역을 .experiment현재 분기의 업스트림; 또는 - 다음과 같은 원격 검색 이름
origin/main또는origin/master또는origin/xyzzy은 다은다같출이다니름입력이에 의해 입니다.git branch -rGit는 이러한 원격 추적 지점 이름을 호출합니다(여기서 "지점"이라는 단어를 삭제하고 싶습니다). 잠시 후에 자세히 살펴보겠습니다.
뒤에, 갈라진 인 앞, 뒤, 최, 신는지메다같다습니음과시산된.git status인쇄는 다소 마법처럼 보이는 명령을 실행하여 파생됩니다.
git rev-list --count --left-right $branch...$upstream
$branch현재 지점 이름입니다.$upstream입니다(From에서 업트림설문다니입자열정스의from().git branch --set-upstream-to상기).여기 두 이름 사이에 세 개의 점이 있고, 그리고.--count,--left-right그리고 세 개의 점이 모두 필요합니다.git rev-list두 개의 숫자를 뱉어내는 것.
Git 2.23 이상이 있는 경우 2다음으로 이동하는 것이 좋습니다.git switch왜냐하면 그것은 약간의 까다로운 것을 피하기 때문입니다.git checkout역사적으로 초보자들을 곤경에 빠뜨린 행동들 (그리고 때때로 Git 전문가들에게 걸려들기도 함).하지만, 만약 당신이 익숙하다면.git checkout계속 지원되므로 원하는 만큼 계속 사용할 수 있습니다.진짜 문제는 기본적으로git checkout지나치게 강력하여 작업을 예상치 못하게 파괴할 수 있습니다.더 뉴git switch의도적으로 덜 중요하고 그렇게 하지 않을 것입니다. "의도적으로 내 작업을 수행" 작업이 이동되었습니다.git restore.
Git이 분리 HEAD 모드라고 부르는 분기가 없을 수도 3있습니다.사용하는 경우git checkout갑자기 이 모드로 전환될 수 있습니다(크게 무서운 경고를 출력하므로 무서운 경고가 보이지 않으면 그렇게 하지 않았습니다). 하지만 만약 당신이 사용할 수 있습니다.git switch분리 HEAD 모드를 허용해야 합니다.git switch --detach이 모드에는 아무런 문제가 없습니다. 일단 모드에 들어가면 새로운 커밋이 손실되지 않도록 주의해야 합니다.여러분이 조심하지 않으면 그것들을 수 있습니다.일반 모드에서 Git는 이와 같은 새로운 커밋을 잃지 않습니다.
분리된 HEAD 모드인 경우 분기가 없기 때문에 정의에 따라 업스트림이 없으며 이 질문의 내용은 적용되지 않습니다.
도달 가능성
이 부분은 약간 기술적이고 저는 그것의 대부분을 Think Like (a) Git라는 웹 사이트에 아웃소싱할 것입니다.여기서 이렇게 요약하겠습니다: 지점 이름(예:main또는xyzzy) 및 원격 검색 이름(origin/main,origin/xyzzyGit가 커밋을 찾는 방법입니다.Git은 커밋에 대한 모든 것입니다.지점 이름은 커밋을 찾는 데만 중요합니다.물론 찾을 수 없으면 곤란하니까 지점 이름이 중요해요.하지만 핵심은 도달 가능성입니다. 기술적인 용어죠.
Git 저장소의 각 커밋에는 크고 못생긴 16진수 문자열과 숫자로 번호가 매겨집니다.이것은 커밋의 해시 ID이며 Git가 커밋을 실제로 찾는 방법입니다.
각 커밋에는 두 가지가 포함됩니다. 즉, 모든 소스 파일의 전체 스냅샷(특수, 압축, Git화 및 중복 제거 형식)과 커밋 자체에 대한 일부 정보(예: 누가, 언제, 왜 (로그 메시지)를 만들었는지 알려주는 메타데이터)입니다.메타데이터에서 각 커밋은 이전 커밋의 커밋 번호를 보유합니다.즉, 한 커밋이 다른 커밋(이전 커밋)을 찾을 수 있습니다.
Think Like (a) Git가 지적했듯이, 이것은 기차와 약간 비슷합니다.일단 기차를 타면 아주 좋습니다. 이 경우에는 자동으로 뒤로, 이전의 모든 기차 정류장으로 이동할 수 있습니다.하지만 먼저 기차역으로 가는 길을 찾아야 합니다.Git 브랜치 이름은 당신의 브랜치에 있는 최근 커밋의 해시 ID를 포함합니다.
다음과 같이 그릴 수 있습니다.
... <-F <-G <-H <--branch
지점 이름branch최근 커밋의 해시 ID를 보유합니다.우리는 그 이름이 커밋을 가리킨다고 말합니다.그게 정말로 크고 못생긴 해시 ID가 무엇이든 간에, 우리는 방금 그 편지를 사용했습니다.H여기서 그것을 대신할 수 있습니다.
H는 실제 커밋이므로 저장된 스냅샷(파일)과 일부 메타데이터가 있습니다.메타데이터에서 Git는 이전 커밋의 해시 ID를 저장했습니다.우리는 그것을 이전 커밋이라고 부를 것입니다.G우리는 말합니다.H 을 가리키는 말. GGit can findH분기 이름 포인터에 의해, 그리고 그것은 Git에게 메타데이터를 포함한 커밋에 대한 액세스를 제공하므로, 이제 Git은 이전 커밋의 해시 ID를 가집니다.G.
G물론 실제 커밋이기도 합니다. 저장된 스냅샷과 일부 메타데이터가 있습니다.의 에서.G 커밋 Git의 했습니다.F우리는 말합니다.G을 가리키는 말.F그리고 이제 Git는 찾을 수 있습니다.F저장된 해시 ID를 사용합니다.
이것은 우리가 처음으로 약속을 할 때까지 영원히, 아니 오히려 반복됩니다.그 약속(아마도 우리는 그것이라고 부를 것입니다.A여기서는) 이전 커밋이 없기 때문에 이전 커밋을 거꾸로 가리키지 않습니다.
이 도달 가능성의 개념은 기본적으로 커밋에서 시작할 경우 발생하는 일을 요약한 것입니다.H지점명에 의하여 발견된 바와 같이.branch그리고 거꾸로 일을 합니다.커밋에 도달했습니다.H그것을 저지르기 위해 뒤로 손을 뻗습니다.G은 는르이에까지 .F등등.
지점 이름 및 원격 추적 이름
방금 언급했듯이 분기 이름에는 일부 커밋의 원시 해시 ID가 포함됩니다.그래서 Git는 그 약속을 찾을 수 있습니다.지점 이름에 대한 또 다른 특별한 기능이 있습니다.
를 할 때git checkout또는git switch분기에 연결한 다음 새 커밋을 수행하기 위해 Git는 자동으로 분기 이름의 저장된 해시 ID를 업데이트합니다.즉, 다음과 같은 일련의 커밋이 있다고 가정합니다.
...--F--G--H <-- xyzzy (HEAD)
우리는 지점에 있습니다.xyzzy특별한 이름을 붙여 표시하고 싶습니다.HEAD이 기능은 다이어그램에 지점 이름이 둘 이상 있을 때 유용합니다.:H현재로서는 가장 최근의 약속입니다.하지만 이제 우리는 일반적인 방법으로 다른 것을 만들 것입니다.
이 새로운 커밋은 다른 커밋과 마찬가지로 새롭고 고유하며 크고 못생긴 16진수 해시 ID를 가져옵니다.Git는 새 커밋이 커밋할 대상을 거꾸로 가리키는지 확인합니다.H그것이 우리가 새로운 약속을 할 때 사용했던 약속이기 때문입니다.우리는 그 편지를 사용할 것입니다.I이 새로운 약속을 대표합니다.다음과 같은 내용을 설명합니다.
...--F--G--H <-- xyzzy (HEAD)
\
I
mid-commit입니다.이 깃을 만들었습니다.I하지만 아직 끝나지 않았습니다.git commit아직 행동이 없습니다.자신에게 다음과 같은 질문을 하십시오. 어떻게 커밋을 찾을 수 있을까요?I할 것 같아요 해시 아이디? 아이디가 필요해요.해시 ID는 어디에 저장할 수 있습니까?
지점 이름으로 말씀하셨다면, 맞습니다.사실 Git에 관한 한 올바른 지점 이름은 현재 "사용 중"입니다.그게 우리가 첨부한 것입니다.HEAD이 도면에서.그래서 이제, 마지막 부분으로서.git commit은 깃을 씁니다 ㅠㅠI를 의해를 ID 름에입니다합력이시라는 으로 입력합니다xyzzy이것은 약속하는 것을 의미합니다.I 예:
...--F--G--H
\
I <-- xyzzy (HEAD)
그리고 이제 도면에 왜곡이 있을 이유가 없으므로, 우리는 그것을 바로잡을 수 있습니다.
...--F--G--H--I <-- xyzzy (HEAD)
지점 이름이 그렇게 작동합니다.이것은 정말로 매우 간단합니다. 한 번에 여러 가지를 생각해 보는 것이 필요합니다.이름이 커밋을 찾습니다.최신 커밋을 찾습니다.여기서 Git는 각 커밋이 이전 커밋을 찾기 때문에 역방향으로 작업합니다.
원격으로 추적하는 이름들은?음, 여기서 비결은 당신의 깃이 다른 깃과 대화한다는 것입니다.각 Git에는 고유한 분기 이름이 있습니다.당신은 당신의 것을 가지고 있습니다. master또는main그들은 그들의 것을 가지고 있습니다.당신은 당신의 것을 가지고 있습니다. xyzzy지점과 그들도 그들의 것을 가질 수 있습니다.
당신의 깃은 항상 그들의 깃을 불러 그들의 지점 이름을 물어볼 수 있습니다.하지만, 그것은 매우 효율적이지 않고 인터넷과 연결이 4끊기면 작동하지 않습니다.어쨌든, Git은 그렇게 하지 않습니다.대신 Git가 Git를 호출하여 모든 지점 이름과 해시 ID 목록을 가져오면 해당 이름과 해시 ID를 가져와 저장소에 저장합니다.실행할 때 발생합니다.git fetch.5
그런데 문제가 있습니다.의 그들.main또는master또는 그들의xyzzy만약 그들이 그것을 가지고 있다면, 그것은 반드시 당신의 약속과 같은 것을 의미하지 않습니다. main또는master또는xyzzy하지만 해결책은 간단합니다. Git은 지점 이름을 사용하여 원격 추적 이름으로 변환합니다.
한다면origin의main또는master또는xyzzy 를 만 하면 됩니다.git fetch또는git fetch origin 아과함께와 함께.--prune당신의 깃이 그들의 깃을 불러옵니다.지점 이름을 나열하고 해시 ID를 커밋합니다.당신의 Git는 필요한 경우 그들로부터 새로운 커밋을 얻습니다. 그들은 커밋을 가지고 있지만 당신은 그렇지 않습니다.그런 다음 Git는 지점 이름을 원격 추적 이름으로 바꾸고 원격 추적 이름을 생성하거나 업데이트하여 지점 이름이 가리키는 위치를 기억합니다.git fetch.
사용하는 경우--prune일부 지점 이름을 삭제한 경우를 처리합니다.그들이 이름을 딴 지점이 있다고 치자.oldstuff아까 받으셨기 때문에.origin/oldstuff당신의 원격 검색 이름으로.그리고 그들은 삭제했습니다. oldstuff그래서 이번에는 그들이...그냥 더 이상 그것을 가지고 있지 않습니다. 없이.--prune당신의 깃은 이것을 무시합니다.당신은 당신의 옛 모습을 유지합니다.origin/oldstuff지금은 죽었지만 말입니다.포함 --prune당신의 깃은 말합니다:오, 허, 이것은 이제 죽은 것처럼 보이고 그것을 잘라냅니다: 당신의 Git에서 그들의 지점 이름 중 하나와 일치하지 않는 원격 추적 이름은 그냥 삭제됩니다.
자르기 옵션은 항상 기본값이어야 했지만 그렇지 않았기 때문에 이제는 그럴 6수 없습니다.그러나 구성할 수 있습니다.fetch.prunetrue기본값으로 설정합니다.
그것은 2010년보다 2021년에 더 흔하지 4않습니다.Git가 처음 출시된 2005년에는 훨씬 더 흔했습니다.예전에는, 예를 들어, Linux 회의에 가는 항공사 비행기에서는, 어떤 가격에도 인터넷에 접속할 수 없었습니다.
5어떤 이름을 선택하고 언제 선택할지는 실제로 여기서 답의 일부입니다.Git에서는 시간이 지남에 따라 변화하고 있으며, 여전히 약간 변화하고 있습니다. 하지만 여전히 다양한 제약 조건이 존재합니다.자세한 얘기는 하지 않겠습니다.
6Git은 일반적으로 역호환성을 상당히 심각하게 생각합니다.1.x에서 2.0으로 전환하는 데 필요했습니다.push.default의 기본 matchingsimple를 들면예를 들어.
어떻게.git rev-list 숫자 의 숫 를 얻 니습다를 가져옵니다.
앞에서 언급한 바에 따르면, 앞, 뒤, 최신 또는 분산된 메시지는 다음과 같습니다.git status인쇄는 실행에서 파생됩니다.
git rev-list --count --left-right $branch...$upstream
무엇을git rev-list여기서 도달 가능한 커밋 수를 계산합니다.Gitrevisions 설명서에 설명된 3점 구문은 집합 이론에서 대칭 차이라고 불리는 것을 생성합니다.하지만 수학이 아닌 자곤에서, 우리는 이것을 두 가지 커밋 도달 가능성 테스트를 하는 것으로 생각할 수 있습니다. 이것은 다음과 같이 그릴 수 있습니다.
I--J <-- xyzzy (HEAD)
/
...--G--H
\
K <-- origin/xyzzy
여기, 커밋J지점 이름에서 연결 가능xyzzy왜냐하면 그 이름이 거기를 가리키기 때문입니다.저지르다I커밋에서 도달 가능J그래서 그것도 중요합니다.이는 다시 커밋으로 이어집니다.H--그래프에서 볼 수 있듯이, 이것은 약간 특별합니다.
동시에 커밋K원격 액세스 이름에서 연결할 수origin/xyzzy.저지르다H에서 도달 가능K커밋에서H뒷면, 커밋G그리고.F등도 모두 도달할 수 있습니다.하지만 두 개의 "철도 선로"는 커밋 시 합류합니다.H범하다H두 이름 모두에서 이전의 모든 커밋에 연결할 수 있습니다.
커밋합니다.I-J*이름에서만 도달할 수 있다는 점에서 특별합니다.xyzzy,그리고.K*이름에서만 도달할 수 있다는 점에서 특별합니다.origin/xyzzy세 점 표기법은 한 이름에서만 도달할 수 있는 커밋 또는 다른 이름에서만 도달할 수 있는 커밋을 찾습니다.
지점 이름을 왼쪽에, 업스트림 이름을 오른쪽에 놓고 3점 표기법을 사용하면 이 경우에 대한 세 가지 커밋을 모두 찾을 수 있습니다.사용.--count만든다git rev-list인쇄 번호: 3.사용.--left-right말한다git rev-list그러나 보다 현명하게 말하자면, 왼쪽 이름(현재 지점 이름)으로 인해 카운트되는 커밋 수와 오른쪽 이름(업스트림)으로 인해 카운트되는 커밋 수를 계산해야 합니다.따라서 두 가지 옵션과 세 가지 점을 모두 사용하면 다음과 같은 이점을 얻을 수 있습니다.
2 1
두 개의 커밋이 있다는 것을 알려주는 출력으로.xyzzy에 없는origin/xyzzy그리고 하나의 약속은 실행 중입니다.origin/xyzzy에 없는xyzzy커밋입니다.J-그리고-I(에)xyzzy) 및K(에)origin/xyzzy) 각각.
다음을 제외하고는--count선택,git rev-list다음과 같이 접두사로 추가된 해시 ID를 나열합니다.<(왼쪽) 또는>기호(오른쪽).사용.git log대신에git rev-list다음과 같이:
git log --left-right xyzzy...origin/xyzzy
(다시 세 개의 점에 주목하세요: Gitrevisions 참조 및 대칭 차이 검색) 우리는 표시된 세 개의 커밋을 받을 것입니다, 다시 앞에 붙입니다.<또는>적당하게
이렇게 하면 지점에 있는 커밋과 업스트림에 있는 커밋을 쉽게 확인할 수 있습니다.일반적으로 더 유용합니다.--decorate,--oneline,그리고.--graph(그리고 추가할 수도 있습니다.--boundary경우에 따라).
전방, 후방, 분산 또는 최신
자, 우리가 실행했다고 가정해 보겠습니다.
git rev-list --count --left-right $branch...$upstream
(또는—Gitrevisions 다시 보기—사용$branch@{upstream}여기 오른쪽에) 그리고 우리의 두 카운트를 받았습니다.다음이 가능합니다.
0그리고.0지점 이름과 원격 추적 이름(또는 업스트림에 있는 모든 이름)은 동일한 커밋을 가리킵니다.아무도 앞서거나 뒤떨어지지 않습니다.그git status사령부는 말할 것입니다.Your branch is up to date with '<upstream>'.0이 아님, 0:현재 분기에 업스트림에 없는 커밋이 있습니다.현재 분기에 없는 커밋이 업스트림에 없습니다.그래서 우리 지점은 상류 쪽에 있습니다.
0, 0이 아님:현재 분기에는 업스트림에 없는 커밋이 없지만 업스트림에는 현재 분기에 없는 커밋이 있습니다.이것은 우리 지점이 상류 쪽에 있다는 것을 의미합니다.
0이 아님, 0이 아님:이것은 제가 위에 그린 도표와 같습니다.현재 분기와 해당 분기의 업스트림은 동시에 서로 앞서 있습니다.그
git status명령은 단어를 사용합니다.diverged.
우리는 이제 원래 질문으로 돌아가려고 합니다.현재 분기의 업스트림이 원격 추적 이름이라고 가정합니다.얻은 개수는 원격 추적 지점 이름에 포함된 개수를 기반으로 합니다.
어떻게 이런 일이 발생할까요?
OP의 시나리오에서, 오직 한 사람만이 새로운 커밋을 만들고 그것들을 전송합니다.git push만약 내가 한 사람이라면, 나는 아마도.git clone깃허브에서 온 무언가, 그리고 새로운 커밋 또는 2 그리고.git push origin master.
현대 Git에서는 제가 최신 상태라고 말할 것입니다. 아주 오래된 Git 버전에서는 이제 내가 앞섰다고 말할 것입니다.그 이유는 간단합니다: 옛날에는,git push 업데이트하지 못했습니다. 실행 중git fetch origin아니면 그냥git fetch당신의 깃허브에 깃오버를 불러 그들의 정보를 읽고 당신의 깃허브가git push효과가 있었습니다.
실행할 때git push당신은 당신의 깃이 다른 깃을 불러오도록 합니다.그런 다음 당신의 깃은 다른 깃에게 당신이 가지고 있는 새로운 약속을 제공합니다, 그들은 그렇지 않습니다, 그들은 그들이 완료해야 할 것입니다.git push 그들은 그 약속들을 받아 7어딘가에 넣습니다.그런 다음 Git가 Git에게 질문합니다. 기본적으로 정중하게 질문합니다. 괜찮으면 지점 이름을 해시 ID로 최신 커밋을 참조하도록 설정하십시오. 지점 이름이 지점 이름에 표시됩니다.여기서는 원격으로 추적하는 일이 없습니다.사용 중인 이름과 동일한 이름을 설정하도록 요청하는 것입니다.
일반적으로 새 커밋을 리포지토리에 추가하는 경우 이러한 정중한 요청이 성공합니다.만약 당신이 그들에게 몇몇 커밋을 "잃어버리"라고 요청한다면, 그것은 실패합니다. 당신은 이것이 "빨리 감기"가 아니라는 불만을 받게 될 것입니다.사용자만 새 커밋을 보내는 경우 이러한 방식으로 손실되는 것이 없어야 하므로 항상 사용할 8수 있습니다.
푸시가 실패하면 Git에서 원격 추적 이름을 변경하지 않고 유지하는 것이 좋습니다.당신의 깃은 그들의 깃으로부터 당신의 깃이 그것을 업데이트하도록 할 정보를 결코 얻지 못했습니다.하지만 푸시가 성공하면... 글쎄요, 그들은 단지 당신의 Git가 사용하도록 요청한 해시 ID로 지점 이름을 설정합니다.이제 당신의 깃은 그들의 지점 이름이 가리키는 곳을 알고 있습니다.Git에서 원격 추적 이름을 업데이트해야 합니다.
오래된 Git 버전에서는, 당신의 Git이 이것을 하는 것을 신경쓰지 않았습니다.Git 버전 1.8.2에서 Git 작성자는 마침내 이것을 수정했습니다: 성공적인git pushGit가 제공한 업데이트에 동의했다는 사실에 근거하여 Git가 원격 추적 이름을 업데이트하도록 합니다.그래서 이런 일은 더 이상 일어나지 않습니다.
옛날에는, 그들은 그것들을 바로 그들의 저장소에 7넣었습니다.현대 Git에서, 그들은 그들을 격리 구역에 두고, 그들이 실제로 새로운 커밋을 받아들이는 경우에만 그들의 저장소로 그들을 마이그레이션합니다.
8물론 GitHub와 같은 곳에서는 예를 들어 모든 푸시에 대해 "아니오"라고 말하는 보호된 분기와 같은 기능도 제공합니다.우리는 또한 컴퓨터가 여러 대 있는데 컴퓨터 A를 통해 새로운 커밋을 만들고 푸시한 것을 잊어버리고 컴퓨터 B에서 푸시를 시도하는 것과 같은 더 멋진 시나리오를 발명할 수 있습니다.
만약 당신이 유일하게 하는 것이 아니라면요?git push
Alice와 Bob 모두 GitHub 저장소를 복제했다고 가정합니다.이 리포지토리의 개발은 분기에서 발생합니다.dev(개발용).그래서 앨리스는 그녀의 것을 만듭니다.dev그녀로부터origin/dev:
...--G--H <-- dev (HEAD), origin/dev [Alice's computer]
밥은, 마찬가지로, 그 자신의 것을 만듭니다.dev:
...--G--H <-- dev (HEAD), origin/dev [Bob's computer]
GitHub 저장소dev에서 끝나다.H역시. (그들은 없습니다.origin/devGitHub 저장소는 원격으로 이름을 추적할 필요가 없습니다.)
앨리스는 새로운 약속을 하고, 우리는 그것을 우리가 부를 것입니다.I그리고 앨리스의 컴퓨터에 이렇게 그립니다.
I <-- dev (HEAD)
/
...--G--H <-- origin/dev
그러는 동안, 밥은 새로운 약속을 하고, 우리는 그것을 우리는 그것이라고 부릅니다.J:
...--G--H <-- origin/dev
\
J <-- dev (HEAD)
이제 앨리스와 밥 둘다 노력합니다.git push origin dev그들 중 한 명이 먼저 도착합니다. 아마도 앨리스:
...--G--H--I <-- dev [GitHub's systems]
Bob이 커밋을 보냅니다.JGitHub은 다음과 같이 보입니다.
I <-- dev
/
...--G--H
\
J ... polite request to set dev to J
깃허브가 그렇게 한다면, 이것은 앨리스의 약속을 "잃어버릴" 것입니다.IGit은 이름에서 시작하여 거꾸로 작업함으로써 커밋을 찾기 때문입니다.그래서 그들은 "빨리 나아가지 못한다"는 불만으로 밀어붙이기를 거부합니다.
밥은 이제 커밋을 끌어내야 합니다.IGitHub에서 Bob의 저장소로 이동하여 Bob이 다음을 볼 수 있도록 합니다.
I <-- origin/dev
/
...--G--H
\
J <-- dev (HEAD) [Bob's computer]
밥은 이것을 해야 합니다.git fetch또는git fetch origin아마과 함께--prune(또는 포함)fetch.prune로 설정한.true. 이제 밥이 달릴 때git status그는 "차단된" 메시지를 받을 것입니다.
이제 푸시 레이스의 패자인 밥이 그의 일을 결합하는 방법을 알아내는 것에 달려 있습니다(커밋).JAlice의 (commit)과 함께I) 일을 결합하는 방법은 여러 가지가 있습니다.두 가지 주요한 것은git merge그리고.git rebase우리는 여기서 누가, 언제, 왜 무엇을 해야 하는지에 대해서는 다루지 않을 것입니다. 단지 이것이 당신이 다른 Git보다 엄격하게 앞서 있다고 생각했을 때 당신이 "분산된" 지위에 부딪힐 수 있는 또 다른 방법이라는 사실입니다.
저는 이 페이지의 모든 해결책을 살펴보았습니다. 다행히도 @anatoli-pazhyn은 그의 해결책이 효과가 있었기 때문에 이렇게 말했습니다.안타깝게도 저는 그를 지지할 충분한 평판을 얻지 못했지만, 먼저 그의 해결책을 시도해 볼 것을 권장합니다.
git reset --hard origin/master
그래서 나는:
HEAD is now at 900000b Comment from my last git commit here
또한 다음을 권장합니다.
git rev-list origin..HEAD
# to see if the local repository is ahead, push needed
git rev-list HEAD..origin
# to see if the local repository is behind, pull needed
다음을 사용할 수도 있습니다.
git rev-list --count --left-right origin/master...HEAD
# if you have numbers for both, then the two repositories have diverged
행운을 빌어요.
저의 경우에는 다음을 사용하여 마스터로 전환했기 때문입니다.
git checkout -B master
단지 그것의 새로운 버전을 끌어내기 위해서.
git checkout master
첫 번째 명령은 마스터 헤드를 최근 커밋으로 재설정합니다.
사용한
git reset --hard origin/master
고치기 위해
저도 윈도우 시스템에서 이와 같은 문제가 있었습니다.내가 실행했을 때git pull origin master명령을 실행하면 "X 커밋에 의한 '오리진/마스터' 앞에" 경고가 표시됩니다.만약 내가 도망친다면,git pull origin분기를 지정하지 않았기 때문에 더 이상 경고를 받을 수 없습니다.
저는 위의 @Marian Zburlia가 언급한 것과 동일한 것을 반복하고 싶습니다.그것은 저에게 효과가 있었고 다른 사람들에게도 똑같이 제안할 것입니다.
git pull origin develop
다음에 와야 합니다.$ git pull --rebase.
이렇게 하면 다음 사이트에 올라오는 댓글이 제거됩니다.$ git status마지막으로 당긴 후에
git fetch이 문제를 해결해 드리겠습니다.
내가 이해한 것이 맞다면, 당신의 로컬(캐시됨)origin/master최신 버전이 아닙니다.이 명령은 서버의 리포지토리 상태를 업데이트합니다.
현재 분기와 현재 트랙을 수행하는 분기의 차이점을 알려줍니다.메시지에 인쇄되는 분기와 현재 분기를 어디에서 누르거나 당길지 등 자세한 정보를 제공하십시오.
Tortise와 스위치/체크아웃을 할 때 실제로 이런 일이 있었습니다.GIT.
저의 문제는 다른 지역 지점을 기반으로 지점을 만든 것입니다.다음에 "합병" 항목을 만들었습니다./.git/config다음과 같이 보였습니다.
[branch "web"]
merge = refs/heads/develop
remote = gitserver
제가 "웹" 지점으로 전환할 때마다 100개 이상의 커밋이 개발보다 앞서 있다고 말했습니다.글쎄요, 저는 더 이상 개발에 전념하지 않았습니다. 그래서 그것은 사실이었습니다.이 항목을 간단히 제거할 수 있었고 예상대로 작동하는 것 같습니다.개발 지점 뒤에 있다고 불평하는 대신 원격 참조로 적절하게 추적하고 있습니다.
비크람의 말처럼 이 Stack Overflow 스레드는 구글에서 이 문제를 검색할 때 최상의 결과이므로 저의 상황과 해결책을 공유하고자 합니다.
그런 다음 Git 상태를 수행하면 분기가 X 커밋(아마도 내가 한 것과 동일한 수의 커밋)으로 앞서 있다는 것을 알려줍니다.
저는 지점이 많은 팀 환경에서 경험했습니다.NAT은 자체 기능 지사(로컬 클론)에서 작업하고 있으며, 이러한 지사 중 하나입니다.git status제가 11번 커밋 앞섰다는 걸 보여줬어요질문의 저자와 마찬가지로 제가 생각하는 작업상의 가정은 +11이 제 자신의 커밋에서 나온 것이라는 것이었습니다.
알고 보니 공통점에서 변화를 이끌어냈던 것 같습니다.develop몇 주 전에 제 기능 분기에 분기했습니다. 하지만 잊어버렸어요!제가 오늘 지역 기능 지사를 다시 방문했을 때git pull origin develop그 수는 +41 커밋 앞으로 뛰어올랐습니다.에서 많은 일이 이루어졌습니다.develop그래서 우리 지역의 특징 지점은 훨씬 더 앞섰습니다.origin저장소
따라서 이 메시지가 표시되면 액세스할 수 있는 다른 지점(또는 다른 지점)에서 풀/합병을 수행했을 수도 있습니다.메시지는 단지 당신이 필요로 하는 신호입니다.git push그것들의pull에드는 다시 로 변경합니다.origin로컬 보고서에서 repo('sync branch')를 선택하여 동기화할 수 있습니다.
나는 실제 질문과 관련된 다음과 같은 것을 받고 있었습니다.Your branch is ahead of 'origin/testing/KB-200' by 17 commits
이유: 지난 주에 검토할 PR을 만들고 프로젝트를 종료했습니다.그리고 오늘 같은 지점에서 약간의 변경을 하기 위해 프로젝트를 열었습니다.(testing/KB-200)그리고 나는 달렸습니다.git pull첫 번째. 이 풀에는 프로젝트를 수행하는 다른 개발자들의 18개의 새로운 커밋이 포함되어 있습니다. 이 커밋으로 인해 제 지역 지사가 원격 지사보다 앞서게 되었습니다. 그래서 저는 그 메시지를 받았습니다.그래서 다음 명령을 실행해야 했습니다.
git push origin testing/KB-200
그리고 나서 모두 동기화되고 최신 상태가 되었습니다. [On branch testing/KB-200 Your branch is up to date with 'origin/testing/KB-200']
이 질문은 좀 오래된 질문이지만...저도 비슷한 상황에 처해 있었고 여기서 제 대답은 제가 가지고 있던 비슷한 문제를 해결하는 데 도움이 되었습니다.
첫 번째 시도push -f또는 강제 옵션
이 방법이 효과가 없다면 (내 경우와 마찬가지로) 원격 저장소(또는 원격 저장소에 대한 참조)가git remote -v)가 업데이트되지 않을 수 있습니다.
위의 결과로 로컬/브랜치와 원격/브랜치의 푸시 동기화가 이루어졌지만 로컬 레포의 캐시에는 (로컬/브랜치의) 이전 커밋이 HEAD로 표시됩니다.
위의 내용을 확인하려면 다른 위치에서 리포를 복제하고 로컬/지점 HEAD와 원격/지점 HEAD를 비교해 보십시오.둘 다 같다면 아마 제가 한 문제에 직면하게 될 것입니다.
솔루션:
$ git remote -v
github git@github.com:schacon/hw.git (fetch)
github git@github.com:schacon/hw.git (push)
$ git remote add origin git://github.com/pjhyett/hw.git
$ git remote -v
github git@github.com:schacon/hw.git (fetch)
github git@github.com:schacon/hw.git (push)
origin git://github.com/pjhyett/hw.git (fetch)
origin git://github.com/pjhyett/hw.git (push)
$ git remote rm origin
$ git remote -v
github git@github.com:schacon/hw.git (fetch)
github git@github.com:schacon/hw.git (push)
자, 이제.push -f하기와 같이
git push -f github master 명령에 다음이 없습니다.origin더 이상!
도아git pull지금이다git pull github master
에git status받다
# On branch master
nothing to commit (working directory clean)
조회 수가 너무 많아서 이 오류를 검색하면 거의 항상 맨 위에 이 스레드가 나열되므로 유용하기를 바랍니다.
자세한 내용은 regitref도 참조하십시오.
제안하는 답은git pull또는git fetch맞습니다.
메시지는 다음과 같이 생성됩니다.git status차이를 보다.git/FETCH_HEAD그리고..git/refs/remotes/<repository>/<branch>(예:.git/refs/remotes/origin/master).
후자의 파일은 마지막 가져오기(리포지토리/분기의 경우)의 HEAD를 기록합니다.하고있다git fetch두 파일을 분기의 현재 HEAD로 업데이트합니다.
물론 가져올 항목이 없는 경우(로컬 저장소가 이미 최신 상태이기 때문에).git/FETCH_HEAD변하지 않습니다.
커밋을 수행한 후 이 메시지가 표시되면 분기의 파일 추적을 해제하려면 파일을 변경하고 커밋을 수행하십시오.이전에 추적된 파일의 추적 해제만 포함하는 단일 커밋을 수행할 수 없습니다.마지막으로 이 게시물은 https://help.github.com/articles/removing-files-from-a-repository-s-history/ 의 모든 문제를 해결하는 데 도움이 되었습니다.저장소 기록에서 파일을 제거해야 했습니다.
내게 일어난 일을 공유하는 것 뿐입니다.
많은 파일을 커밋했고 커밋하고 싶지 않은 파일이 있다는 것을 깨닫고 VS 코드를 사용하여undo last commit파일을 제거하고 gitignore에 추가한 다음 내 커밋을 다시 강제 실행합니다.
이로 인해 Git는 파일이 로컬에서 어떻게든 커밋되었기 때문에 원격으로 커밋해야 한다고 생각했습니다.
해결자undo last commit그리고 지금 무시하고 있는 파일의 스테이징을 해제합니다.
언급URL : https://stackoverflow.com/questions/2432579/git-your-branch-is-ahead-by-x-commits
'programing' 카테고리의 다른 글
| Android xml 오류: RelativeLayout(@id/LinearLayout_acc, @id/ProgressBar_statusScreen)이 있는 "지정된 이름과 일치하는 리소스를 찾을 수 없습니다" (0) | 2023.05.04 |
|---|---|
| 명령줄을 사용하여 커밋 메시지를 검색하는 방법은 무엇입니까? (0) | 2023.05.04 |
| LINQ를 사용하여 컬렉션의 모든 개체 업데이트 (0) | 2023.05.04 |
| iOS5 SDK의 자동 참조 카운팅에 대한 몇 가지 질문 (0) | 2023.05.04 |
| Python 3에서 선행 0으로 문자열을 패딩하는 방법 (0) | 2023.05.04 |