Git 커밋의 출처를 특정하다
커밋의 SHA-1 해시 값을 지정하면 어떤 브랜치로부터 커밋이 오는지 알 수 있는 방법이 있습니까?
루비 그리트를 어떻게 사용하는지 알려주시면 보너스 포인트입니다.
정보가 직접 저장되지 않는다는 David의 말은 맞지만, 그렇다고 해서 찾을 수 없는 것은 아닙니다.여기 당신이 할 수 있는 몇 가지 방법이 있습니다.
커밋이 있는 브랜치를 찾습니다.
git branch -a --contains <commit>
이력에 지정된 커밋이 있는 모든 브랜치를 알 수 있습니다.커밋이 이미 병합된 경우에는 이 방법이 유용하지 않습니다.
재로그 검색
커밋된 저장소에서 작업 중인 경우 해당 커밋의 행을 reflog에서 검색할 수 있습니다.90일 이상 지난 리로그는 git-gc에 의해 삭제되므로 커밋이 너무 오래되면 찾을 수 없습니다.단, 다음과 같이 할 수 있습니다.
git reflog show --all | grep a871742
커밋 a871742를 찾습니다.커밋의 첫 번째 자리에는 생략형 7을 사용해야 합니다.출력은 다음과 같습니다.
a871742 refs/heads/completion@{0}: commit (amend): mpc-completion: total rewrite
커밋이 브랜치 "temption"에서 이루어졌음을 나타냅니다.디폴트 출력에는 생략된 커밋 해시가 표시되므로 풀 해시를 검색하지 않도록 하십시오.검색하지 않으면 아무것도 찾을 수 없습니다.
git reflog show
는, 실제로는 「」의입니다.git log -g --abbrev-commit --pretty=oneline
출력 포맷을 조작해, GREP에 사용할 수 있는 다른 것을 만들고 싶은 경우는, 그것이 시작점입니다.
커밋이 이루어진 저장소에서 작업하지 않는 경우 이 경우 할 수 있는 최선의 방법은 재로그를 검토하여 커밋이 저장소에 처음 도입된 시기를 찾는 것입니다.운 좋게도 커밋된 브랜치를 가져왔습니다.커밋 트리와 재로그를 동시에 실행할 수 없기 때문에 이 방법은 조금 더 복잡합니다.reflog 출력을 해석하여 각 해시에 원하는 커밋이 포함되어 있는지 확인합니다.
후속 병합 커밋 찾기
이는 워크플로우에 의존하지만 워크플로우가 양호할 경우 개발 브랜치에서 커밋이 이루어지며 그 브랜치는 머지됩니다.다음과 같이 할 수 있습니다.
git log --merges <commit>..
지정된 커밋을 상위 커밋으로 하는 병합 커밋을 표시합니다.(커밋이 한 번만 Marge된 경우 첫 번째 Marge는 원하는 Marge가 되어야 합니다.그렇지 않은 경우 몇 가지 검토가 필요할 것 같습니다.병합 커밋 메시지에는 병합된 지점 이름이 포함되어야 합니다.
할 수 , 「 」를 할 수 .--no-ff
" " " option to " " option to " )git merge
(단, 너무 서두르지 마세요)너무 많이 사용하면 난독화될 수 있습니다.)관련 질문에 대한 VonC의 답변은 이 주제에 대해 자세히 설명합니다.
이 간단한 명령어는 마법처럼 작동합니다.
git name-rev <SHA>
예를 들어 (test-branch는 지점 이름입니다)
git name-rev 651ad3a
251ad3a remotes/origin/test-branch
이마저도 다음과 같은 복잡한 시나리오에 적합합니다.
origin/branchA/
/branchB
/commit<SHA1>
/commit<SHA2>
서 ★★★★git name-rev commit<SHA2>
branch B를 반환합니다.
2013년 12월 갱신:
git-what-branch
(Perl 스크립트, 아래 참조)는 더 이상 유지보수가 되지 않는 것 같습니다.git-when-merged
Python으로 작성된 대안으로 매우 효과적입니다.
이것은, 「특정 커밋을 포함한 머지 커밋 검색」에 근거하고 있습니다.
git when-merged [OPTIONS] COMMIT [BRANCH...]
커밋이 하나 이상의 브랜치로 병합된 시기를 검색합니다.
' 커밋'을하여 ' 커밋'을 가져옵니다.COMMIT
브런치첫 번째 .
BRANCH
게 요.COMMIT
조상으로서.
원답: 2010년 9월:
Sebastien Douche는 방금 트위터를 했습니다(SO 답변 16분 전).
git-what-branch: 커밋이 어떤 브랜치에 있는지, 또는 어떻게 그것이 지정된 브랜치에 도달했는지 확인합니다.
이것은 Seth Robertson의 Perl 스크립트로 매우 흥미로워 보입니다.
개요
git-what-branch [--allref] [--all] [--topo-order | --date-order ]
[--quiet] [--reference-branch=branchname] [--reference=reference]
<commit-hash/tag>...
개요
요청된 커밋이 지정된 브랜치에 도달하는 원인이 되는 커밋 및 병합의 초기 원인 경로를 알려 주십시오(기본값).지정된 브런치에서 직접 커밋이 이루어진 경우, 그것이 가장 빠른 경로입니다.
원인단, 커밋 은 제외).
--topo-order
지정됩니다).성능
많은 브랜치(예를 들어 수백 개)가 커밋을 포함하고 있는 경우, 시스템은 각 커밋에 대한 경로를 추적하는 데 오랜 시간이 걸릴 수 있습니다(Linux 트리의 특정 커밋은 브랜치 탐색에 8초가 걸렸지만 후보 브랜치는 200개가 넘습니다).
의 「 ★★★★★★★★★★★★★★★★★★★★」--reference-branch --reference tag
(후보 브랜치가 수백 개 있는 경우) 검토가 수백 배 빨라집니다.예
# git-what-branch --all 1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4
1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4 first merged onto master using the following minimal temporal path:
v2.6.12-rc3-450-g1f9c381 merged up at v2.6.12-rc3-590-gbfd4bda (Thu May 5 08:59:37 2005)
v2.6.12-rc3-590-gbfd4bda merged up at v2.6.12-rc3-461-g84e48b6 (Tue May 3 18:27:24 2005)
v2.6.12-rc3-461-g84e48b6 is on master
v2.6.12-rc3-461-g84e48b6 is on v2.6.12-n
[...]
이 프로그램은 관심 있는 커밋의 효과는 고려하지 않고 병합 작업만 고려합니다.
예를 들어, 다음을 검색하려면c0118fa
은 밋밋 commit commit commit commit commit에서 나왔다.redesign_interactions
:
* ccfd449 (HEAD -> develop) Require to return undef if no digits found
* 93dd5ff Merge pull request #4 from KES777/clean_api
|\
| * 39d82d1 Fix tc0118faests for debugging debugger internals
| * ed67179 Move &push_frame out of core
| * 2fd84b5 Do not lose info about call point
| * 3ab09a2 Improve debugger output: Show info about emitted events
| * a435005 Merge branch 'redesign_interactions' into clean_api
| |\
| | * a06cc29 Code comments
| | * d5d6266 Remove copy/paste code
| | * c0118fa Allow command to choose how continue interaction
| | * 19cb534 Emit &interact event
다음 작업을 수행합니다.
git log c0118fa..HEAD --ancestry-path --merges
아래로 스크롤하여 마지막 병합 커밋을 찾습니다.즉, 다음과 같습니다.
commit a435005445a6752dfe788b8d994e155b3cd9778f
Merge: 0953cac a06cc29
Author: Eugen Konkov
Date: Sat Oct 1 00:54:18 2016 +0300
Merge branch 'redesign_interactions' into clean_api
갱신하다
또는 하나의 명령어:
git log c0118fa..HEAD --ancestry-path --merges --oneline --color | tail -n 1
Khichar.anil은 그의 대답에서 이 대부분을 다루었다.
리비전 이름 목록에서 태그를 제거하는 플래그를 추가하는 중입니다.다음과 같은 이점이 있습니다.
git name-rev --name-only --exclude=tags/* $SHA
git branch --contains <ref>
명령하다: "plumbing" 명령어는 다음과 같습니다.
COMMIT=$(git rev-parse <ref>) # expands hash if needed
for BRANCH in $(git for-each-ref --format "%(refname)" refs/heads); do
if $(git rev-list $BRANCH | fgrep -q $COMMIT); then
echo $BRANCH
fi
done
저는 같은 문제(Jenkins multibranch pipeline)에 대처하고 있습니다.커밋 정보만 가지고, 이 커밋이 원래 있던 브랜치명을 찾으려고 합니다.리모트 브랜치에서는 동작해야 합니다.로컬 복사는 사용할 수 없습니다.
저는 다음과 같이 작업하고 있습니다.
git rev-parse HEAD | xargs git name-rev
선택적으로 출력을 제거할 수 있습니다.
git rev-parse HEAD | xargs git name-rev | cut -d' ' -f2 | sed 's/remotes\/origin\///g'
위의 모든 솔루션을 시도해 보았지만, 어느 것도 효과가 없었습니다.
입니다.HEAD
:한장))))))))) :
git log --branches --source | grep <sha>
#or if you also care about remotes
git log --branches --remotes --source | grep <sha>
지점 이름은 줄 끝에 있어야 합니다.
--소스
각 커밋에 도달한 명령줄에 지정된 참조 이름을 출력합니다.
이것은 에 있느냐에 수 .HEAD
★★★★★★★★★★★★★★★★★★★★★★★.HEAD
제 마스터 브랜치에서의 최신 커밋에서 기대했던 결과를 얻었습니다.
안안을 사용한 육안 gitk --all
도움이 될 수도 있습니다.각 커밋에 대해 '브런치' 필드가 있지만 커밋에 도달할 수 있는 모든 브런치가 표시됩니다.커밋이 어느 브런치가 온이 되어 있는지는 알 수 없습니다.여기를 참조해 주세요.
기타:
또한 이 질문은 약간 잘못된 명칭이라는 것을 언급할 가치가 있다.다른 SVC와 달리 git 브랜치는 커밋 이력/그래프 내의 위치에 대한 일시적인 포인터일 뿐입니다.그들은 커밋을 소유하지도 않고 커밋으로 구성하지도 않습니다.기본적으로 태그는 체크 아웃 중에 푸시한 커밋으로 갱신되는 태그일 뿐입니다.브랜치는 일련의 커밋이 아니라 일련의 커밋의 끝/팁에 대한 포인터입니다.따라서 커밋은 브랜치에 '속'하거나 '출발'하지 않습니다.그래프상의 노드일 뿐입니다.
그럼 여기서 뭘 하는 거죠?우리는 도달 가능성이라는 개념을 사용하고 있다.각 브런치가 가리키는 커밋('브런치'의 끝)에서 시작하여 과거로 거슬러 올라가면 어떤 커밋을 찾을 수 있습니까?커밋을 찾는 유일한 방법이 특정 브랜치에서 검색을 시작하는 경우 커밋은 브랜치에 있다고 합니다.
이것은 안정된 것이 아니라는 점에 주의해 주세요.브런치를 갑자기 Marge, 이름 변경 또는 기본 재배치하면 브런치가 'on'으로 이행할 수 있는 커밋이 변경됩니다.그렇기 때문에 특정 지점에 의해 'on/owner'되는 커밋이 git에서 공식적이거나 항상 의미 있는 개념이 아닙니다.(그리고 이 질문에는 명확한 답변이 없는 이유)
가난한 사람의 선택은 도구를 사용하는 것이다.HEAD
커밋을 검색하여 커밋백업에서 머지 커밋이 표시될 때까지의 행을 시각적으로 따릅니다.
1 Tig는 Git용 ncurses 기반의 텍스트 모드 인터페이스입니다.주로 Git 저장소 브라우저로 기능하지만 청크 수준에서 커밋을 위한 변경 스테이징을 지원하고 다양한 Git 명령 출력을 위한 호출기 역할을 할 수도 있습니다.
실험으로 현재 체크아웃된 브랜치에 대한 정보를 커밋 메타데이터에 저장하는 포스트 커밋 후크를 만들었습니다.저도 그 정보를 보여주기 위해 gitk를 약간 수정했습니다.
https://github.com/pajp/branch-info-commits 에서 확인하실 수 있습니다.
OP가 특정 커밋이 생성되었을 때 브런치에 의해 통과된 이력을 확인하려고 하는 경우('SHA-1 해시값에서 커밋이 나오는 브런치를 찾아라'), reflog가 없으면 Git 오브젝트 데이터베이스 내에 어떤 이름 있는 브런치가 어떤 커밋 이력에 바인드되었는지 보여주는 레코드가 없습니다.
(댓글에 대한 답변으로 이 글을 올렸습니다.)
이 스크립트가 제 요점을 설명해주길 바랍니다.
rm -rf /tmp/r1 /tmp/r2; mkdir /tmp/r1; cd /tmp/r1
git init; git config user.name n; git config user.email e@x.io
git commit -m"empty" --allow-empty; git branch -m b1; git branch b2
git checkout b1; touch f1; git add f1; git commit -m"Add f1"
git checkout b2; touch f2; git add f2; git commit -m"Add f2"
git merge -m"merge branches" b1; git checkout b1; git merge b2
git clone /tmp/r1 /tmp/r2; cd /tmp/r2; git fetch origin b2:b2
set -x;
cd /tmp/r1; git log --oneline --graph --decorate; git reflog b1; git reflog b2;
cd /tmp/r2; git log --oneline --graph --decorate; git reflog b1; git reflog b2;
출력에는 'Add f1'을 사용한 커밋이 지점 b1에서 온 것인지 원격 복제 /tmp/r2에서 온 것인지 알 수 있는 방법이 없습니다.
(여기 출력의 마지막 줄)
+ cd /tmp/r1
+ git log --oneline --graph --decorate
* f0c707d (HEAD, b2, b1) merge branches
|\
| * 086c9ce Add f1
* | 80c10e5 Add f2
|/
* 18feb84 empty
+ git reflog b1
f0c707d b1@{0}: merge b2: Fast-forward
086c9ce b1@{1}: commit: Add f1
18feb84 b1@{2}: Branch: renamed refs/heads/master to refs/heads/b1
18feb84 b1@{3}: commit (initial): empty
+ git reflog b2
f0c707d b2@{0}: merge b1: Merge made by the 'recursive' strategy.
80c10e5 b2@{1}: commit: Add f2
18feb84 b2@{2}: branch: Created from b1
+ cd /tmp/r2
+ git log --oneline --graph --decorate
* f0c707d (HEAD, origin/b2, origin/b1, origin/HEAD, b2, b1) merge branches
|\
| * 086c9ce Add f1
* | 80c10e5 Add f2
|/
* 18feb84 empty
+ git reflog b1
f0c707d b1@{0}: clone: from /tmp/r1
+ git reflog b2
f0c707d b2@{0}: fetch origin b2:b2: storing head
간단히 말하면 Git은 커밋된 브랜치의 이름을 저장하지 않습니다.이 정보를 재구성하려는 속임수는 모든 경우에 효과가 있는 것은 아닌 것 같습니다.
TL;DR:
셸의 종료 상태에 관심이 있는 경우는, 다음을 사용해 주세요.
branch-current
- 지점 이름 - 지점 이름branch-names
브런치명(브런치명 1개)branch-name
- . - 1개를 .branch-names
다.branch-name
★★★★★★★★★★★★★★★★★」branch-names
로는 " " " 입니다.HEAD
아무 것도 안 됩니다.
스크립팅에 도움이 되는 에일리어스
branch-current = "symbolic-ref --short HEAD" # https://stackoverflow.com/a/19585361/5353461
branch-names = !"[ -z \"$1\" ] && git branch-current 2>/dev/null || git branch --format='%(refname:short)' --contains \"${1:-HEAD}\" #" # https://stackoverflow.com/a/19585361/5353461
branch-name = !"br=$(git branch-names \"$1\") && case \"$br\" in *$'\\n'*) printf \"Multiple branches:\\n%s\" \"$br\">&2; exit 1;; esac; echo \"$br\" #"
하나의 브랜치에서만 도달 가능
% git branch-name eae13ea
master
% echo $?
0
- 출력은 STDOUT으로
- 은 료음음음 음음음음 음음음 exit exit exit 。
0
.
여러 브랜치에서 도달 가능한 커밋
% git branch-name 4bc6188
Multiple branches:
attempt-extract
master%
% echo $?
1
- STDERR에 대한 출력
- 은 " " 입니다.
1
.
종료 상태이기 때문에 안전하게 구축할 수 있습니다.예를 들어, 취득에 사용되는 리모트를 취득하려면 , 다음의 순서에 따릅니다.
remote-fetch = !"branch=$(git branch-name \"$1\") && git config branch.\"$branch\".remote || echo origin #"
한 지점에 실제로 존재하지만 지점을 찾을 수 없는 동일한 문제에 직면해야 한다고 생각합니다.
먼저 모든 것을 꺼내는 것이 좋습니다.
git pull --all
다음으로 브랜치 검색을 수행합니다.
git name-rev <SHA>
또는 다음과 같이 입력합니다.
git branch --contains <SHA>
git checkout <SHA>
-> HEAD를 선택합니다.
git rev-parse --abbrev-ref HEAD
는 ->를 인쇄합니다.HEAD
이 상태에서는 이 명령어가 동작하지 않습니다.
이제 분리된 HEAD 상태가 되었으므로 다음 명령을 사용하여 지점 이름을 가져올 수 있습니다.
추신: 드 ps ps ps ps ps ps ps ps ps ps ps ps ps ps ps ps ps ps ps ps.
git branch -a --contains HEAD | sed -n 2p | awk '{ printf $1 }'
자, 이제 지점 이름을 알겠군
로컬 브랜치를 찾으려면:
grep -lR YOUR_COMMIT .git/refs/heads | sed 's/.git\/refs\/heads\///g'
리모트 브랜치를 찾으려면:
grep -lR $commit .git/refs/remotes | sed 's/.git\/refs\/remotes\///g'
일치하는 해시를 찾을 때까지 모든 트리를 검색하는 것 외에는 없습니다.
언급URL : https://stackoverflow.com/questions/2706797/finding-what-branch-a-git-commit-came-from
'programing' 카테고리의 다른 글
Python에서 범위를 벗어난 인덱스 기본값 가져오기 (0) | 2023.04.16 |
---|---|
개인 API를 사용하지 않고 현재 첫 번째 응답자를 가져옵니다. (0) | 2023.04.16 |
Windows용 Objective-C (0) | 2023.04.11 |
목록에서 고유한 값 목록을 가져옵니다. (0) | 2023.04.11 |
cURL이 에러 「(23) Failed write body」를 반환하는 이유는 무엇입니까? (0) | 2023.04.11 |