git rebase를 수행 할 때 종종 충돌을 해결할 때 ‘local’및 ‘remote’로 발생하는 문제를 해결하는 데 어려움이 있습니다. 때때로 그들은 한 커밋에서 다음 커밋으로 사이드를 바꾼다는 인상을받습니다.
내가 아직도 제대로 이해하지 못했기 때문에 이것은 아마도 (확실히)입니다.
Rebasing 할 때 누가 ‘로컬’이고 누가 ‘원격’입니까?
(충돌을 해결하기 위해 P4Merge를 사용합니다)
답변
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
local
인A
(병합 으로 )remote
이다B
리베이스 스위치 ours
(리베이스가 시작되기 전의 현재 분기) 및 theirs
(위의 리베이스하려는 분기).
kutschkem , 지적를 GUI를의 mergetool 컨텍스트에서 :
- 로컬 참조 부분적으로 재 기반 된 커밋 : ”
ours
“(업스트림 브랜치) - remote는 들어오는 변경을 나타냅니다 . ”
theirs
“-리베이스 이전의 현재 분기.
이 답변의 마지막 부분에있는 그림을보십시오.
리베이스시 반전
혼란은 관련이있을 수도 의 반전 ours
과 theirs
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
는 먼저 HEAD
B를 업스트림 지점으로 변경합니다 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
‘
나를 위해, 여전히 “로컬”이고 누가 “원격”인지에 대한 질문이 남아 있습니다 ( “우리의”및 “그들의”라는 용어는 자식으로 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 는 다음 과 같이 병합 해상도를 표시합니다 .
git mergetool -t gvimdiff를 사용하여 Vimdiff를 mergetool로 호출하십시오. 최신 버전의 Git은 다음과 같은 창 레이아웃으로 Vimdiff를 호출합니다.
+--------------------------------+
| LOCAL | BASE | REMOTE |
+--------------------------------+
| MERGED |
+--------------------------------+
LOCAL
:
현재 분기의 파일 내용이 포함 된 임시 파일입니다.BASE
:
병합의 공통 기반을 포함하는 임시 파일입니다.REMOTE
:
병합 할 파일의 내용이 포함 된 임시 파일입니다.MERGED
:
충돌 마커가 포함 된 파일입니다.힘내 가능한 한 자동 충돌 해결로 수행하고이 파일의 상태는 모두의 조합
LOCAL
및REMOTE
힘내 자체를 해결할 수 없다는 것을 둘러싼 갈등 마커.
는mergetool
이 파일을 해상도의 결과를 작성해야합니다.
답변
결론
자식 리베이스
- 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)
결과는 위에 표시된 것과 동일해야합니다.