나는 여기서 당신의 기본적인 문제는 당신이 git이하는 일과 그것이하는 이유를 오해하거나 오해하고 있다는 것입니다.
다른 저장소를 복제 할 때 git은 "저기"에있는 모든 항목의 복사본을 만듭니다. 또한 같은 "그들의"지점 라벨을 소요 master
하고, "이름"에서 라벨의 복사본을 만드는 당신의 자식 트리 (일반적으로)입니다 remotes/origin/master
(하지만 경우에 remotes/upstream/master
). 대부분의 경우 remotes/
부분도 생략 하므로 원본을 upstream/master
.
이제 일부 파일을 변경하고 커밋하면 해당 변경 사항이있는 유일한 사람입니다. 한편 다른 사람들은 (당신이 복제 한) 원본 저장소를 사용하여 다른 복제를 만들고 그 복제를 변경할 수 있습니다. 물론 그들은 그들의 변화를 가진 유일한 사람들입니다. 하지만 결국 누군가가 ( "푸시"또는 패치 등을 통해) 원래 소유자에게 다시 보내는 변경 사항을 가질 수 있습니다.
이 git pull
명령은 대부분 git fetch
뒤에 git merge
. 이 두 작업이 실제로 수행하는 작업을 이해해야하기 때문에 중요합니다.
이 git fetch
명령은 복제 한 곳 (또는 가져올 장소로 설정 한 곳)으로 돌아가 "다른 사람이 추가하거나 변경하거나 제거한 새 항목"을 찾도록합니다. 이러한 변경 사항은 복사되어 이전에 가져온 내용의 복사본에 적용 됩니다 . 그것들은 당신 자신의 일에만 적용 되지 않습니다 .
git merge
명령은 더 복잡하고 비스듬히가는 곳입니다. 그것이하는 일은 "당신이 당신의 사본에서 변경 한 것"을 "당신이 다른 누군가로부터 가져 와서 당신의 사본에 추가 된 것"과 비교하는 것입니다. 변경 사항과 변경 사항이 충돌하지 않는 것 같으면 merge
작업이이를 하나로 묶어 개발과 개발을 함께 연결하는 "병합 커밋"을 제공합니다 (비록없는 매우 일반적인 "쉬운"경우가 있지만 변경하고 "빨리 감기").
지금 당신이 직면하고있는 상황은 당신이 변경하고 커밋 한 상황입니다 (사실 9 번, 따라서 "앞서 9") . 그들은 변경 하지 않았습니다 . 따라서 fetch
성실하게 아무것도 가져 오지 않고 merge
변경 사항이 없는 것을 가져오고 아무것도 하지 않습니다.
원하는 것은 "자신의"버전의 코드를 보거나 "재설정"하는 것입니다.
단순히보고 싶다면 해당 버전을 확인하면됩니다.
git checkout upstream/master
그러면 git에게 현재 디렉토리를 전체 이름이 실제로 인 브랜치로 이동하려고합니다 remotes/upstream/master
. 마지막으로 실행 git fetch
하고 최신 코드를 받았을 때의 코드가 표시됩니다.
자신의 변경 사항을 모두 버리고 싶다면 레이블 master
이름을 지정해야하는 개정판에 대한 git의 아이디어를 변경 해야합니다. 현재 가장 최근 커밋의 이름을 지정합니다. 해당 지점으로 돌아 가면 :
git checkout master
그런 다음 git reset
명령을 사용하면 "레이블을 이동"할 수 있습니다. 남은 유일한 문제는 (당신이 가진 모든 것을 버릴 준비가되어 있다고 가정 할 때) 레이블이 가리키는 위치를 찾는 것입니다.
git log
7cfcb29
영구적 인 (절대 변경되지 않는) 이름 인 숫자 이름을 찾을 수 있으며 이름 을 지정하는 다른 방법은 엄청나게 많지만이 경우에는 이름을 원합니다 upstream/master
.
자신의 변경을 닦아 레이블을 이동하려면 (당신이 저지른 모든 것을 아주 잠시 동안 실제로 복구 할 수 있지만, 그렇게 할 많이 힘들어이 이후의 매우 확실) :
git reset --hard upstream/master
은 --hard
주어진 커밋을 체크 아웃 한 후, 당신이하고있다 무엇을 쓸어 현재 지점 레이블을 이동하고 이눔 알려줍니다.
많은 일을 정말로 원 git reset --hard
하고 지우는 것은 드문 일이 아닙니다 . 보다 안전한 방법 (일부가 가치가 있다고 판단한 경우 해당 작업을 훨씬 쉽게 복구 할 수 있도록하는 방법)은 기존 브랜치의 이름을 바꾸는 것입니다.
git branch -m master bunchofhacks
그런 다음 master
"tracks" 라는 이름의 새 로컬 브랜치를 만듭니다 (사람들을 혼란스럽게한다고 생각하므로이 용어가 마음에 들지 않지만 git 용어입니다 :-)) 원점 (또는 업스트림) 마스터 :
git branch -t master upstream/master
그런 다음 다음과 같이 할 수 있습니다.
git checkout master
마지막 세 개의 명령이 수행하는 작업 (단지 두 개의 명령을 만드는 단축키가 있음)은 기존 레이블에 붙여 넣은 이름을 변경 한 다음 새 레이블을 만든 다음 전환하는 것입니다.
무엇이든하기 전에 :
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "master"
이후 git branch -m
:
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
이후 git branch -t master upstream/master
:
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
다음 C0
은 .NET Framework를 처음 수행했을 때 얻은 최신 커밋 (전체 소스 트리)입니다 git clone
. C1에서 C9는 커밋입니다.
을했다면 마지막 사진이 git checkout bunchofhacks
다음 git reset --hard HEAD^^
과 같이 변경됩니다.
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 - "bunchofhacks"
\
\- C8 --- C9
그 이유는 즉 HEAD^^
이름 (리셋이 될 것 바로 전에 현재 지점의 머리에서 개정이 최대 bunchofhacks
)와 reset --hard
다음 레이블을 이동합니다. 커밋 C8 및 C9는 이제 거의 보이지 않습니다 (reflog와 같은 것을 사용 git fsck
하여 찾을 수 있지만 더 이상 사소한 것은 아닙니다). 레이블은 원하는대로 이동할 수 있습니다. 이 fetch
명령은로 시작하는 항목을 처리합니다 remotes/
. "yours"를 "theirs"와 일치시키는 것이 일반적 이지만 (그러므로 만약 remotes/origin/mauve
당신이 당신의 이름을 붙인다면 mauve
) "그들로부터"받은 커밋의 이름을 짓거나보고 싶을 때마다 "theirs"를 입력 할 수 있습니다. ( "하나의 커밋"은 전체 소스 트리임을 기억하십시오. 하나의 커밋에서 하나의 특정 파일을 선택할 수 있습니다. git show
예를 들어,