변경된 모든 파일이 부모 중 하나와 동의 할 때도 결합 된 diff 출력으로 병합 커밋을 "git show"하는 방법은 무엇입니까?


186

"간단한"병합 (충돌이없는 병합)을 수행 한 후 git show일반적으로

commit 0e1329e551a5700614a2a34d8101e92fd9f2cad6 (HEAD, master)
Merge: fc17405 ee2de56
Author: Tilman Vogel <email@email>
Date:   Tue Feb 22 00:27:17 2011 +0100

Merge branch 'testing' into master

병합 git show의 경우 상위 버전 중 하나와 일치하는 파일을 생략하는 결합 된 diff 형식을 사용 하기 때문 입니다.

결합 된 diff 모드에서 git이 여전히 모든 차이점을 표시하도록하는 방법이 있습니까?

수행하면 git show -m차이점이 표시되지만 (새 버전과 모든 상위 버전 사이에 쌍으로 차이를 사용) 조합 모드와 같이 각 열에서 차이가 +/-로 표시되는 것을 선호합니다.


1
@ Tilman Vogel : 허용되는 답변을 검토하십시오-더 나은 답변이있는 것 같습니다
Jayan

1
@Jayan 다른 답변은 유용한 힌트가 포함되어 있기 때문에 더 인기가 있지만 실제로는 양방향 diff를 수행하는 것처럼 내 문제에 더 가까이 가지 않습니다. 나는 3 방향 diff를 찾고 있었다.
Tilman Vogel 2018

답변:


-3

아니요,으로 할 수있는 방법이 없습니다 git show. 그러나 그것은 확실히 때로는 좋은 것, 그것은 아마도 비교적 쉽게 (모든 후, 당신은 단지 그것을 말하고있는 자식 소스 코드에 구현하는 것입니다 하지 패치 그렇게 할 수 있도록, 그것은 외부 출력은 어떻게 생각하는지 알아 트림) 아마도 자식 관리자가 받아 들일 것입니다.

그래도 원하는 것을 조심하십시오. 3 개월 전에 분기 된 한 줄 변경으로 지점을 병합하면 여전히 메인 라인에 비해 차이 가있을 것이므로 이러한 완전한 차이는 거의 완전히 도움이되지 않습니다. 그것이 git이 보여주지 않는 이유입니다.


12
"가능하지 않은 방법"이라고 명확하게 말하지 마십시오. 다른 답변을 참조하십시오. 이것은 매우 잘못된 말입니다.
kgadek

1
git show HEAD ^ ... HEAD; # @ hesham_EE의 솔루션 당.
Michael Dimmitt

git show HEAD ~ 1 ... HEAD ~ 0-이름 만; # 더 나은 구문. 홍보를 반복합니다.
Michael Dimmitt 1

256

커밋 메시지를 살펴보십시오.

commit 0e1329e551a5700614a2a34d8101e92fd9f2cad6 (HEAD, master)
Merge: fc17405 ee2de56
Author: Tilman Vogel <email@email>
Date:   Tue Feb 22 00:27:17 2011 +0100

Merge branch 'testing' into master

라인을 주목하십시오 :

Merge: fc17405 ee2de56

이 두 커밋 ID를 가져 와서 반대로하십시오. 따라서 원하는 diff를 얻으려면 다음을 수행하십시오.

git diff ee2de56..fc17405

변경된 파일의 이름 만 표시하려면 다음을 수행하십시오.

git diff --name-only ee2de56..fc17405

그것들을 추출하기 위해 이것을 gitconfig에 추가 할 수 있습니다 :

exportfiles = !sh -c 'git diff $0 --name-only | "while read files; do mkdir -p \"$1/$(dirname $files)\"; cp -vf $files $1/$(dirname $files); done"'

그런 다음 다음을 수행하여 사용하십시오.

git exportfiles ee2de56..fc17405 /c/temp/myproject

제안 해 주셔서 감사하지만 내 문제를 해결하지 못한다고 생각합니다. 댓글 마크 업 및 서식이 제한되어있어 답변에 댓글을 추가했습니다. 그 죄송합니다! 표시 될 때까지 동료 검토를 받아야합니다.
Tilman Vogel

6
편집이 거부 된 것 같습니다. 요약하면, 당신의 diff는 어떤 추가가 어떤 브랜치에서 왔는지 보여주지 않습니다. 또한 변경 사항이 두 번째 분기에 추가되었는지 또는 첫 번째 분기에서 제거되었는지를 구분할 수 없습니다.
Tilman Vogel

45
더 나은 해결책은 git diff fc17405...ee2de56fc17405의 커밋에서 도달 할 수있는 ee2de56의 모든 변경 사항을 표시합니다. 2 개 대신 3 개 점에 유의하십시오.
Kris Nuttycombe

1
@KrisNuttycombe 3 개의 점과 순서. 그리고 당신의 의견은 내가 찾고있는 것인데, OP가 원했던 것과 더 비슷하다고 생각합니다.
Izkata

@KrisNuttycombe이 방법은으로 작동하지 않으므로 변형 git log과 같은 모든 커밋이 여전히 표시됩니다 ... .....대해 동일한 작업을 수행 log하지만 diff서로 다릅니다!? 이 브랜치로 병합 된 커밋 목록을 어떻게 얻습니까?
Rudie

77

더 나은 솔루션 (@KrisNuttycombe에서 언급) :

git diff fc17405...ee2de56

병합 커밋의 경우 :

commit 0e1329e551a5700614a2a34d8101e92fd9f2cad6 (HEAD, master)
Merge: fc17405 ee2de56
Author: Tilman Vogel <email@email>
Date:   Tue Feb 22 00:27:17 2011 +0100

ee2de56커밋에서 도달 할 수 있는 모든 변경 사항을 표시합니다 fc17405. 커밋 해시의 순서를 참고하십시오-병합 정보에 표시된 것과 같습니다.Merge: fc17405 ee2de56

또한 ...두 개 대신 세 개 점을 참고하십시오 !

변경된 파일 목록을 보려면 다음을 사용할 수 있습니다.

git diff fc17405...ee2de56 --name-only

이것은 내가 +1 이후에 있었던 것입니다.
geedoubleya

이것은 실제로 병합 충돌의 결과를 보여 주지만 다른 대답은 그렇지 않습니다.
포드

12

병합하기 전에 HEAD를 하나의 커밋으로 설정하여 분기를 만들 수 있습니다. 그런 다음 다음을 수행 할 수 있습니다.

git merge --squash testing

병합되지만 커밋되지는 않습니다. 그때:

git diff

5

여기에 답변 된 것 같습니다 : https://public-inbox.org/git/7vd392ezhx.fsf@alter.siamese.dyndns.org/

비슷한 방식으로

$ git diff --cc $ M $ M ^ 1 $ M ^ 2 $ (git merge-base $ M ^ 1 $ M ^ 2)

부모 및 병합 기반에 기록 된 상태와 비교하여 $ M의 상태를 설명하는 결합 된 패치를 표시해야합니다.


IntelliJ 병합 충돌 해결 창에서와 같이 몇 개의 열로 나란히 이러한 차이를 표시하도록 도구를 구성 할 수 있는지 알고 있습니까? 당신의 대답은 정확히 내가 찾고 있었던 것입니다
Max

@ 맥스 아니오 나는 두려워하지 않습니다. 인터넷 검색 "n-way visual diff"는 몇 가지 링크를 제공하므로 시도했습니다.
max630

4

'git show -c $ ref'가 필요하다고 생각합니다. a8e4a59의 git 저장소에서 이것을 시도하면 결합 된 diff (2 열 중 하나의 플러스 / 마이너스 문자)가 표시됩니다. git-show 매뉴얼에서 언급했듯이 'git diff-tree'를 대표하는 사람들이 많으므로 이러한 옵션은 유용하게 보입니다.


3
아니오, "간단한"병합의 경우, git show -c $ref인용 한 것과 동일한 출력을 보여줍니다 (예 : 차이가 없음). -c'--cc'인 병합 커밋의 기본 모드와 매우 유사한 결합 된 diff 모드를 선택합니다 ( git help show및 참조) git help diff-tree. 둘 다 해당 파일의 상위 버전 중 하나와 일치하는 파일을 완전히 생략합니다.
Tilman Vogel

a8e4a59실제로 병합 커밋 범주에 속하지 않습니다. 이 병합 커밋에는 실제로 부모 버전과 다른 하나의 파일이 포함되어 있습니다. Documentation/git-fast-import.txt한 부모와 다른 것에서 추가 된 것들이 있습니다. 결과는에서 비어 있지 않은 출력이됩니다 git diff-tree --cc. 그러나이 "충돌"사례의 변경 사항 만 표시됩니다. "깨끗한"병합 결과 git show -m a8e4a59는 모두 표시되지 않습니다.
Tilman Vogel 2019

1
@TilmanVogel : "흥미롭지 않은"파일 병합이 git show -c출력에서 제외되었음을 지적 해 주셔서 감사합니다 . ( man git-diff-tree또한 "모든 부모님이 수정 한 파일 만 나열합니다."라고 말하지만 분명히 그 사실을 발견하지 못했습니다.)
Paul Whittaker

3

귀하의 경우에는

git diff HEAD^ HEAD^2

또는 커밋을 위해 해시하십시오.

git diff 0e1329e55^ 0e1329e55^2

4
아니오, 이것은 단지 두 부모 사이에 명백한 양방향 차이를 나타냅니다. 내가 요구 한 것은 충돌로 병합 된 파일에 대해 수행 된 것과 같은 스타일로 git merge-base HEAD^ HEAD^2and HEAD^HEAD^2같은 스타일 의 차이를 동시에 보여주는 모드였습니다 .
Tilman Vogel 2016

3

위와 같이 병합 커밋이 commit 0e1329e5이면 다음과 같이이 병합에 포함 된 diff를 얻을 수 있습니다.

git diff 0e1329e5^..0e1329e5

이게 도움이 되길 바란다!


3

병합 커밋에 앉아 있다면 차이가 표시됩니다.

git diff HEAD~1..HEAD

병합 커밋이 아닌 경우 HEAD를 병합 커밋으로 바꿉니다. 이 방법은 가장 단순하고 직관적 인 것 같습니다.


1
이것은 "결합 된 diff"출력이 아닙니다. 각 부모와 HEAD 사이에 차이를 얻는 것은 여기서 문제가되지 않습니다.
Tilman Vogel

2

diff-tree 명령을 -c 플래그와 함께 사용할 수 있습니다. 이 명령은 병합 커밋에서 변경된 파일을 보여줍니다.

git diff-tree -c {merged_commit_sha}

Git-Scm 에서 -c 플래그의 설명을 얻었습니다 .

이 플래그는 병합 커밋이 표시되는 방식을 변경합니다 (즉, 명령에 --stdin이 지정된 경우에만 유용함). 한 번에 하나씩 부모와 결과 사이에 쌍별 차이를 표시하는 대신 각 부모와 병합 결과의 차이점을 동시에 표시합니다 (-m 옵션의 기능). 또한 모든 상위에서 수정 된 파일 만 나열합니다.


2
이 주제에 대한 좋은 기사처럼 보입니다 : haacked.com/archive/2014/02/21/reviewing-merge-commits 그리고 아마도 이것도 : longair.net/blog/2009/04/16/git-fetch-and-merge
Devin G Rhode

1

병합의 커밋에 대한 다양한 작업을 수행하기위한 범용 접근 방식을 구축했습니다.

1 단계 : 편집하여 git에 별칭을 추가하십시오 ~/.gitconfig.

[alias]
  range = "!. ~/.githelpers && run_on_merge_range"

2 단계 : ~/.githelpers에서 bash 함수를 정의하십시오.

run_on_merge_range() {
  cmd=$1; shift
  commit=$1; shift
  range=$(git show $commit | grep Merge: | awk '{print $2 "..." $3}')
  echo "git $cmd $range $@"
  if [ -z $range ]; then
    echo "No merge detected"
    exit 1
  fi
  git $cmd $range $@
}

3 단계 : 이익!

git range log <merge SHA> --oneline
git range diff <merge SHA> --reverse -p
git range diff <merge SHA> --name-only

여기에 개선의 여지가 많이있을 것입니다. 나는 성가신 상황을 극복하기 위해 이것을 함께 채찍질했습니다. 내 bash 구문 및 / 또는 논리를 조롱하십시오.


필요한 사항과 실행중인 명령에 따라 "awk"비트에서 "..."을 ".."로 변경할 수 있습니다. stackoverflow.com/questions/462974/…
Nerdmaster
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.