정말이 대답과 관련,하지만 난 도랑 것 아니 git pull
바로 실행이되는, git fetch
다음에 git merge
. 세 번의 병합을 수행하면 한 번의 가져 오기가 필요한 경우 Git에서 세 번의 가져 오기 작업을 실행하게됩니다. 그 후:
git fetch origin # update all our origin/* remote-tracking branches
git checkout demo # if needed -- your example assumes you're on it
git merge origin/demo # if needed -- see below
git checkout master
git merge origin/master
git merge -X theirs demo # but see below
git push origin master # again, see below
가장 까다로운 병합 제어
여기서 가장 흥미로운 부분은 git merge -X theirs
입니다. 으로 root545는 지적 의 -X
옵션은 병합 전략에 전달하고 기본 모두 recursive
전략과 대안 resolve
전략 포획 -X ours
또는 -X theirs
(둘 중 하나만). 하지만 그들이하는 일을 이해하려면 Git이 어떻게 병합 충돌을 찾고 처리하는지 알아야합니다 .
기본 버전 이 동일한 파일 의 현재 (로컬, HEAD 또는라고도 함 ) 버전 과 다른 (원격 또는이라고도 함 ) 버전 과 다를 때 일부 파일 1 내에서 병합 충돌이 발생할 수 있습니다 . 즉, 병합은 base, ours 및 theirs의 세 가지 개정 (세 개의 커밋)을 식별했습니다. "기본"버전은 커밋 그래프에서 볼 수 있듯이 커밋과 커밋 간의 병합 기반 에서 가져온 것 입니다 (이에 대한 자세한 내용은 다른 StackOverflow 게시물 참조). Git은 "우리가 한 일"과 "그들이 한 일"이라는 두 가지 변경 사항을 발견했습니다. 이러한 변경 사항은 (일반적으로) 한 줄씩 순전히 텍스트로 표시됩니다.--ours
--theirs
기초. Git은 파일 내용을 제대로 이해하지 못합니다. 단지 각 텍스트 줄을 비교하는 것입니다.
이러한 변경 사항은 git diff
출력에서 볼 수 있으며 항상 그렇듯이 컨텍스트 도 있습니다. 변경 한 내용이 변경된 내용과 다른 줄에있을 수 있으므로 변경 내용이 충돌하지 않는 것처럼 보이지만 컨텍스트도 변경되었습니다 (예 : 변경 내용이 파일의 상단 또는 하단에 가까워짐에 따라 그래서 우리 버전에서는 파일이 다 떨어지지 만 그들의 버전에서는 상단이나 하단에 더 많은 텍스트를 추가했습니다).
변경 사항에 일어날 경우 다른 라인-에 대한 예, 우리는 변화 color
에 colour
라인 (17)에 그들이 변경 fred
에 barney
줄에 71 다음 충돌이없는 : 힘내 간단합니다 모두 변경. 변경 사항이 동일한 줄에서 발생하지만 동일한 변경 사항 인 경우 Git은 변경 사항의 복사본 하나를 가져옵니다 . 변경 사항이 동일한 줄에 있지만 다른 변경 사항이거나 컨텍스트를 방해하는 특수한 경우에만 수정 / 수정 충돌이 발생합니까?
-X ours
과 -X theirs
우리, 또는 그들의 것을 : 옵션은 두 가지 변화 중 하나를 선택하여,이 충돌을 해결하는 방법을 망할 놈의 말. demo
(그들의)를 master
(우리의) 로 병합 하고에서 변경 사항을 demo
원한다고 말 했으므로 -X theirs
.
-X
그러나 맹목적으로 적용하는 것은 위험합니다. 변경 사항이 줄 단위로 충돌하지 않았다고해서 변경 사항이 실제로 충돌하지 않는다는 의미는 아닙니다! 한 가지 고전적인 예는 변수 선언이있는 언어에서 발생합니다. 기본 버전은 사용되지 않는 변수를 선언 할 수 있습니다.
int i;
우리 버전에서는 컴파일러 경고를 없애기 위해 사용되지 않는 변수를 삭제하고, 그 버전에서는 i
루프 카운터로 사용하여 몇 줄 후에 루프를 추가합니다 . 두 변경 사항을 결합하면 결과 코드가 더 이상 컴파일되지 않습니다. 이 -X
옵션은 변경 사항이 다른 행 에 있으므로 여기서는 도움이되지 않습니다 .
자동화 된 테스트 스위트가있는 경우 가장 중요한 것은 병합 후 테스트를 실행하는 것입니다. 커밋 후에이 작업을 수행하고 필요한 경우 나중에 수정할 수 있습니다. 또는 커밋 하기 전에 명령 에 추가 --no-commit
하여 수행 할 수 있습니다 git merge
. 이 모든 세부 사항은 다른 게시물에 남겨 둘 것입니다.
1 "파일 전체"작업과 관련하여 충돌이 발생할 수도 있습니다. 예를 들어 파일에서 단어의 철자를 수정하여 (변경할 수 있도록) 전체 파일 을 삭제 합니다 ( 지우다). Git은 -X
인수에 관계없이 이러한 충돌을 자체적으로 해결하지 않습니다 .
더 적은 병합 및 / 또는 더 스마트 한 병합 및 / 또는 리베이스 사용
두 명령 시퀀스 모두에 세 가지 병합이 있습니다. 첫 번째는 origin/demo
로컬 로 가져 오는 demo
것입니다 ( git pull
Git가 매우 오래된 경우 업데이트에 실패 origin/demo
하지만 동일한 최종 결과를 생성하는 사용자 사용). 두 번째는 가지고하는 것입니다 origin/master
으로 master
.
누가 업데이트 demo
하고 있는지 명확하지 않습니다 master
. 자신의 demo
브랜치 에 자신의 코드를 작성 하고 다른 사람들이 코드를 작성하여에서 demo
브랜치에 푸시하는 origin
경우이 첫 번째 단계 병합은 충돌을 일으키거나 실제 병합을 생성 할 수 있습니다. 종종 병합보다는 rebase를 사용하여 작업을 결합하는 것이 좋습니다 (분명히 이것은 취향과 의견의 문제입니다). 그렇다면 git rebase
대신 사용할 수 있습니다 . 당신이 당신의 자신의 커밋 중 하나가에하지 않을 경우 반면에 demo
, 당신도하지 않습니다 필요demo
지점을. 또는 많은 것을 자동화하고 싶지만, 당신과 다른 사람들이 만든 커밋이있을 때주의 깊게 확인할 수 있다면,git merge --ff-only origin/demo
: 이것은 가능한 경우 demo
업데이트 된 것과 일치하도록 빨리 감기 origin/demo
하고 그렇지 않은 경우 완전히 실패합니다 (이 시점에서 두 가지 변경 사항을 검사하고 적절하게 실제 병합 또는 리베이스를 선택할 수 있습니다).
이 동일한 논리가에 적용 master
되지만에서 병합 을 수행 master
하므로 반드시 master
. 그러나 빨리 감기 비 병합으로 수행 할 수없는 경우 병합이 실패하기를 원할 가능성이 더 높으므로이 역시 git merge --ff-only origin/master
.
.NET에서 직접 커밋을하지 않는다고 가정 해 봅시다 demo
. 이 경우 이름을 demo
완전히 버릴 수 있습니다 .
git fetch origin # update origin/*
git checkout master
git merge --ff-only origin/master || die "cannot fast-forward our master"
git merge -X theirs origin/demo || die "complex merge conflict"
git push origin master
당신이 경우에 하는 자신의 일 demo
지점 커밋이는 도움이되지 않습니다; 기존 병합을 유지 --ff-only
하거나 (원하는 동작 에 따라 추가 할 수 있음) 리베이스로 전환 할 수도 있습니다. 참고 모든 세 가지 방법이 실패 할 수 있음 : 병합 충돌이 실패 할 수 있습니다와 병합 --ff-only
빨리 감기를 할 수 없습니다 및 REBASE이 REBASE는 본질적으로 작동 (충돌이 실패 할 수 있습니다, 체리 따기 커밋, 병합을 사용하는 따라서 병합 충돌이 발생할 수 있습니다.
git push -f origin master