마스터 브랜치와 '원산지 / 마스터'가 분기되었는데, '지점을'버릴 '방법은 무엇입니까?


964

어떻게 든 내 마스터와 마스터 / 마스터 지점이 분기되었습니다.
나는 실제로 그들이 갈라지는 것을 원하지 않습니다.

이러한 차이점을보고 '병합'하려면 어떻게해야합니까?


2
분기한다는 것은 무슨 뜻입니까? 당신은 그것을 밀어 마스터를 rebase 합니까?
hasen

13
"지사와 '원산지 / 마스터'가 각각 분기되어 # 1과 1의 커밋이 각각 다릅니다"라는 메시지가 표시됩니다.
Frank

해당 "분산 된"경고 메시지를 반영하여 답변을 업데이트했습니다.
VonC

다른 질문에 대한 허용 대답은이 놀이에 올 수도 어떤 경우 해결에 도움이 될 수있다 (당신이 주변에 마스터를 이동하려는 예를 들어,하지만 이미 밀려 있었다) : stackoverflow.com/questions/2862590/...를
lindes

8
이 블로그에 대한 설명은 아래의 답변보다 더 많은 도움이되었습니다. sebgoo.blogspot.com/2012/02/…

답변:


1013

다음 과 같은 차이점검토 할 수 있습니다 .

git log HEAD..origin/master

전에 잡아 당겨 (+ 병합을 가져 오기) (참조 : "항상 특정 지점에서 당겨에 당신이 자식을 어떻게합니까?" )


다음과 같은 메시지가있을 때 :

"지점과 '원산지 / 마스터'가 각각 분기되어 각각 1 개와 1 개의 서로 다른 커밋이 있습니다."

업데이트가 필요한지origin 확인하십시오 . 경우 origin입니다 최신, 다음 몇 가지 커밋은 푸시 된 origin로컬 자신의 커밋을 만들어 동안 다른 REPO에서.

... o ---- o ---- A ---- B  origin/master (upstream work)
                   \
                    C  master (your work)

커밋 C는 커밋 A에 기반을 두었습니다. 그 이유는 당시 업스트림에서 가져온 최신 작업 이었기 때문입니다.

그러나 원점으로 돌아 가려고 시도하기 전에 다른 사람이 커밋 B를 푸시했습니다.
개발 기록은 별도의 경로로 분기되었습니다.

그런 다음 병합하거나 리베이스 할 수 있습니다. 자세한 내용은 Pro Git : Git Branching-Rebasing 을 참조하십시오.

병합

git merge 명령을 사용하십시오 :

$ git merge origin/master

이것은 Git에게 변경 사항을 origin/master작업 에 통합하고 병합 커밋을 만들도록 지시 합니다.
히스토리 그래프는 이제 다음과 같습니다.

... o ---- o ---- A ---- B  origin/master (upstream work)
                   \      \
                    C ---- M  master (your work)

새로운 병합 커밋 M에는 두 개의 부모가 있으며, 각 부모는 커밋에 저장된 내용으로 이어지는 하나의 개발 경로를 나타냅니다.

M 뒤에있는 이력은 이제 비선형입니다.

리베이스

git rebase 명령을 사용하십시오 :

$ git rebase origin/master

이것은 Git에게 커밋 C (작업)를 마치 A 대신 커밋 B에 기반한 것처럼 재생하도록 지시합니다.
CVS와 Subversion 사용자는 커밋 전에 업데이트 할 때 업스트림 작업 위에 로컬 변경 사항을 정기적으로 리베이스합니다.
Git은 커밋 단계와 리베이스 단계 사이에 명확한 분리를 추가합니다.

히스토리 그래프는 이제 다음과 같습니다.

... o ---- o ---- A ---- B  origin/master (upstream work)
                          \
                           C'  master (your work)

커밋 C '는 git rebase 명령으로 생성 된 새로운 커밋입니다.
두 가지 측면에서 C와 다릅니다.

  1. 다른 역사가 있습니다 : A 대신 B.
  2. 그 내용은 B와 C의 변화를 설명합니다. 병합 예제의 M과 동일합니다.

C '의 히스토리는 여전히 선형입니다.
우리는 (현재)에서 선형 이력 만 허용하도록 선택했습니다 cmake.org/cmake.git.
이 접근 방식은 이전에 사용 된 CVS 기반 워크 플로우를 유지하며 전환을 쉽게 할 수 있습니다.
C '를 리포지토리에 푸시하려는 시도가 작동합니다 (권한이 있고 재조정하는 동안 아무도 푸시하지 않았다고 가정).

git pull 명령은 원점에서 가져 와서 로컬 작업을 리베이스하는 간단한 방법을 제공합니다.

$ git pull --rebase

위의 페치 및 리베이스 단계를 하나의 명령으로 결합합니다.


5
같은 문제를 찾는 동안 이것을 찾았습니다. 왜 'git reset --hard HEAD'가 문제를 해결하지 못했는지 설명 할 수 있습니까?
Neth

12
@Neth : 단계별 수정 (예 : 색인에 있지만 아직 커밋되지 않은 수정)이 아니라 로컬 커밋 (원격에 존재하는 커밋과는 다름) 때문입니다. git reset --hard HEAD커밋되지 않은 로컬 인덱싱 된 수정 만 제거하고 로컬 커밋 과 원격 커밋 의 차이점을 조정하기 위해 아무 작업도 수행하지 않습니다 . 병합 또는 리베이스 만 두 커밋 세트 (로컬 및 원격 커밋)를 함께 가져옵니다.
VonC

4
와우,이 멋진 반응에 감사합니다. 우연히 "--rebase"없이 "git pull"을했고 "git rebase origin / master"는 그저 해결책 일뿐입니다!
mrooney

3
어떻습니까-로컬 변경 사항을 무시 / 덤프하고 리모컨이있는 로컬 지사와 함께하고 싶습니까? 다시 말해, 나는 당신의 모범 master을 지적 하고 싶습니다 B.
CygnusX1

23
@ CygnusX1 git reset --hard origin/master바로 아래 답변에서 언급 한 것처럼 : stackoverflow.com/a/8476004/6309
VonC

725

나는 이것을 가지고 있었고 위의 답변을 읽은 후에도 그 원인을 알 수 있습니다. 내 해결책은했다

git reset --hard origin/master

그런 다음 (원격) 원점 / 마스터로 표시되는 마스터 (내가 망친 것으로 가정)의 내 로컬 사본을 올바른 지점으로 재설정합니다.

경고 : 아직 변경하지 않은 모든 변경 사항을 잃게됩니다 origin/master.


21
네, 그것은 인형 옵션과 같은 느낌이 들지만, 실제 위험이 없으며 빠른 해결을 위해 여기에 있다면-이것은 효과가 있습니다 (어쨌든 나를 위해)
PandaWood

7
이 전에 마스터 분기에 있어야합니다 ( "git checkout master").
blueyed

이것은 원산지에서 최신 정보를 얻었을 때 한 번 나에게 일어난 다음 다른 사람이 원산지로 강제 푸시를 수행하여 이전 원산지 커밋이 되돌려졌습니다. 그래서 내 지역 지점은 되 돌린 커밋을 가지고 있었고, 원점에서 최신 정보를 가져 오려고했을 때 병합해야한다고 말하고있었습니다. 이 경우 문제가 이미 수정 되었기 때문에 --hard origin / (branch)를 재설정하는 것이 좋습니다.
랜든 포치

96
아마도 사용자에게 이것이 아직 시작되지 않은 모든 변경 사항을 잃게 할 것이라고 경고해야합니다.
Pedro Loureiro

6
@PedroLoureiro 커밋은 실제로 손실됩니다. 커밋을 찾 git reflog거나에서 볼 수 있습니다 gitk --all. 그러나 물론 하드 리셋은 리베이스와 다른 것입니다.
sebkraemer

52
git pull --rebase origin/master 

대부분의 시간에 도움을 줄 수있는 단일 명령입니다.

편집 : 오리진 / 마스터에서 커밋을 가져 와서 새로 가져온 분기 히스토리에 변경 사항을 적용합니다.


89
명령이 수행하는 것을 언급하십시오. 그렇지 않으면 사람들이 명령을 실행하여
망칠

1
문제가 없다면, 모든 변경 오리진 / 마스터를 포함하는 마스터로 끝나고 모든 로컬 커밋이 그 위에 재생됩니다. 나에게 좋은 것 같습니다.
Philipp Claßen

7
실제 차이가 있고 중단 된 리베이스에 빠지는 경우를 제외하고.
ffledgling

오류 : 오류 : 변경 사항을 병합하지 못했습니다. 0024 요청 및 응답 모델에서 패치 실패
IgorGanapolsky

32

원격 지점을 추적하는 지점 을 리베이스 하려고 할 때이 상황에서 자신을 발견 했으며 마스터에서 리베이스하려고했습니다. 이 시나리오에서 리베이스를 시도하면 분기가 분기 되어 git nubees가 아닌 엉망이 될 수 있습니다!

마스터에서 분기 한 my_remote_tracking_branch 지점에 있다고 가정 해 보겠습니다.

$ git status

# my_remote_tracking_branch 지점에서

커밋 할 것이 없음 (작업 디렉토리 정리)

이제 마스터에서 다음과 같이 리베이스하려고합니다.

자식 리베이스 마스터

지금 중지하고 문제를 해결하십시오! 대신 다음과 같이 merge를 사용하십시오.

자식 병합 마스터

예, 지점에서 추가 커밋이 발생합니다. 그러나 "배포 해제"브랜치를 사용하지 않는 한 리베이스 작업보다 훨씬 원활한 워크 플로가됩니다. 보다 자세한 설명 은 이 블로그 를 참조하십시오 .

당신의 지점 만있는 경우 반면에, 지역 지점은 확실히 REBASE을 수행해야합니다 (즉, 아직 원격 푸시되지 않음) (그리고 분기되지 않습니다 분기 이 경우).

당신이 이것을 읽고 있다면 지금 당신은 이미 때문 이다 시나리오 등 REBASE 때문에, 다시 마지막에 얻을 수 있습니다 사용하여 (미 - 갈라 상태 즉) 원점에서 커밋 "분기"에서 :

git reset --hard origin / my_remote_tracking_branch


5
일반적으로 rebaserebasing하는 지점이 게시되지 않았거나 다른 사람이 사용하지 않은 경우 사용 하는 것이 좋습니다. 그렇지 않으면을 사용하십시오 merge. 이미 게시하고 사용한 지점을 리베이스 한 경우 지점을 사용한 모든 개발자의 기록을 다시 작성하려면 음모를 조정해야합니다.
Mikko Rantalainen

1
불행히도 나는하기 전에이 메시지를 읽지 못했습니다 git rebase master...
Vitaly Isaev

분기 'foobar'에있는 동안 git rebase master를 수행하면 기술적으로 foobar가 git push -f 할 때까지 origin / foobar에서 분기됩니다.
relipse


1
git reset --hard origin/my_remote_tracking_branch실제로 작동 한 것
roothahn

24

내 경우에는 여기에 분산 된 메시지 를 유발하기 위해 수행 git push한 작업이 있습니다.git commit --amend 커밋 메시지에 무언가를 추가했습니다. 그런 다음 또 다른 커밋을했습니다.

그래서 제 경우에는 단순히 원산지 / 마스터가 오래되었다는 것을 의미했습니다. 나는 아무도 다른 감동 원산지 / 마스터 없었다 알고 있기 때문에, 수정 사소한했다 : git push -f (여기서 -f수단의 힘)


8
+1 git push -f이전에 커밋되고 푸시 된 변경 사항을 덮어 씁니다. 또한 아무도 저장소를 건드리지 않았다고 확신합니다.
zacharydl

4
매우 위험한 명령입니다. 명령의 위험 요소에 관한 간단한 정보를 작성하십시오.
J4cK

1
@Trickster : 이미 위험을 설명했습니다. "아무도 원산지 / 마스터에게 연락하는 사람이 아무도 없다는 것을 알았습니다." 나는이 경우 위험한 명령이 아니라고 생각합니다.
대런 쿡

1
누군가가 마스터를 저지른 다음 한 사람이 git push -f 명령을 실행하면 위험이 큰 명령입니다.
J4cK

11

내 경우에는 변경 사항을 푸시했습니다. origin/master 한 다음 그렇게하지 않아야한다는 것을 깨달았습니다.-(로컬 변경 사항이 하위 트리에 있다는 사실로 인해 복잡했습니다. 따라서 "나쁜"로컬 이전의 마지막 커밋으로 돌아갔습니다. SourceTree를 사용하여 변경 한 다음 "divergence message"를 받았습니다.

엉망을 로컬로 수정 한 후 (자세한 내용은 여기서 중요하지 않음) 원격 origin/master지점을 "시간으로 이동" 하여 로컬과 master다시 동기화되도록 했습니다. 내 경우의 해결책은 다음과 같습니다.

git push origin master -f

-f(강제) 스위치에 유의하십시오 . 이로 origin/master인해 실수 로 푸시 된 "잘못된 변경"이 삭제 되었으며 이제 로컬 및 원격 브랜치가 동기화되었습니다.

이 작업은 잠재적으로 파괴적인 작업이므로 원격 마스터를 "이전으로"이동 "할 수 있다는 것을 100 % 확신하는 경우에만 수행하십시오.


항상 유용하지만 반드시 질문에 대답하지는 않습니다.
Thibault D.

1
@ThibaultD. 그렇지 않은 경우에도 이것이 내가 찾던 것입니다.
Neil Chowdhury

을 받고 You are not allowed to force push code to a protected branch on this project.있습니다. 포크로 밀려 고합니다.
BanAnanas


5

나는 여기에 많은 답변이 있다는 것을 알고 있지만 git reset --soft HEAD~1마지막에 변경 사항을 유지할 수 있기 때문에주의를 기울여야 한다고 생각 합니다. 은 분기 된 상태를 해결하는 동안 로컬 (푸시되지 않은) 커밋의 합니다. 나는 이것이 풀보다 더 다재다능한 해결책이라고 생각한다rebase로컬 커밋을 검토하고 다른 지점으로 옮길 수 있기 때문에 이것이 .

열쇠는 --soft가혹한 대신에 사용하고 --hard있습니다. 커밋이 두 개 이상인 경우 변형 HEAD~x이 작동합니다. 내 상황을 해결하는 모든 단계는 다음과 같습니다 (원격에서 1 개의 로컬 커밋 및 8 개의 커밋이 있음).

1) git reset --soft HEAD~1 로컬 커밋을 취소합니다. 다음 단계에서는 SourceTree에서 인터페이스를 사용했지만 다음 명령도 작동해야한다고 생각합니다.

2) git stash 1)에서 변경 사항을 숨 깁니다. 이제 모든 변경 사항이 안전하고 더 이상 발산이 없습니다.

3) git pull 원격 변경 사항을 가져옵니다.

4) git stash pop 또는 git stash apply마지막 숨김 변경 사항을 적용한 다음 원하는 경우 새 커밋을 적용합니다. 이 단계는 로컬 커밋에서 변경 사항을 휴지통에 버릴 때 2) 와 함께 선택 사항입니다. 또한 다른 분기로 커밋하려면이 단계는 원하는 분기로 전환 한 후에 수행해야합니다.


실제로 요즘에는 pull --rebase어쨌든 자동으로 숨겨져 있습니다. stackoverflow.com/a/30209750/6309
VonC

4

차이점을 보려면

git difftool --dir-diff master origin/master

두 분기 간의 변경 또는 차이점이 표시됩니다. araxis (My favorite)에서는 폴더 diff 스타일로 표시합니다. 변경된 각 파일을 표시합니다. 그런 다음 파일을 클릭하여 파일 변경 내용을 자세히 볼 수 있습니다.


1
git-dir의 흥미로운 사용법 : +1
VonC

3

필자의 경우 이것은 충돌 해결을 저 지르지 않아 발생했습니다.

git pull명령 을 실행하여 문제점이 발생했습니다 . 원산지 변경으로 인해 로컬 리포지토리와 충돌이 발생하여 해결했습니다. 그러나 나는 그들을 저 지르지 않았다. 이 시점의 해결책은 변경 사항을 git commit확인 하는 것입니다 ( 해결 된 파일).

충돌을 해결 한 후 일부 파일도 git status수정 한 경우이 명령은 로컬 수정 사항을 준비되지 않은 로컬 수정으로 표시하고 병합 해결을 준비된 로컬 수정으로 표시합니다. 먼저 병합에서 변경 사항을 커밋 git commit한 다음 평소와 같이 스테이지되지 않은 변경 사항을 추가하고 커밋하여 (예 :에 의해 git commit -a) 이를 올바르게 해결할 수 있습니다 .


0

다음을 사용하여 이미 푸시 된 커밋의 마지막 커밋 메시지를 편집하려고 할 때 동일한 메시지 가 나타났습니다. 문제를 git commit --amend -m "New message" 사용 git push --force-with-lease repo_name branch_name하지 않고 변경 사항을 푸시했을 때 .


0

지점 A를 기반으로 지점을 만들 때이 문제를 해결했습니다.

git checkout -b a

그런 다음 분기 a의 업 스트림을 원점 B로 설정했습니다.

git branch -u origin/B

그런 다음 위의 오류 메시지가 나타납니다.

나를 위해이 문제를 해결하는 한 가지 방법은

  • 지점 삭제
  • 에 의해 새로운 지점 b를 만듭니다
git checkout -b b origin/B
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.