문제

다음을 사용하여 주제 분기 "B"를 "A"로 병합할 때 git merge, 약간의 충돌이 발생합니다."B" 버전을 사용하면 모든 충돌을 해결할 수 있다는 것을 알고 있습니다.

나는 알고있어 git merge -s ours.하지만 내가 원하는 것은 다음과 같습니다 git merge -s theirs.

왜 존재하지 않습니까?기존과 충돌하는 병합 후 동일한 결과를 얻으려면 어떻게 해야 합니까? git 명령?(git checkout B의 병합되지 않은 모든 파일)

업데이트:분기 A(트리의 B 버전에 대한 병합 커밋 지점)에서 무엇이든 삭제하는 "솔루션"은 내가 찾고 있는 것이 아닙니다.

도움이 되었습니까?

해결책

추가 -X 옵션 theirs. 예를 들어:

git checkout branchA
git merge -X theirs branchB

모든 것이 원하는 방식으로 합쳐질 것입니다.

문제를 일으킨 유일한 것은 파일이 BranchB에서 삭제 된 경우입니다. git 이외의 것이 제거를했다면 그들은 갈등으로 나타납니다.

수정은 쉽습니다. 그냥 실행 git rm 삭제 된 파일의 이름으로 :

git rm {DELETED-FILE-NAME}

그 후, -X theirs 예상대로 작동해야합니다.

물론, 실제 제거를 수행합니다 git rm 명령은 처음에 갈등이 일어나지 못하게합니다.


메모: 더 긴 형식 옵션도 존재합니다. 사용하려면 교체하십시오.

-X theirs

와 함께:

--strategy-option=theirs

다른 팁

체크 아웃 브랜치로 분기를 병합하기위한 가능한 테스트 솔루션 :

# in case branchA is not our current branch
git checkout branchA

# make merge commit but without conflicts!!
# the contents of 'ours' will be discarded later
git merge -s ours branchB    

# make temporary branch to merged commit
git branch branchTEMP         

# get contents of working tree and index to the one of branchB
git reset --hard branchB

# reset to our merged commit but 
# keep contents of working tree and index
git reset --soft branchTEMP

# change the contents of the merged commit
# with the contents of branchB
git commit --amend

# get rid off our temporary branch
git branch -D branchTEMP

# verify that the merge commit contains only contents of branchB
git diff HEAD branchB

자동화하려면 Brancha와 BranchB를 인수로 사용하여 스크립트로 랩핑 할 수 있습니다.

이 솔루션은 예상대로 합병 커밋의 첫 번째 및 두 번째 부모를 보존합니다. git merge -s theirs branchB.

이전 버전의 GIT를 사용하면 "그들의"병합 전략을 사용할 수있었습니다.

git pull --strategy=theirs remote_branch

그러나 이것은이 메시지에서 설명한대로 이후에 제거되었습니다. 주니오 하노 (GIT 관리자). 링크에서 언급했듯이 대신 다음을 수행합니다.

git fetch origin
git reset --hard origin

그러나 이것은 실제 병합과 다르다는 점을 고려하십시오. 솔루션은 아마도 당신이 정말로 찾고있는 옵션 일 것입니다.

나는 지금부터 Paul Pladijs의 답을 사용했습니다. 나는 당신이 "정상적인"합병을 할 수 있고, 충돌이 발생할 수 있습니다.

git checkout --theirs <file>

다른 지점의 개정을 사용하여 갈등을 해결합니다. 각 파일에 대해이 작업을 수행하면 예상 한 것과 동일한 동작이 있습니다.

git merge <branch> -s theirs

어쨌든, 노력은 병합-스트레이트와의 노력 이상입니다! (이것은 GIT 버전 1.8.0으로 테스트되었습니다)

원하는 결과가 무엇인지는 완전히 명확하지 않으므로 답과 의견에이를 수행하는 "올바른"방법에 대한 혼란이 있습니다. 개요를 제공하고 다음 세 가지 옵션을 보려고합니다.

병합을 시도하고 충돌에 B를 사용하십시오

이것은 ~ 아니다 "그들의 버전 git merge -s ours"그러나"그들의 버전 git merge -X ours"(짧은 git merge -s recursive -X ours):

git checkout branchA
# also uses -s recursive implicitly
git merge -X theirs branchB

이것이 바로 예를 들어 Alan W. Smith의 답변 하다.

B에서만 콘텐츠를 사용하십시오

이것은 두 가지 모두에 대한 병합 커밋을 생성하지만 모든 변경 사항을 폐기합니다. branchA 그리고 내용을 보관합니다 branchB.

# Get the content you want to keep.
# If you want to keep branchB at the current commit, you can add --detached,
# else it will be advanced to the merge commit in the next step.
git checkout branchB

# Do the merge an keep current (our) content from branchB we just checked out.
git merge -s ours branchA

# Set branchA to current commit and check it out.
git checkout -B branchA

합병은 이제 첫 부모가 branchB 그리고 두 번째는 branchA. 이것이 바로 예를 들어 Gandalf458의 답변 하다.

B에서만 콘텐츠를 사용하고 수정 부모 주문을 유지하십시오.

이것은 진짜 "그들의 버전입니다 git merge -s ours". 이전 옵션에서와 동일한 내용이 있습니다 (즉, branchB)하지만 부모의 질서는 정확합니다. 즉, 첫 부모는 branchA 그리고 두 번째 branchB.

git checkout branchA

# Do a merge commit. The content of this commit does not matter,
# so use a strategy that never fails.
# Note: This advances branchA.
git merge -s ours branchB

# Change working tree and index to desired content.
# --detach ensures branchB will not move when doing the reset in the next step.
git checkout --detach branchB

# Move HEAD to branchA without changing contents of working tree and index.
git reset --soft branchA

# 'attach' HEAD to branchA.
# This ensures branchA will move when doing 'commit --amend'.
git checkout branchA

# Change content of merge commit to current index (i.e. content of branchB).
git commit --amend -C HEAD

이것이 무엇입니다 Paul Pladijs의 대답 (임시 지점을 요구하지 않고).

사용한 문제를 해결했습니다

git checkout -m old
git checkout -b new B
git merge -s ours old

당신이 지점에 있다면 :

git merge -s recursive -X theirs B

GIT 버전 1.7.8에서 테스트

"A"에서 GIT 병합을 사용하여 주제 지점을 병합 할 때 약간의 충돌이 발생합니다. 나는 "B"의 버전을 사용하여 모든 충돌을 해결할 수 있다는 것을 알고 있습니다.

나는 git merge -s 우리를 알고 있습니다. 그러나 내가 원하는 것은 git merge> -s와 같은 것입니다.

나는 당신이 마스터에서 지점을 만들었고 이제는 마스터의 오래된 것들을 무시하고 마스터로 다시 합병하고 싶다고 가정합니다. 이것이 바로이 게시물을 발견했을 때 내가하고 싶었던 것입니다.

한 가지를 먼저 다른 분기로 병합하는 것을 제외하고는 원하는 일을 정확히하십시오. 나는 방금 이것을했다. 그리고 그것은 훌륭하게 작동했다.

git checkout Branch
git merge master -s ours

그런 다음 체크 아웃 마스터 및 지점을 병합합니다 (지금은 순조롭게 진행됩니다).

git checkout master
git merge Branch

실제로 합병을 수행하려면 합병하는 지점에서 입력 할 수 있습니다.

git merge --strategy=ours ref-to-be-merged

git diff --binary ref-to-be-merged | git apply --reverse --index

git commit --amend

내가 아는 모든 시나리오에는 충돌이 없을 것입니다. 추가 지점을 만들 필요가 없으며 정상적인 병합 커밋처럼 작용합니다.

그러나 이것은 하위 모듈에서 좋지 않습니다.

보다 Junio ​​Hamano의 널리 인용되는 답변:커밋된 콘텐츠를 삭제하려면 커밋을 삭제하거나 기본 기록에서 제외하세요.앞으로 아무 것도 제공하지 않는 커밋의 커밋 메시지를 읽는 모든 사람을 귀찮게 할 이유가 무엇입니까?

그러나 때로는 관리적 요구 사항이나 다른 이유가 있을 수도 있습니다.아무 것도 기여하지 않는 커밋을 기록해야 하는 상황에서는 다음을 원합니다.

(편집하다:와, 내가 전에 이걸 틀렸었나요?이것은 작동합니다.)

git update-ref HEAD $(
        git commit-tree -m 'completely superseding with branchB content' \
                        -p HEAD -p branchB    branchB:
)
git reset --hard

왜 존재하지 않습니까?

"에서 언급하는 동안하나의 브랜치를 다른 브랜치처럼 만드는 git 명령"시뮬레이트하는 방법 git merge -s theirs, Git 2.15(2017년 4분기)가 이제 더 명확해졌습니다.

'에 대한 문서-X<option>'합병은-s theirs"라는 내용이 있는데, 그렇지 않습니다.

보다 c25d98b를 커밋하다 (2017년 9월 25일) 주니오 C 하마노(gitster).
(병합자: 주니오 C 하마노 -- gitster -- ~에 커밋 4da3e23, 2017년 9월 28일)

병합 전략:"라고 암시하지 마십시오.-s theirs"가 존재한다

설명 -Xours 병합 옵션에는 독자에게 매우 다르다고 말하는 괄호 안에 있습니다. -s ours, 그것은 정확하지만 설명입니다 -Xtheirs 그것은 부주의하게 "이것은 반대입니다. ours"독자들도 매우 다르다는 경고를 받아야한다는 잘못된 인상을줍니다. -s theirs, 실제로는 존재하지도 않습니다.

-Xtheirs전략 옵션 재귀 전략에 적용됩니다.이는 재귀 전략이 가능한 모든 것을 병합하고 "theirs" 충돌이 발생할 경우 논리.

그 타당성 여부에 대한 논쟁 theirs 병합 전략이 최근에 다시 시작되었습니다. 이번 9월에2017 스레드.
그것은 인정한다 이전 (2008) 스레드

요컨대 앞선 논의는 '우리는 원하지 않는다'로 요약할 수 있다.-s theirs' 잘못된 작업 흐름을 조장하기 때문입니다.

별칭이 언급되어 있습니다.

mtheirs = !sh -c 'git merge -s ours --no-commit $1 && git read-tree -m -u $1' -

야로슬라프 할첸코(Yaroslav Halchenko)는 다시 한 번 그 전략을 옹호하려고 합니다. 하지만 주니오 C.하마노가 덧붙인다:

우리와 그들의 것이 대칭적이지 않은 이유는 당신이 그들이 아니라 당신이기 때문입니다. 우리의 역사와 그들의 역사에 대한 통제와 소유권은 대칭적이지 않습니다.

그들의 역사가 메인라인이라고 결정했다면, 개발 라인을 사이드 브랜치로 취급하고 그 방향으로 병합하는 것이 좋습니다.결과 병합의 첫 번째 부모는 해당 기록에 대한 커밋이고 두 번째 부모는 기록의 마지막 나쁜 부모입니다.그래서 당신은 "를 사용하게 될 것입니다.checkout their-history && merge -s ours your-history"첫부모를 현명하게 유지합니다.

그리고 그 시점에서 "-s ours"는 더 이상 " 부족에 대한 해결 방법이 아닙니다.-s theirs".
이는 원하는 의미의 적절한 부분입니다.살아남은 정경 역사 계열의 관점에서 볼 때, 당신은 그것이 한 일을 보존하고 다른 역사 계열이 한 일을 무효화하기를 원합니다..

이것은 GIT 배관 명령 판독-트리를 사용하지만 전체 워크 플로를 더 짧게 만듭니다.

git checkout <base-branch>

git merge --no-commit -s ours <their-branch>
git read-tree -u --reset <their-branch>
git commit

# Check your work!
git diff <their-branch>

이것은 기존 BaseBranch에서 NewBranch를 병합합니다

git checkout <baseBranch> // this will checkout baseBranch
git merge -s ours <newBranch> // this will simple merge newBranch in baseBranch
git rm -rf . // this will remove all non references files from baseBranch (deleted in newBranch)
git checkout newBranch -- . //this will replace all conflicted files in baseBranch

나는 당신이 실제로 원하는 것은 다음과 같습니다.

git checkout -B mergeBranch branchB
git merge -s ours branchA
git checkout branchA
git merge mergeBranch
git branch -D mergeBranch

이것은 서투른 것처럼 보이지만 작동해야합니다. 내가이 솔루션에 대해 정말로 싫어하는 유일한 생각은 git 역사가 혼란 스러울 것이라는 것입니다 ... 그러나 적어도 역사는 완전히 보존 될 것이며 삭제 된 파일에 특별한 일을 할 필요는 없습니다.

'git merge -s iss branchb'에 해당하는 (부모 질서를 유지하는)

병합 전 :enter image description here

!!!!!!!! 당신이 깨끗한 상태인지 확인하십시오 !!!

병합 :

git commit-tree -m "take theirs" -p HEAD -p branchB 'branchB^{tree}'
git reset --hard 36daf519952 # is the output of the prev command

우리는 무엇을 했습니까? 우리는 우리의 두 부모와 그들의 두 부모와 커밋의 콘넷이 Branchb를 만들었습니다.

병합 후 :enter image description here

더 정확하게:

git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'

이 답변은 Paul Pladijs에 의해 주어졌습니다. 방금 그의 명령을 받아 편의를 위해 git 별칭을 만들었습니다.

.gitConfig를 편집하고 다음을 추가하십시오.

[alias]
    mergetheirs = "!git merge -s ours \"$1\" && git branch temp_THEIRS && git reset --hard \"$1\" && git reset --soft temp_THEIRS && git commit --amend && git branch -D temp_THEIRS"

그런 다음 실행하여 "git merge -s ys"를 사용할 수 있습니다.

git checkout B (optional, just making sure we're on branch B)
git mergetheirs A

나는 최근 공통 기록을 공유하는 두 개의 별도 리포지토리를 위해이 작업을 수행해야했습니다. 나는 시작했다 :

  • Org/repository1 master
  • Org/repository2 master

나는 모든 변화를 원했다 repository2 master 적용됩니다 repository1 master, 리포지토리 2가 할 모든 변경 사항을 수락합니다. git의 용어로는, 이것 ~해야 한다 전략이라는 전략이 되십시오 -s theirs 그러나 존재하지 않습니다. 주의하십시오 -X theirs 당신이 원하는 것 같지만 아니다 마찬가지로 (사람 페이지에서도 그렇게 말합니다).

내가 이것을 해결 한 방식은가는 것이 었습니다 repository2 그리고 새로운 지점을 만드십시오 repo1-merge. 그 지점에서 나는 달렸다 git pull git@gitlab.com:Org/repository1 -s ours 그리고 문제없이 잘 통합됩니다. 그런 다음 리모컨으로 밀어 넣습니다.

그런 다음 돌아갑니다 repository1 그리고 새로운 지점을 만드십시오 repo2-merge. 그 지점에서 나는 달린다 git pull git@gitlab.com:Org/repository2 repo1-merge 문제가 완료됩니다.

마지막으로 병합 요청을 발행해야합니다. repository1 그것을 새로운 마스터로 만들거나 단지 지점으로 유지하기 위해.

단순하고 직관적 인 (내 의견으로는) 2 단계 방법은

git checkout branchB .
git commit -m "Picked up the content from branchB"

그 뒤에

git merge -s ours branchB

(두 가지가 합병 된 것으로 표시)

유일한 단점은 현재 분기에서 분기에서 삭제 된 파일을 제거하지 않는다는 것입니다. 나중에 두 가지 사이의 간단한 차이는 그러한 파일이 있는지 보여줍니다.

이 접근법은 또한 수행 한 작업과 의도 된 내용 이후 개정 로그에서 명확하게 설명합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top