변경된 모든 파일이 부모 중 하나와 동의 할 때도 결합 된 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.