git rebase, 'local'및 'remote'추적


174

git rebase를 수행 할 때 종종 충돌을 해결할 때 'local'및 'remote'로 발생하는 문제를 해결하는 데 어려움이 있습니다. 때때로 그들은 한 커밋에서 다음 커밋으로 사이드를 바꾼다는 인상을받습니다.

내가 아직도 제대로 이해하지 못했기 때문에 이것은 아마도 (확실히)입니다.

Rebasing 할 때 누가 '로컬'이고 누가 '원격'입니까?

(충돌을 해결하기 위해 P4Merge를 사용합니다)


이것을 읽는 것이 도움 될 수 있습니까? 이 튜토리얼의 나머지 부분도 매우 유용합니다.
Ivans

또 다른 훌륭한 자식 리소스 .
알 수없는

겠습니까 stackoverflow.com/questions/2959443/... 도움을? ( ' git svn'부분이 아니라 ' git rebase'부분 만)
VonC

@VonC, 그렇습니다. 정확합니다. 당신이 여기에 당신의 대답의 관련 비트를 복사하려면, 나는 그것을 체크합니다 (정말 이번에 약속합니다!)
Benjol

알았어 ... 물린거야.) 관련 추출물이 게시되었습니다.
VonC

답변:


244

TL; DR;

다음과 같은 경우에 ( Benubird 의견으로 ) 요약 하면 :

git checkout A
git rebase   B    # rebase A on top of B
  • local되고 B(리베이스 )
  • remote 이다 A

과:

git checkout A
git merge    B    # merge B into A
  • localA(병합 으로 )
  • remote 이다 B

리베이스 스위치 ours(리베이스가 시작되기 전의 현재 분기) 및 theirs(위의 리베이스하려는 분기).


kutschkem , 지적를 GUI를의 mergetool 컨텍스트에서 :

  • 로컬 참조 부분적으로 재 기반 된 커밋 : " ours"(업스트림 브랜치)
  • remote는 들어오는 변경을 나타냅니다 . " theirs"-리베이스 이전의 현재 분기.

이 답변의 마지막 부분에있는 그림을보십시오.


리베이스시 반전

혼란은 관련이있을 수도 의 반전 ourstheirsREBASE 동안 .
(관련 추출물)

git rebase매뉴얼 페이지 :

리베이스 병합은 분기 위의 작업 분기에서 각 커밋을 재생하여 작동합니다 <upstream>.

이로 인해 병합 충돌이 발생할 때 :

  • ' ours' 로보고 된 측은로 시작하는 지금까지의 시리즈입니다 <upstream>.
  • ' theirs'는 작업 지점입니다. 다시 말해, 측면이 서로 바뀝니다.

반전 설명

합병

x--x--x--x--x(*) <- current branch B ('*'=HEAD)
    \
     \
      \--y--y--y <- other branch to merge

현재 지점 'B'를 변경하지 않으므로 현재 작업중인 작업은 여전히 ​​진행중인 작업입니다 (다른 지점에서 병합).

x--x--x--x--x---------o(*)  MERGE, still on branch B
    \       ^        /
     \     ours     /
      \            /
       --y--y--y--/  
               ^
              their

리베이스에서 :

그러나 REBASE에 REBASE가 맨 처음에하는 일이 업스트림 브랜치를 체크 아웃하기 때문에, 우리는 측면을 전환! (현재 커밋을 재생하기 위해)

x--x--x--x--x(*) <- current branch B
    \
     \
      \--y--y--y <- upstream branch

A git rebase upstream는 먼저 HEADB를 업스트림 지점으로 변경합니다 HEAD(따라서 이전 "현재"작업 지점과 비교하여 '우리'와 '그들의'전환).

x--x--x--x--x <- former "current" branch, new "theirs"
    \
     \
      \--y--y--y(*) <- upstream branch with B reset on it,  
                       new "ours", to replay x's on it

리베이스는 새로운 '우리'B 브랜치에서 '그들의'커밋을 재생합니다.

x--x..x..x..x <- old "theirs" commits, now "ghosts", available through reflogs
    \
     \
      \--y--y--y--x'--x'--x'(*) <-  branch B with HEAD updated ("ours")
               ^
               |
        upstream branch

참고 : "업스트림"개념 은 데이터를 읽거나 새 데이터를 추가 / 작성 하는 참조 데이터 세트 (모든 리포지토리 또는 여기에서와 같이 분기 ( 로컬 분기 일 수 있음 ))입니다.


' local'및 ' remote'vs. ' mine'및 ' theirs'

Pandawood주석에 다음을 추가합니다 .

나를 위해, 여전히 "로컬"이고 누가 "원격"인지에 대한 질문이 남아 있습니다 ( "우리의"및 "그들의"라는 용어는 자식으로 rebasing 할 때 사용되지 않기 때문에 더 혼란스럽게 대답합니다) .

GUI 자식 병합 도구

kutschkem은 다음과 같이 덧붙입니다.

충돌을 해결할 때 git은 다음과 같이 말합니다.

local: modified file and remote: modified file. 

이 질문은이 시점에서 로컬 및 원격의 정의를 목표로하고 있다고 확신합니다. 그 시점에서 내 경험으로는 다음과 같이 보입니다.

  • 로컬 참조 부분적으로 재 기반 된 커밋 : " ours"(업스트림 브랜치)
  • remote는 들어오는 변경을 나타냅니다 . " theirs"-리베이스 이전의 현재 분기.

git mergetool실제로 'local'과 'remote'를 언급합니다 .

Merging:
f.txt

Normal merge conflict for 'f.txt':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (kdiff3):

예를 들어 KDiff3 는 다음 과 같이 병합 해상도를 표시합니다 .

kdiff3

그리고 MELD는 것입니다 그것을 너무 표시 :

녹은 차이

대한 동일 VimDiff , 디스플레이 :

git mergetool -t gvimdiff를 사용하여 Vimdiff를 mergetool로 호출하십시오. 최신 버전의 Git은 다음과 같은 창 레이아웃으로 Vimdiff를 호출합니다.

+--------------------------------+
| LOCAL  |     BASE     | REMOTE |
+--------------------------------+
|             MERGED             |
+--------------------------------+
  • LOCAL:
    현재 분기의 파일 내용이 포함 된 임시 파일입니다.
  • BASE:
    병합의 공통 기반을 포함하는 임시 파일입니다.
  • REMOTE:
    병합 할 파일의 내용이 포함 된 임시 파일입니다.
  • MERGED:
    충돌 마커가 포함 된 파일입니다.

힘내 가능한 한 자동 충돌 해결로 수행하고이 파일의 상태는 모두의 조합 LOCALREMOTE힘내 자체를 해결할 수 없다는 것을 둘러싼 갈등 마커.
mergetool이 파일을 해상도의 결과를 작성해야합니다.


13
나를 위해, 여전히 "로컬"이고 누가 "원격"인지에 대한 질문이 남아 있습니다 ( "우리의"및 "그들의"라는 용어는 자식으로 rebasing 할 때 사용되지 않기 때문에 더 혼란스럽게 대답합니다) . 문제는 "누가 현지인이며 누가 원격에 있는지"입니다. 따라서 답은 반드시 "로컬"과 "원격"이라는 단어를 언급해야합니다.
PandaWood

@PandaWood : "local"은 "현재 지점"( "그들의"이 됨)이고 "원격"은 "상류 지점"( "우리의"이 됨)입니다.
VonC

3
그래서, 요약 : 당신이 때 git checkout A; git rebase B지역 B이며, 원격 A. 모든 내가 알 필요는 ...
Benubird

1
git은 그러한 클러스터의 유용성입니다. 이것은 아무 의미 : 당신이 때 git checkout A; git rebase B지역 B이고, 멀리 떨어진입니다 . 내가하면 checkout A그때 하고 그들이에 존재하는 현재 파일을보고 A, 어떤 식으로의 해당 어떻게 원격는 ? (나는 Benubird가 잘못되었다고 말하는 것이 아니라 git에 바보 같은 UX가 있다고 말하고있다)
Rafa

1
확실히 @VonC; 필자의 요점은 문서를 읽고, 다이어그램을보고, StackOverflow를 찾아 보지 않아도된다는 것입니다. 명령 만 명확하고 명확한 피드백을 제공 한 경우. 예를 들어, 대신 원격 / 로컬 / 그들의 / 우리 / 내 / 당신의 단지 보여 {branch A}{branch B}또는 유사한.
라파

45

결론

자식 리베이스

  • LOCAL = 당신이 리베이스하고 기본
  • REMOTE = 위로 이동하는 커밋

자식 병합

  • LOCAL = 병합하려는 원래 지점
  • REMOTE = 커밋하려는 다른 지점

즉, LOCAL 은 항상 원본이고 REMOTE 는 항상 커밋이 없었던 사람입니다.

증명해!

확실히. 내 말을 받아들이지 마라! 다음은 직접 확인할 수있는 간단한 실험입니다.

먼저 git mergetool이 올바르게 구성되어 있는지 확인하십시오. (그렇지 않으면이 질문을 읽지 않았을 것입니다.) 그런 다음 작업 할 디렉토리를 찾으십시오.

저장소를 설정하십시오.

md LocalRemoteTest
cd LocalRemoteTest

빈 파일을 사용하여 초기 커밋을 만듭니다.

git init
notepad file.txt  (use the text editor of your choice)
  (save the file as an empty file)
git add -A
git commit -m "Initial commit."

마스터가 아닌 지점에 커밋을 만듭니다.

git checkout -b notmaster
notepad file.txt
  (add the text: notmaster)
  (save and exit)
git commit -a -m "Add notmaster text."

마스터 브랜치에서 커밋을 만듭니다.

git checkout master
notepad file.txt
  (add the text: master)
  (save and exit)
git commit -a -m "Add master text."

gitk --all

이 시점에서 저장소는 다음과 같아야합니다.

기본 커밋과 두 개의 커밋이있는 리포지토리

이제 rebase 테스트의 경우 :

git checkout notmaster
git rebase master
  (you'll get a conflict message)
git mergetool
  LOCAL: master
  REMOTE: notmaster

이제 병합 테스트입니다. 변경 사항을 저장하지 않고 mergetool을 닫은 다음 리베이스를 취소하십시오.

git rebase --abort

그때:

git checkout master
git merge notmaster
git mergetool
  LOCAL: master
  REMOTE: notmaster
git reset --hard  (cancels the merge)

결과는 위에 표시된 것과 동일해야합니다.


1
+1. 그것은 위의 자신의 대답에서 어려워했던 local/ remote측면을 분명히합니다 ( 어쨌든 ours대 반전에 관한 theirs것입니다)
VonC

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