git-merge --dry-run 옵션이 있습니까?


725

많은 충돌이있을 수있는 원격 지점에서 병합하고 있습니다. 충돌 여부를 어떻게 알 수 있습니까?

나는 같은 것을 표시되지 않습니다 --dry-run에를 git-merge.


5
분기는 Git으로 저렴하기 때문에 사본을 체크 아웃 한 다음 드라이 런을 수행 할 필요가없는 이유는 무엇입니까? 나중에 사본을 버릴 수 있습니다.
Alexander Mills

답변:


812

앞에서 언급했듯이 --no-commit플래그를 전달 하지만 빨리 감기 커밋을 피하려면 다음 --no-ff과 같이 전달하십시오 .

$ git merge --no-commit --no-ff $BRANCH

단계적 변경 사항을 검토하려면 다음을 수행하십시오.

$ git diff --cached

빨리 감기 병합 인 경우에도 병합을 취소 할 수 있습니다.

$ git merge --abort

51
이것은 훌륭하지만 여전히 작업 사본을 수정합니다.
리포지토리

21
작업 복사본에 영향을주지 않으면 실제로 병합을 수행 할 수 없습니다.
mipadi 2016 년

55
사실이지만 정말 편리 git merge --only-if-there-wont-be-any-conflicts하거나 git diff --show-conflicts <commit>유용 할 것입니다. 아직 안타까운 일이 있거나 뭔가 빠졌습니까?
dave1010

344
@ dave1010 라이브 웹 서버에서 병합을 처리해서는 안됩니다 !!! 그것이 당신의 개발 박스를위한 것입니다! "prod"분기를 수정 한 다음 실제 웹 서버로 푸시하십시오.
jpswain 2012 년

52
라이브 / 프로덕션 서버에서 작업하는 경우에는 아무것도하고 싶지 않습니다 git pull --ff-only!
ThiefMaster

237

리포지토리와 원격 장치 간의 충돌을 자동으로 찾는 방법을 구현해야했습니다. 이 솔루션은 메모리에서 병합을 수행하므로 인덱스 또는 작업 트리를 건드리지 않습니다. 나는 이것이 당신 이이 문제를 해결할 수있는 가장 안전한 방법이라고 생각합니다. 작동 방식은 다음과 같습니다.

  1. 리모컨을 저장소로 가져옵니다. 예를 들면 다음과 같습니다. git fetch origin master
  2. git merge-base를 실행하십시오. git merge-base FETCH_HEAD master
  3. git merge-tree를 실행합니다 : git merge-tree mergebase master FETCH_HEAD( mergebase 는 이전 단계에서 merge-base가 인쇄 한 16 진수 ID입니다)

이제 원격 마스터를 로컬 마스터와 병합하려고하지만 모든 브랜치를 사용할 수 있다고 가정하십시오. git merge-tree메모리에서 병합을 실행하고 결과를 표준 출력에 인쇄합니다. 패턴에 대한 GREP <<>>. 또는 출력을 파일로 인쇄하여 확인할 수 있습니다. '둘 다 변경됨'으로 시작하는 행을 찾으면 충돌이있을 수 있습니다.


41
이 답변은 작업 복사본이나 색인을 건드리지 않고 깨끗한 솔루션이므로 IMHO는 과소 평가되었습니다.
sschuberth

23
BTW, 2 단계 및 3 단계는 Linux 콘솔의 백틱 연산자를 사용하여 한 단계로 병합 할 수 있습니다. Linux 콘솔의 내용을 평가합니다.git merge-tree `git merge-base FETCH_HEAD master` FETCH_HEAD master
jakub.g

15
.gitconfig의 [alias]에 추가 : dry = "! f () {git merge-tree`git merge-base $ 2 $ 1` $ 2 $ 1;}; f"# 마스터에 dev를 병합하는 방법을 확인하십시오 : git dry dev master
Noel

8
나의 새로운 fav GIT 라인 : git merge-tree `git merge-base clieop master` clieop master | grep -A3 "changed in both"Simply awesome! +100
Rudie

4
이것을 테스트 할 때 병합 충돌이 발생하지 않더라도 두 분기가 동일한 파일을 수정하는 '둘 다 변경됨'플래그 병합에 대한 grepping을 발견했습니다. 단지 실제 충돌을 식별하기 위해 나는 그것이 필요 충돌 마크 업에 대한 grep을 발견 그 같은 시작 : +<<<<<<< .our나는 같은 GREP 표현식을 사용하므로grep -q '^+<* \.our$'
남자

55

이것에 대한 나의 단순한 무차별 해결책은 다음과 같습니다.

  1. "사전 마스터"브랜치 작성 (마스터에서)

  2. 원하는 모든 것을이 프리 마스터에 병합하십시오.
    그러면 마스터를 건드리지 않고 병합이 어떻게되었는지 확인할 수 있습니다.

    • 프리 마스터를 마스터 OR로 병합
    • 지망생이 발표 한 모든 지점을 마스터로 병합

어쨌든 @ orange80의 조언을 따르겠습니다.


5
나는 @akostajti 솔루션을 좋아하지만 이것은 아직 과소 평가 된 옵션입니다. 사실 나는 방어적이고 새로운 임시 브랜치를 만들고 (물론 충돌이 예상되는 경우에만, 그렇지 않으면 과잉이 될 수 있습니다) 무언가 잘못되면 간단하게 삭제하십시오.
jakub.g

1
이것이 "더러운"해결책인지 아닌지는 모르지만 실제로는 그 일을합니다. 나는 그것을 좋아한다! (Y)
sara

3
이것이 허용되는 솔루션이어야합니다. 빠르고, 쉽고, 안전하고, 가역적이고, 직관적이며, 시작하기 전에 커밋되지 않은 변경 사항이 없으면 부작용이 없습니다.
Bob Ray

3
이 솔루션은 자식이 어떻게 작동하는지 이해하지 못한다고 알려줍니다. 분기는 포인터 일 뿐이며 중복 포인터 만 작성합니다. 당신은 당신이 어떻게 든 지점 합병을 해칠 수 있다는 나쁜 느낌을 가지고 있지만 그렇게 할 수는 없습니다. git merge --abort충돌 git reset --hard HEAD~1이 있거나 병합이있는 경우 언제든지 할 수 있습니다 git reset --hard origin/master. 다른 브랜치를 생성하면 안전감을 느낄 수 있지만 git의 작동 방식을 배우면 잘못 배치 된 두려움이라는 것을 알 수 있습니다. 작업 사본을 변경하지 않는 것이 우려되는 경우에는 해결책이 없습니다.
Thibault D.

@ thibault-d 깨끗한 브랜치로 시작하지 않을 때 솔루션이 얼마나 복잡한 지 생각해보십시오. git merge --no-commit빨리 감기 할 수 있으면 병합을 중단하지 않습니다. git merge --abort병합 된 경우 작동하지 않습니다. 이것을 스크립트로 작성 git merge하려면 다른 유형의 충돌을 설명하기에 충분한 오류 코드로 응답하지 않기 때문에 어색 합니다. 새로운 브랜치를 사용하면 손상된 스크립트가 리포지토리를 수동 개입이 필요한 상태로 유지하지 못합니다. 물론 당신은 아무것도 잃을 수 없습니다. 그러나 다른 방식으로 구축하는 것이 더 쉽습니다.
Erik Aronesty

47

git과의 병합을 취소하는 것은 너무 쉬워서 드라이 런에 대해 걱정하지 않아도됩니다.

$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world

편집 : 아래 주석에서 언급했듯이 작업 디렉토리 또는 준비 영역에 변경 사항이 있으면 위의 작업을 수행하기 전에 숨길 수 있습니다 (그렇지 않으면 위의 경우 사라집니다 git reset)


7
병합이 빨리 진행되는지 확인하는 것 (FF)은 git branch --contains HEAD직접 또는 더 직접 목록을 확인하는 문제입니다.git merge --ff-only
Brian Phillips

7
git reset --hard는 git이 가지고있는 정보를 삭제하지 않고 제거하는 명령 중 하나이므로 매우주의해서 사용해야합니다. 따라서 -1
Kzqai

8
@Tchalvak에는 여전히 reflog가 있습니다.
사키

3
--dry-run"병합이 빨리 진행되는지 간단히 확인"하지 않습니다. 병합은 파일, 충돌 등의 정확한 결과를 반환합니다. ff가 실제로 흥미롭지 않습니까?
Rudie

3
방법은 git stash; git reset --hard? @BrianPhillips
코드 위스퍼러

41

나는 이것을하기위한 별칭을 만들고 매력처럼 작동합니다.

 git config --global alias.mergetest '!f(){ git merge --no-commit --no-ff "$1"; git merge --abort; echo "Merge aborted"; };f '

이제 난 그냥 전화

git mergetest <branchname>

충돌이 있는지 확인합니다.


훌륭한! 나는 이것을 유지하고 있습니다.
qbert65536

28

현재 브랜치를 원격 브랜치와 비교하면 풀 / 병합시 변경되는 내용이 표시됩니다.

#see diff between current master and remote branch
git diff master origin/master

1
재미있는 생각. 해당 출력을보고 병합이 작동하는지 여부를 어떻게 결정합니까?
MatrixFrog

6
충돌이 발생하는지는 알 수 없지만 풀 / 병합을 수행 할 경우 발생할 수있는 일반적인 아이디어를 제공합니다.
timh

10
이것은 두 가지의 차이점만을 알려주고 병합 결과가 무엇인지는 알려주지 않습니다. 이는 병합이 커밋 된 시점에 따라 다른 브랜치에서 자동으로 변경을 수행하기 때문에 중요한 차이점입니다. 본질적으로 diff를 수행하면 실제로 변경 사항 중 일부가 되돌릴 것이라고 생각할 수 있으며 병합 프로세스는 이전 변경 사항보다 자동으로 새로운 변경 사항을 적용합니다. 이해가 되길 바랍니다.
markquezada

3
@mirthlab의 의견을 바탕으로 누군가 이전에 "우리의"병합 전략 (또는 다른 수동 병합 수정)과 병합을 수행 한 경우 diff와 merge 사이에 큰 차이가 있습니다. diff는 또한 이미 "병합 된"것으로 계산 된 차이를 표시합니다.
Tao

21

request-pull git 명령을 사용하여 그렇게합니다. 병합 할 때 발생할 수있는 모든 변경 사항을 볼 수 있지만 로컬 또는 원격 리포지토리에서 아무 작업도 수행하지 않습니다 .

예를 들어 "feature-x"라는 브랜치를 마스터 브랜치에 병합한다고 가정합니다.

git request-pull master origin feature-x

(어떤 일도하지 않고) 일어날 일에 대한 요약을 보여줍니다 :

The following changes since commit fc01dde318:
    Layout updates (2015-06-25 11:00:47 +0200)
are available in the git repository at:
    http://fakeurl.com/myrepo.git/ feature-x
for you to fetch changes up to 841d3b41ad:
----------------------------------------------------------------
john (2):
    Adding some layout
    Refactoring
ioserver.js            |   8 +++---
package.json           |   7 +++++-
server.js              |   4 +--
layout/ldkdsd.js       | 277 +++++++++++++++++++++++++++++++++++++
4 files changed, 289 insertions(+), 7 deletions(-)
create mode 100644 layout/ldkdsd.js

-p매개 변수 를 추가하면 변경된 모든 파일에 대해 git diff를 수행하는 것과 마찬가지로 전체 패치 텍스트가 표시됩니다.


3
당신은 추가하여이 조금 명확하게 수 있는지 masterorigin명령 줄 옵션에서 수행하고 제가 지방에 예를 들어 나는 경우에 대해 branch1하고 싶지 request-pull로컬 기능 분기에 branch2? 여전히 필요 origin합니까? 물론, 항상 문서를 읽을 수 있습니다.
Ela782

레브 # 2 분기 이름 인 경우 슬프게도,이 명령은이 해시 작동하지 않습니다, 작동합니다 /
자레드 그럽

20

아직 패치 사용을 제안한 사람이 아무도 없습니다.

당신이에서 병합을 테스트하고 싶은 말 your_branchmaster(난 당신이 있으리라 믿고있어 master체크 아웃) :

$ git diff master your_branch > your_branch.patch
$ git apply --check your_branch.patch
$ rm your_branch.patch

그 트릭을해야합니다.

다음과 같은 오류가 발생하면

error: patch failed: test.txt:1
error: test.txt: patch does not apply

이는 패치가 성공하지 못했으며 병합으로 인해 충돌이 발생했음을 의미합니다. 출력이 없다는 것은 패치가 깨끗하고 브랜치를 쉽게 병합 할 수 있음을 의미합니다


이것은 실제로 작업 트리를 변경 하지는 않습니다 (물론 패치 파일을 만드는 것 외에도 나중에 안전하게 삭제할 수 있습니다). git-apply 문서에서 :

--check
    Instead of applying the patch, see if the patch is applicable to the
    current working tree and/or the index file and detects errors. Turns
    off "apply".

나보다 git에 대해 더 똑똑하고 경험이 많은 사람에게주의하십시오. 여기서 내가 틀렸다면 알려주십시오.이 방법은 일반 병합과 다른 동작을 보여줍니다. 8 년 이상이 질문이 존재했다는 것은 아무도이 겉보기에 명백한 해결책을 제시하지 않을 것입니다.


이 방법은 이 질문에 허용되는 답변 이며 "git이 '재귀 적'병합 전략을 사용할 수 없습니다"및 "패치 파일에서 새 파일에 오류가 발생 함"과 같은 몇 가지주의 사항이 있습니다. 그렇지 않으면 좋을 것 같습니다.
neno

1
임시 패치 파일을 만들지 않는 더 짧은 방법 : git diff master your_branch | git apply --check.
ks1322

9

이것은 흥미로울 수 있습니다 : 문서에서 :

복잡한 충돌을 일으킨 병합을 시도하고 다시 시작하려는 경우 git merge --abort로 복구 할 수 있습니다 .

그러나 순진하지만 느린 방법으로도 할 수 있습니다.

rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)

(참고 : 커밋되지 않은 변경 사항이 충돌하지 않도록하려면 / tmp로 복제하는 것만으로는 작동하지 않습니다. 사본이 필요합니다).


2
당신이 필요한 전부 망치라면 ... :) +1
kaiser

클린 복사본을 얻을 수있다 cp -r repository/.git /tmp/repository/.git, cd /tmp/repository, git reset --hard, git add --all, git reset --hard(좋은 측정을 위해), git status(가 깨끗하는지 확인합니다).
ADTC

8

나는 이것이 오래된 질문이라는 것을 알고 있지만 Google 검색에 처음으로 나타납니다.

Git은 병합 할 때 --ff-only 옵션을 도입했습니다.

보낸 사람 : http://git-scm.com/docs/git-merge


--ff 전용

현재 HEAD가 이미 최신 상태이거나 병합을 빨리 진행할 수있는 경우가 아니면 0이 아닌 상태로 병합 및 종료를 거부하십시오.

이렇게하면 병합 및 빨리 감기가 시도되고, 실패하면 빨리 감기를 수행 할 수 없다는 메시지가 표시되고 작업 분기는 그대로 둡니다. 빨리 감을 수 있으면 작업 지점에서 병합을 수행합니다. 이 옵션은에서 사용할 수 있습니다 git pull. 따라서 다음을 수행 할 수 있습니다.

git pull --ff-only origin branchA #See if you can pull down and merge branchA

git merge --ff-only branchA branchB #See if you can merge branchA into branchB

1
원래 질문에서 원했던 것이 아닌 빨리 감기로 수행 할 수 있다면 병합을 수행합니다. 나는 받아 들인 대답이 그것을 고치는 다른 절반을 가지고 있다고 생각합니다.
Otto

실제로 멋진 git prompt는 이런 종류의 것들에 대한 필요성을 없애줍니다.
Otto

2
실제로 동일하지 않습니다. 빨리 감기를 수행한다고해서 충돌을 해결할 수 없으므로 병합이 0이 아닌 상태로 종료되는 것은 아닙니다 . 그것은 역사가 분기되었고 병합 커밋이 필요하다는 것을 의미합니다.
ADTC

7

git log를 사용하여 마스터 브랜치의 기능 브랜치에서 변경된 사항을 확인합니다.

git log does_this_branch..contain_this_branch_changes

예를 들어-피처 브랜치에 커밋이 무엇이고 마스터로 병합되지 않았는지 확인하려면 :

git log master..feature_branch

3

B에서 A로 빨리 감기하려면 git log B..A가 아무것도 표시하지 않는지 확인해야합니다. 즉 A에는 B에없는 것이 없습니다. 그러나 B..A에 무언가가 있어도 여전히 충돌없이 병합 할 수 있으므로 위의 두 가지 사항을 보여줍니다. 앞으로 빨리 갈 것이므로 충돌이 발생하지 않습니다.


2

내 해결책은 뒤로 병합하는 것입니다.

지점을 원격 "대상"지점으로 병합하는 대신 해당 지점을 귀하의 지점으로 병합하십시오.

git checkout my-branch
git merge origin/target-branch

충돌이 있는지 확인하고이를 해결하는 방법을 계획 할 수 있습니다.

그런 다음 git 통해 병합을 중단 merge --abort하거나 충돌이없고 병합이 발생한 경우를 통해 이전 커밋으로 롤백 할 수 있습니다.git reset --hard HEAD~1


-2

작업 사본의 임시 사본을 작성한 다음 병합하여 두 사본을 비교하십시오.

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