Como recuperar o hash para o commit atual no Git?

Gostaria de manter (por enquanto) a capacidade de vincular changesets do Git a itens de trabalho armazenados no TFS.

Eu já escrevi uma ferramenta (usando um hook do Git) na qual eu posso injetar identificadores de workitem na mensagem de um changeset do Git.

No entanto, eu também gostaria de armazenar o identificador do commit do Git (o hash) em um campo customizado do item de trabalho do TFS. Dessa forma, posso examinar um item de trabalho no TFS e ver quais conjuntos de mudanças do Git estão associados ao item de trabalho.

Como posso recuperar facilmente o hash do commit atual do Git?

Para transformar arbitrária referência de object estendido em SHA-1, use simplesmente git-rev-parse , por exemplo

git rev-parse HEAD 

ou

 git rev-parse --verify HEAD 

Sidenote: Se você quiser transformar referências ( branches e tags ) em SHA-1, há git show-ref e git for-each-ref .

Se você quer apenas o hash encurtado:

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

Além disso, usar% H é outra maneira de obter o hash longo.

Outro, usando o log do git:

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

É muito parecido com o de @outofculture, embora um pouco mais curto.

Para completar, já que ninguém sugeriu isso ainda. .git/refs/heads/master é um arquivo que contém apenas uma linha: o hash do commit mais recente no master . Então você poderia apenas ler a partir daí.

Ou como como comando:

 cat .git/refs/heads/master 

Atualizar:

Note que o git agora suporta o armazenamento de algumas referências de cabeça no arquivo pack-ref ao invés de um arquivo na pasta / refs / heads /. https://www.kernel.org/pub/software/scm/git/docs/git-pack-refs.html

Para obter o SHA completo:

 $ git rev-parse HEAD cbf1b9a1be984a9f61b79a05f23b19f66d533537 

Para obter a versão abreviada:

 $ git rev-parse --short HEAD cbf1b9a 

Há sempre git describe também. Por padrão, dá-lhe –

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

Commit hash

 git show -s --format=%H 

Hash de confirmação abreviado

 git show -s --format=%h 

Clique aqui para mais exemplos de git show .

Use git rev-list --max-count=1 HEAD

Se você precisar armazenar o hash em uma variável durante um script, poderá usar

 last_commit=$(git rev-parse HEAD) 

Ou, se você quiser apenas os 10 primeiros caracteres (como o github.com)

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

A maneira mais sucinta que conheço:

 git show --pretty=%h 

Se você quiser um número específico de dígitos do hash, você pode adicionar:

 --abbrev=n 

Se você quer que a maneira super-hacky faça isso:

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

Basicamente, o git armazena a localização de HEAD em .git / HEAD, no formato ref: {path from .git} . Esse comando lê isso, corta o “ref:” e lê o arquivo para o qual apontou.

Isso, é claro, falhará no modo de cabeça desanexada, já que o HEAD não será “ref: …”, mas o hash em si – mas, você sabe, eu não acho que você espere tanto conhecimento em seu bash -liners. Se você não acha que os ponto-e-vírgulas estão trapaceando, embora …

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

Talvez você queira um apelido para não precisar lembrar de todos os detalhes interessantes. Depois de fazer um dos passos abaixo, você poderá simplesmente digitar:

 $ git lastcommit 49c03fc679ab11534e1b4b35687b1225c365c630 

Seguindo a resposta aceita , aqui estão duas maneiras de configurar isso:

1) Ensine o git explicitamente editando a configuração global (minha resposta original):

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

2) Ou se você gosta de um atalho para ensinar um atalho, como recentemente comentado por Adrien:

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

A partir daqui, use o git lastcommit para mostrar o hash do último commit.

Eu precisava de algo um pouco mais diferente: exibir o sha1 completo do commit, mas acrescentar um asterisco ao final se o diretório de trabalho não estiver limpo. A menos que eu queira usar vários comandos, nenhuma das opções nas respostas anteriores funciona.

Aqui está o liner que faz:
git describe --always --abbrev=0 --match "NOT A TAG" --dirty="*"
Resultado: f5366ccb21588c0d7a5f7d9fa1d3f85e9f9d1ffe*

Explicação: descreve (usando tags anotadas) o commit atual, mas apenas com tags contendo “NOT A TAG”. Como as tags não podem ter espaços, isso nunca corresponde a uma tag e como queremos mostrar um resultado – --always , o comando retrocede exibindo o full ( --abbrev=0 ) sha1 da confirmação e anexa um asterisco se o diretório de trabalho é – --dirty .

Se você não quiser acrescentar o asterisco, isso funciona como todos os outros comandos nas respostas anteriores:
git describe --always --abbrev=0 --match "NOT A TAG"
Resultado: f5366ccb21588c0d7a5f7d9fa1d3f85e9f9d1ffe

 git show-ref --head --hash head 

Se você está indo para a velocidade, porém, a abordagem mencionada pelo Deestan

 cat .git/refs/heads/ 

é significativamente mais rápido que qualquer outro método listado aqui até agora.

Aqui está o one-liner no shell Bash usando a leitura direta dos arquivos git:

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

Você precisa executar o comando acima na sua pasta raiz do git.

Este método pode ser útil quando você tiver arquivos de repository, mas o comando git não foi instalado.

Se não funcionar, verifique na pasta .git/refs/heads que tipo de cabeças você tem presente.

no seu diretório home no arquivo “.gitconfig” adicione o seguinte

 [alias] sha = rev-parse HEAD 

então você terá um comando mais fácil de lembrar:

 $ git sha 59fbfdbadb43ad0b6154c982c997041e9e53b600 

Aqui está outra maneira de fazer isso 🙂

 git log | grep -o '\w\{8,\}' | head -n 1 

Aqui está outra implementação de access direto:

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

Isso também funciona em http, o que é útil para arquivos de pacotes locais (eu sei: para sites públicos, não é recomendável tornar o diretório .git acessível):

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