Git에서 현재 커밋의 해시를 검색하는 방법은 무엇입니까?


1931

Git 변경 세트를 TFS에 저장된 작업 항목에 연결하는 기능을 유지하고 싶습니다 (현재).

나는 이미 Git 체인지 셋 메시지에 workitemidentifiers를 주입 할 수있는 도구 (Git의 후크를 사용)를 작성했다.

그러나 Git 커밋 (해시)의 식별자를 사용자 정의 TFS 작업 항목 필드에 저장하고 싶습니다. 이렇게하면 TFS에서 작업 항목을 검사하고 Git 변경 세트가 작업 항목과 어떤 관련이 있는지 확인할 수 있습니다.

Git의 현재 커밋에서 해시를 쉽게 검색하려면 어떻게해야합니까?

답변:


2808

임의의 확장 객체 참조를 SHA-1로 바꾸려면 git-rev-parse 를 사용하십시오.

git rev-parse HEAD

또는

git rev-parse --verify HEAD

(!) 참고 : 당신이 설정하려면 참조 ( 지점 태그를 SHA-1로),이git show-refgit for-each-ref.


81
--verify그 의미 :The parameter given must be usable as a single, valid object name. Otherwise barf and abort.
리누스 Unnebäck

647
git rev-parse --short HEAD누군가 궁금해하는 경우를 대비하여 해시의 짧은 버전을 반환합니다.
Thane Brimhall

54
왕의 근위병이 말에 추가, 당신은 또한에 특정 길이를 추가 할 수 있습니다 --short같은 --short=12해시에서 숫자의 특정 번호를 얻을.
타이슨 팔프

31
@TysonPhalp는 : --short=N에 관한 최소한의 자릿수; git은 단축 된 다른 커밋과 구별 할 수없는 경우 큰 자릿수를 사용합니다. 예를 들어 git rev-parse --short=2 HEAD또는을 시도하십시오 git log --oneline --abbrev=2.
Jakub Narębski

36
Thane, Tyson 및 Jakub의 말에 덧붙여, 전체 해시를 인쇄 할 수 있지만 커밋 파란색을 식별하는 데 필요한 16 진수를 강조 표시하십시오.git rev-parse HEAD | GREP_COLORS='ms=34;1' grep $(git rev-parse --short=0 HEAD)
Zaz

423

단축 된 해시 만 원하는 경우 :

git log --pretty=format:'%h' -n 1

또한 % H를 사용하는 것이 긴 해시를 얻는 또 다른 방법입니다.


106
또는 위의 rev-parse 명령에 --short를 추가하면 작동하는 것 같습니다.
outofculture

15
나는 git log도자기이고 git rev-parse배관 이라고 생각 합니다.
Amedee Van Gasse

이 방법의 장점 중 하나는 더 큰 리포지토리에서 발생하는 해시 충돌에 맞게 올바른 길이로 조정 된 짧은 버전의 해시를 반환한다는 것입니다. 적어도 최신 버전의 git.
Ilia Sidorenko

4
이 방법은 헤드가 분리 된 경우 잘못된 해시를 제공하기 때문에 잘못된 / 올바르지 않은 방법입니다. 예를 들어 현재 커밋이 12ab34 ...이고 이전 커밋이 33aa44 인 경우 ... 'git checkout 33aa44'를 수행 한 다음 명령을 실행하면 12ab34가 다시 표시됩니다. to 33aa44 ...
theQuestionMan

3
@theQuestionMan 나는 당신이 묘사하는 행동을 경험하지 않습니다; git checkout 33aa44; git log -n 1나에게 준다 33aa44. 어떤 버전의 자식을 사용하고 있습니까?
outofculture

150

자식 로그를 사용하는 다른 하나 :

git log -1 --format="%H"

@outofculture와 매우 유사하지만 조금 짧습니다.


그리고 결과는 작은 따옴표가 아닙니다.
crokusek 2013

5
이 질문은 대신 특정 커밋을 체크 아웃하더라도 작동하기 때문에 정답입니다 HEAD.
Parsa

1
@Parsa : 특정 커밋을 체크 아웃 할 때 HEAD이름이 지정된 브랜치 가 아닌이 커밋을 가리키는 분리 헤드라고 합니다.
ChristofSenn

124

전체 SHA를 얻으려면 :

$ git rev-parse HEAD
cbf1b9a1be984a9f61b79a05f23b19f66d533537

단축 버전을 얻으려면 :

$ git rev-parse --short HEAD
cbf1b9a

이 경우 git commit해시가 필요하다 등의 하나로서 branch당신은 현재 작업중인 A는 master branch, 당신은 또한 사용할 수 있습니다 git rev-parse FETCH_HEAD당신이 해시해야하는 경우 master commit는 것이 merge현재에 거라고를 branch. 예를 들어, 당신이있는 경우 branchES를 master하고 feature/new-feature주어진 REPO합니다.에있는 동안 feature/new-feature당신이 사용할 수있는 git fetch origin master && git merge FETCH_HEAD다음 git rev-parse --short FETCH_HEAD당신은 필요한 경우 commit로부터 해시 master그냥 mergeD에 모든 스크립트에 대한 당신이있을 수 있습니다.
EVAL

72

아무도 그것을 아직 제안하지 않았기 때문에 완전성을 위해. .git/refs/heads/master한 줄만 포함 된 파일입니다 : 최신 커밋의 해시 on master. 거기서 읽을 수 있습니다.

또는 명령으로

cat .git/refs/heads/master

최신 정보:

git은 / refs / heads / 폴더의 파일 대신 pack-ref 파일에 일부 헤드 참조 저장을 지원합니다. https://www.kernel.org/pub/software/scm/git/docs/git-pack-refs.html


10
이것은 현재 브랜치가이라고 가정하며 master반드시 그런 것은 아닙니다.
gavrie

12
과연. 이것이 내가 이것을위한 것이라고 명시 적으로 말한 이유입니다 master.
Deestan

20
.git/HEADSHA1이 있으면 헤드 모드가 분리 된 것입니다.
eckes

8
이것은 다른 접근 방식과 비교할 때 특히 강력하지는 않습니다. 특히 .git하위 디렉토리 가 있다고 가정하기 때문에 반드시 그렇지는 않습니다. 참고 항목 --separate-git-dir에 깃발을 git init매뉴얼 페이지를 참조하십시오.
jub0bs

16
+1 때로는 git 실행 파일을 설치하지 않기를 원하기 때문에 (예 : Dockerfile에)
wim

50

커밋 해시

git show -s --format=%H

약식 커밋 해시

git show -s --format=%h

더 많은 예를 보려면 여기 를 클릭 하십시오git show .


50

항상 git describe있습니다. 기본적으로 그것은 당신에게-

john@eleanor:/dev/shm/mpd/ncmpc/pkg (master)$ git describe --always
release-0.19-11-g7a68a75

18
Git describe는 커밋에서 도달 할 수있는 첫 번째 TAG를 반환합니다. 이것이 SHA를 얻는 데 어떻게 도움이됩니까?
Sardaukar

42
같은 나는 git describe --long --dirty --abbrev=10 --tags그것이 나에게 같은 것을 줄 것이다 7.2.0.Final-447-g65bf4ef2d4"65bf4ef2d4"이다 447 개 7.2.0.Final 태그 후 커밋과 제 (10)는 현재 HEAD에서 글로벌 SHA-1의 다이제스트 인을. 버전 문자열에 매우 좋습니다. --long을 사용하면 태그가 정확하게 일치하더라도 항상 카운트 (-0-)와 해시를 추가합니다.
eckes

14
어떤 태그 다음 존재하지 않는 경우 git describe --always것 "고유 축약 보여 대체 등의 목적 커밋"
로니 앤더슨

사용 git describe --tags --first-parent --abbrev=11 --long --dirty --always합니다. 이 --always옵션은 태그가 없어도 결과 (해시)를 제공함을 의미합니다. 이는 --first-parent병합 커밋에 의해 혼동되지 않고 현재 분기의 항목 만 따릅니다. 또한 참고 --dirty추가합니다 -dirty현재 분기 않은 변경이있는 경우 결과에.
ingyhere

30

사용하다 git rev-list --max-count=1 HEAD


3
git-rev-list는 커밋 객체 목록을 생성하는 것입니다. 객체 이름 (예 : HEAD)을 SHA-1로 변환하는 것은 git-rev-parse입니다.
Jakub Narębski

21

스크립트 도중 해시를 변수에 저장해야하는 경우

last_commit=$(git rev-parse HEAD)

또는 github.com처럼 처음 10자를 원한다면

last_commit=$(git rev-parse HEAD | cut -c1-10) 

26
--short또는 --short=number매개 변수 도 있습니다 git rev-parse. 파이프를 사용할 필요가 없습니다 cut.
Julian D.

15

슈퍼 해키 방법을 원한다면 :

cat .git/`cat .git/HEAD | cut -d \  -f 2`

기본적으로 git은 HEAD의 위치를 ​​.git / HEAD에 형식으로 저장 ref: {path from .git}합니다. 이 명령은 그 내용을 읽고 "ref :"를 잘라 내고 지정한 파일을 읽습니다.

HEAD는 "ref : ..."가 아니지만 해시 자체는 아니기 때문에 분리 헤드 모드에서는 실패합니다. 그러나 당신은 알고 있습니다. 라이너. 세미콜론이 바람을 피우고 있다고 생각하지 않는다면 ...

HASH="ref: HEAD"; while [[ $HASH == ref\:* ]]; do HASH="$(cat ".git/$(echo $HASH | cut -d \  -f 2)")"; done; echo $HASH

1
자식을 설치할 필요가 없습니다. 좋습니다. (내 도커 빌드 이미지에는 자식이 없습니다)
Helin Wang

git repo 외부에서 이것을 쉽게 실행할 수 있기 때문에 유용합니다.
samaspin

나는 이것을 로컬 컴퓨터의 스크립트로 공식화했다. 그런 다음 생각했습니다. 내가 만든 구현은 관련이없는 문제 (외부 프로그램이없는 원시 POSIX 셸 스크립트의 인수 구문 분석)를 해결하는 방법을 보여줄만큼 간단하지만 약간의 변형을 제공하고 대부분을 활용하기에 충분히 복잡합니다. 의 기능 sh. 30 분의 문서에 대한 주석은 나중에, 여기에 요점이 있습니다 : gist.github.com/Fordi/29b8d6d1ef1662b306bfc2bd99151b07
Fordi

그것을보고, 나는 Git과 SVN을 감지하고 git hash / svn 개정판을 잡기 위해보다 광범위한 버전을 만들었습니다. 이번에는 깨끗한 문자열이 아니지만 쉽게 명령 줄 구문 분석되었으며 버전 태그로 사용할 수 있습니다. gist.github.com/Fordi/8f1828efd820181f24302b292670b14e
Fordi

14

내가 아는 가장 간결한 방법 :

git show --pretty=%h 

해시의 특정 자릿수를 원하는 경우 다음을 추가 할 수 있습니다.

--abbrev=n

14
이것이 기술적으로 작동하는 동안 git show, 도자기 명령 (즉, 사용자 대면)이라고 알려진 것이기 때문에 출력에 변경이있을 수 있으므로 스크립트에 사용 해서는 안됩니다 . git rev-parse --short HEAD대신 위의 답변 ( )을 사용해야합니다.
jm3

4
거꾸로 @ jm3. "Porcelain"명령에는 스크립트 용으로 안정적인 출력이 있습니다. 를 검색 git help show하십시오 porcelain.
John Tyree

2
@JohnTyree 이것은 혼란스러운 주제이지만 jm3는 옳았습니다. 도자기 명령은 파싱되는 것이 아니라 사람이 읽을 수있는 것입니다. 스크립트에서 도자기 명령을 사용해야하고 안정적인 형식을 원할 경우, 때때로 git status, push and blame과 같은 옵션이 있습니다. 불행히도이 옵션은이라고 불려 --porcelain지므로 혼란 스럽습니다. 당신의 세부 사항 찾을 수 있습니다 VonC에 의해이 큰 대답을
파비오는 분석 재개 모니카 말한다

1
내가 그들을 찾으려하고 ... 오 내가 신경 끄시 고 그들을 찾을 자식을 사용해야 할 것입니다 기다릴 --porcelain 해당 옵션의 이름을 결정 사랑하는 신
브리튼 Kerin

14

아마도 별명을 원할 것이므로 모든 멋진 세부 사항을 기억할 필요는 없습니다. 아래 단계 중 하나를 수행 한 후 간단히 다음을 입력 할 수 있습니다.

$ git lastcommit
49c03fc679ab11534e1b4b35687b1225c365c630

수락 된 답변 에 이어 다음 과 같이 두 가지 방법으로 설정할 수 있습니다.

1) 전역 설정 (원래 답변)을 편집하여 git에게 명시적인 방법을 가르치십시오.

 # open the git config editor
 $ git config --global --edit
 # in the alias section, add
 ...
 [alias]
   lastcommit = rev-parse HEAD
 ...

2) 또는 최근 Adrien이 언급 한 것처럼 git에게 단축키를 가르치는 단축키를 좋아하는 경우 :

$ git config --global alias.lastcommit "rev-parse HEAD"

여기에서 git lastcommit마지막 커밋의 해시를 표시하는 데 사용하십시오 .


3
Adrien de Sentenac 은 git config 파일을 수동으로 편집하는 대신 다음과 같이 간단하게 수행 할 수 있다고 git config --global alias.lastcommit "rev-parse HEAD"
언급했습니다

12

좀 더 다른 것이 필요했습니다. 커밋의 전체 sha1을 표시하지만 작업 디렉토리가 깨끗하지 않으면 끝에 별표를 추가하십시오. 여러 명령을 사용하고 싶지 않으면 이전 답변의 옵션 중 어느 것도 작동하지 않습니다.

하나의 라이너는 다음과 같습니다.
git describe --always --abbrev=0 --match "NOT A TAG" --dirty="*"
결과 :f5366ccb21588c0d7a5f7d9fa1d3f85e9f9d1ffe*

설명 : 주석이 달린 태그를 사용하여 현재 커밋을 설명하지만 "NOT A TAG"가 포함 된 태그 만 사용합니다. 태그는 공백을 가질 수 없으므로 태그와 일치하지 않으며 결과를 표시하려고하기 때문에 --always명령 --abbrev=0은 커밋 의 전체 ( ) sha1을 표시하고 작업 디렉토리가있는 경우 별표를 추가합니다 --dirty.

별표를 추가하지 않으려면 이전 답변의 다른 모든 명령과 같이 작동합니다.
git describe --always --abbrev=0 --match "NOT A TAG"
결과 :f5366ccb21588c0d7a5f7d9fa1d3f85e9f9d1ffe


고마워, 단지 그것을 넘어
뜨리고

1
그것은없이 나를 위해 작동합니다 --match "NOT A TAG". 자식 2.18.0과 2.7.4에서 테스트되었습니다. 이 논쟁이 필요한 상황이 있습니까?
토마스

@Thomas 현재 커밋 기록에 주석이 달린 태그가 있으면 작동하지 않습니다. 가짜 태그는 describe 명령이 커밋을 설명하기 위해 태그를 사용하지 않도록합니다.
Rado

8
git show-ref --head --hash head

속도 를 내려면 Deestan이 언급 한 접근 방식

cat .git/refs/heads/<branch-name>

지금까지 여기에 나열된 다른 방법보다 훨씬 빠릅니다.


show-ref이 배관 명령의 향후 릴리스에서 안정을 유지하는 것이 보장 (또는 매우 가능성이 적어도) 이후, 스크립팅을위한 최선의 선택이 될 나에게 보인다 다른 답변 사용 rev-parse, show, describe, 또는 log모든 도자기 명령이있다. 그리고 속도가 핵심 이 아닌 경우 show-ref맨 페이지 의 참고 사항이 적용됩니다. '.git 디렉토리에있는 파일에 직접 액세스하는 것이 좋습니다.'
Pont

6

다음은 git 파일에서 직접 읽은 Bash 셸의 한 줄짜리입니다.

(head=($(<.git/HEAD)); cat .git/${head[1]})

git root 폴더에서 위 명령을 실행해야합니다.

이 방법은 파일을 리포지토리에 저장했지만 git명령이 설치되지 않은 경우에 유용 할 수 있습니다 .

작동하지 않으면 .git/refs/heads폴더에 어떤 종류의 헤드가 있는지 확인하십시오 .


5

파일 ".gitconfig"의 홈 디렉토리에 다음을 추가하십시오.

[alias]
sha = rev-parse HEAD

그러면 기억하기 쉬운 명령이 있습니다.

$ git sha
59fbfdbadb43ad0b6154c982c997041e9e53b600

3

git bash에서 $ git log -1을 실행하십시오.

이 줄들은 당신의 명령을 따르는 것을 볼 것입니다.

commit d25c95d88a5e8b7e15ba6c925a1631a5357095db .. (info about your head)

d25c95d88a5e8b7e15ba6c925a1631a5357095db, is your SHA for last commit.

0

또 다른 직접 액세스 구현은 다음과 같습니다.

head="$(cat ".git/HEAD")"
while [ "$head" != "${head#ref: }" ]; do
  head="$(cat ".git/${head#ref: }")"
done

이것은 또한 로컬 패키지 아카이브에 유용한 http를 통해 작동합니다 (공개 웹 사이트의 경우 .git 디렉토리에 액세스 할 수 없도록 권장하지 않음).

head="$(curl -s "$baseurl/.git/HEAD")"
while [ "$head" != "${head#ref: }" ]; do
  head="$(curl -s "$baseurl/.git/${head#ref: }")"
done


0
cat .git/HEAD

출력 예 :

ref: refs/heads/master

그것을 파싱하십시오 :

cat .git/HEAD | sed "s/^.\+ \(.\+\)$/\1/g"

창이있는 경우 wsl.exe 사용을 고려할 수 있습니다.

wsl cat .git/HEAD | wsl sed "s/^.\+ \(.\+\)$/\1/g"

산출:

refs/heads/master

이 값은 나중에 체크 아웃하는 데 사용될 수 있지만 SHA를 가리키게됩니다. 이름으로 실제 현재 분기를 가리 키도록하려면 다음을 수행하십시오.

wsl cat .git/HEAD | wsl sed "s/^.\+ \(.\+\)$/\1/g" | wsl sed "s/^refs\///g" | wsl sed "s/^heads\///g"

출력 :

master

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.