한 커밋이 다른 커밋의 자손인지 어떻게 알 수 있습니까? 한 커밋이 다른 커밋의 자손인지 어떻게 알

Git을 사용하면 지점의 한 커밋이 다른 커밋의 자손인지 어떻게 알 수 있습니까?



답변

프로그래밍 방식으로 (예 : 스크립트에서) 확인 git merge-base A B하려면 git rev-parse --verify A(B에서 ​​A에 도달 할 수 있는지 ) 또는 (A에서 B에 도달 할 수 있는지) 확인할 수 있습니다 git rev-parse --verify B. git rev-parse커밋 이름에서 커밋 SHA-1 / 커밋 ID로 변환하는 데 필요합니다.

VonCgit rev-list 에서와 같은 답변을 사용하는 것도 가능합니다.

편집 : 현대 Git에는이 쿼리에 대한 형식이 명시 적으로 지원됩니다 git merge-base --is-ancestor.


당신이 요구하는 커밋 중 하나에 대한 경우 지점 팁 , 다음 git branch --contains <commit>또는 git branch --merged <commit>더 나은 비 프로그램의 솔루션이 될 수 있습니다.


답변

Git 1.8.0부터는 다음과 같은 옵션으로 지원됩니다 merge-base.

git merge-base --is-ancestor <maybe-ancestor-commit> <descendant-commit>

매뉴얼 페이지에서 :

-조상

첫 번째가 두 번째의 조상인지 확인하고 true이면 상태 0으로, 그렇지 않으면 상태 1로 종료하십시오. 오류는 1이 아닌 0이 아닌 상태로 표시됩니다.

예를 들면 다음과 같습니다.

git merge-base --is-ancestor origin/master master; echo $?

답변

이러한 종류의 작업은 SO 질문에 자세히 설명 된 수정 범위의 개념에 의존합니다 . ” ‘git log origin / master’와 ‘git log origin / master ..’의 차이

git rev-list 도달 할 수있는 다른 커밋까지 커밋에서 되돌아 갈 수 있어야합니다.

그래서 시도 할 것입니다 :

git rev-list --boundary 85e54e2408..0815fcf18a
0815fcf18a19441c1c26fc3495c4047cf59a06b9
8a1658147a460a0230fb1990f0bc61130ab624b2
-85e54e240836e6efb46978e4a1780f0b45516b20

(경계 커밋은 접두사가 붙습니다 -)

표시된 마지막 커밋이 git rev-list명령 의 첫 번째 커밋과 동일 하면 두 번째 커밋에서 도달 가능한 커밋입니다.

첫 번째 커밋이 두 번째 커밋에 도달 할 수 git rev-list없으면 아무것도 반환하지 않아야합니다.

git rev-list --boundary A..B

에서 도달 할 수있는 A경우에 완료됩니다 .
다음과 같습니다.AB

git rev-list --boundary B --not A

함께 포지티브 기준제외 참조 .
에서 도달 할 수있는 개정판을 발견 할 때까지 그래프 에서 시작 하여 그래프를 다시 살펴 봅니다. 에서 직접 연결할 수
있으면 옵션 과 관련하여 표시 됩니다.BA
BA
AB--boundaryA


답변

또 다른 방법은 git log및 을 사용하는 것 grep입니다.

git log --pretty=format:%H abc123 | grep def456

commit def456이 commit abc123의 조상이거나 그렇지 않으면 출력이 없으면 한 줄의 출력을 생성합니다.

일반적으로 --pretty인수 를 생략하여 벗어날 수는 있지만 로그 주석 등이 아닌 실제 커밋 해시를 통해서만 검색하도록하려면 필요합니다.


답변

https://stackoverflow.com/a/13526591/895245에서 더 인간 친화적으로 만들기 위해 언급했습니다.

git-is-ancestor() (
  if git merge-base --is-ancestor "$1" "$2"; then
      echo 'ancestor'
  elif git merge-base --is-ancestor "$2" "$1"; then
      echo 'descendant'
  else
      echo 'unrelated'
  fi
)
alias giia='git-is-ancestor'

답변

git show-branch branch-sha1 커밋 -sha1

어디:

  • branch-sha1 : 확인하려는 지점의 sha1
  • commit-sha1 : 확인할 커밋의 sha1

답변

당신이 사용하는 경우 git merge-base --is-ancestor , 힘내 2.28을 사용해야합니다 (Q3 2020)

Git 2.28 (Q3 2020)에서는 struct commit항상 존재하지 않아도 되는 ” ” 의 일부 필드가 슬래브를 커밋하도록 이동되었습니다.

참조 c752ad0 커밋 , c49c82a 커밋 , 4,844,812 커밋 , 6da43d9 커밋 에 의해 (2020 6월 17일) (Abhishek 쿠마 abhishekkumar2718) .
(의해 병합 Junio C 하마노 – gitster커밋 d80bea4 06 7 월를 2020)

commit-graph: 설명하다 commit_graph_data_slab

서명자 : Abhishek Kumar

구조체 커밋은 많은 상황에서 사용됩니다. 그러나, 부재 generation와는 graph_pos단지 저지 그래프 관련 작업에 사용하고, 그렇지 않으면 메모리를 낭비.

이 낭비는 현재 32 비트 대신 64 비트 세대 번호를 사용하는 세대 번호 v2로 전환함에 따라 더욱 두드러졌습니다.

그들은 종종 함께 접근하기 때문에 구조체를 소개 commit_graph_data하고 commit_graph_data슬래브 로 옮깁니다 .

전체 테스트 스위트는 master(26m48s, master27m34s, 2.87 % 더 빠름) git merge-base --is-ancestor속도로 실행 되지만 Szeder Gábor가 발견 한 것과 같은 특정 명령 은 40 % 느려졌습니다 .
커밋 슬래브 액세스를 최소화 한 후에도 속도가 느려지지만 20 %에 가깝습니다.

데릭 스토리 (Derrick Stolee) 는 커밋 슬래브 액세스 속도 가 느리지 않고 기본 알고리즘에 기인한다고 느꼈으 며 이후 시리즈에서 후속 조치를 취할 것입니다.