Programing

한 커밋이 다른 커밋의 조상인지 (또는 그 반대의 경우) 어떻게 알 수 있습니까?

lottogame 2020. 12. 31. 07:52
반응형

한 커밋이 다른 커밋의 조상인지 (또는 그 반대의 경우) 어떻게 알 수 있습니까?


Git은 그래프의 각 노드가 커밋을 나타내는 스냅 샷 DAG 입니다. 각 커밋은 'n'부모 커밋을 가질 수 있습니다.

두 개의 커밋이 주어지면 DAG에서이 두 커밋의 "순서"를 식별하는 단 하나의 간결한 방법이 있습니까? git rev-list가장 유망한 것처럼 보이지만 올바른 주문을 찾을 수없는 것 같습니다.

이상적으로는 다음과 같은 것이 있습니다.

$ git related hash1 hash2
hash1 is ancestor of hash2

또는

hash2 is ancestor of hash1

또는

hash1 unrelated to hash2

또는

hash1 is equal to hash2

사용하다 git merge-base --is-ancestor <commit1> <commit2>

이것에 대한 답을 찾는 방법은 여러 가지가 있습니다. 가장 간단한 방법은

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

에 대한 문서에서 git merge-base:

--is-ancestor

첫 번째 항목 <commit>이 두 번째 항목의 조상 인지 확인 <commit>하고 참이면 상태 0으로 종료하고 그렇지 않으면 상태 1로 종료합니다. 오류는 1이 아닌 0이 아닌 상태로 표시됩니다.

다른 옵션

트리플 점 ...표기법이있는 git log

또 다른 옵션은 git log삼점 표기법 ...사용 하여 Git에게 자식 커밋의 집합 조합에서 집합 교차를 뺀 값을 출력하도록 지시하는 것입니다. 기본적으로 커밋 세트가 서로 어떻게 다른지 알려줍니다.

$ git log --oneline --graph --left-right \
--first-parent --decorate <commit1>...<commit2>

위의 명령은 commit1또는 commit2에서 도달 할 수 있지만 둘 다가 아닌 커밋을 보여줍니다 . 즉, 집합 연산 측면에서 C1 UNION C2-C1 INTERSECTION C2입니다.

어느 커밋도 다른 커밋의 부모가 아니면 둘 다의 자식 커밋을 볼 수 있지만, 하나가 다른 커밋의 조상이면 조상이 경로에 포함되어 있기 때문에 하위 커밋에 대한 출력 만 볼 수 있습니다. 따라서 출력에서 ​​제외됩니다.

git log다음 리소스에서 삼점 표기법 에 대해 자세히 알아볼 수 있습니다 .

  1. git-log (1) .
  2. gitrevisions (1) : 범위 지정 .
  3. 개정 선택 .

git branch --contains 옵션

git-rev-list (1) 이 답변에 사용할 수있는 것 같습니다. 또 다른 방법은 테스트하려는 커밋에 임시 브랜치 레이블을 첨부 한 다음에 대한 --contains옵션을 사용하는 것입니다 git branch.

git branch --contains <commit-to-test>

출력은 커밋 트리 어딘가에 커밋을 포함하는 모든 브랜치이므로 다른 커밋에서 임시 브랜치를 사용하여 테스트중인 커밋이 조상인지 확인할 수 있습니다.

문서에서 :

--contains [<commit>]

지정된 커밋을 포함하는 분기 만 나열합니다 (지정되지 않은 경우 HEAD).


다음 쉘 스크립트가 트릭을 수행 할 수 있습니다.

if git rev-list $SHA1 | grep -q $SHA2 ; then echo "$SHA2 is ancestor of $SHA1"
elif git rev-list $SHA2 | grep -q $SHA1 ; then echo "$SHA1 is ancestor of $SHA2"
else echo "$SHA1 unrelated to $SHA2" ; fi

또는 git 별칭으로 깔끔하게 정리하려면 :

git config --global alias.related '!function git_related() { if git rev-list $1 | grep -q $2 ; then echo "$2 is ancestor of $1" ; elif git rev-list $2 | grep -q $1 ; then echo "$1 is ancestor of $2" ; else echo "$1 unrelated to $2" ; fi } ; git_related $1 $2'

if   (( $(git rev-list $1..$2|wc -l) == 0 )); then echo "$2 is ancestor of $1"
elif (( $(git rev-list $2..$1|wc -l) == 0 )); then echo "$1 is ancestor of $2"
else echo "$1 and $2 are unrelated"
fi

git log  --oneline -1  OLD_SHA..NEW_SHA

이것이 로그를 제공한다면 OLD_SHA는 NEW_SHA의 부모입니다.


@helmbert의 뛰어난 git related별칭 을 구축하기 위해 다음은 커밋 ID가 아닌 분기 이름 (또는 HEAD 등)도 인수로 허용하는 버전입니다.

git config --global alias.related '!function git_related() { commit1=`git log -n 1 --format="%h" $1` ; commit2=`git log -n 1 --format="%h" $2` ; if git rev-list $commit1 | grep -q $commit2 ; then echo "$2 is ancestor of $1" ; elif git rev-list $commit2 | grep -q $commit1 ; then echo "$1 is ancestor of $2" ; else echo "$1 unrelated to $2" ; fi } ; git_related $1 $2'

참조 URL : https://stackoverflow.com/questions/18345157/how-can-i-tell-if-one-commit-is-an-ancestor-of-another-commit-or-vice-versa

반응형