Git'teki mevcut işlemin karmasını nasıl alırım?


1934

Git değişiklik kümelerini TFS'de depolanan çalışma öğelerine bağlama yeteneğini (şimdilik) korumak istiyorum.

Zaten Git değişiklik kümesinin mesajına workitemifiifiers enjekte edebileceğim bir araç (Git'ten bir kanca kullanarak) yazdım.

Ancak, Git taahhüdünün (karma) tanımlayıcısını özel bir TFS iş öğesi alanına da saklamak istiyorum. Bu şekilde TFS'deki bir çalışma öğesini inceleyebilir ve Git değişiklik kümelerinin çalışma öğesi ile ilişkili olduğunu görebilirim.

Git'i mevcut işlemden karmayı nasıl alabilirim?

Yanıtlar:


2810

SHA-1 rasgele genişletilmiş nesne başvurusu açmak için, sadece kullanım git-REV-ayrıştırma , örneğin,

git rev-parse HEAD

veya

git rev-parse --verify HEAD

Sidenote: Referansları ( dallar ve etiketler ) SHA-1'e dönüştürmekistiyorsanızgit show-refve vardırgit for-each-ref.


81
--verifyşunu ima eder:The parameter given must be usable as a single, valid object name. Otherwise barf and abort.
Linus Unnebäck

648
git rev-parse --short HEADHerkesin merak etmesi durumunda, karma işlemin kısa sürümünü döndürür.
Thane Brimhall

54
Thane'nin söylediklerine ek --shortolarak --short=12, karmadan belirli sayıda basamak almak için belirli bir uzunluk da ekleyebilirsiniz .
Tyson Phalp

32
@TysonPhalp: --short=Nyaklaşık en az basamak sayısı; git kısaltılmışsa, diğer kısaltılmış kısaltmadan ayırt edilemezse çok sayıda basamak kullanır. Örn. git rev-parse --short=2 HEADYa da deneyin git log --oneline --abbrev=2.
Jakub Narębski

36
Thane, Tyson ve Jakub'un söylediklerine ek olarak, tam karmayı yazdırabilirsiniz, ancak tamamlama mavisini tanımlamak için gerekli hexits'leri vurgulayıngit rev-parse HEAD | GREP_COLORS='ms=34;1' grep $(git rev-parse --short=0 HEAD)
Zaz

423

Yalnızca kısaltılmış karmayı istiyorsanız:

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

Ayrıca% H kullanmak uzun hash elde etmenin başka bir yoludur.


107
Ya da, yukarıdaki dev-ayrıştırma komutuna -short eklemek işe yaramış gibi görünüyor.
outofculture

15
Bence git logporselen ve git rev-parsesıhhi tesisat.
Amedee Van Gasse

Bu yöntemin faydalarından biri, daha büyük depolar için meydana gelen karma çarpışmalarına göre ayarlanmış doğru uzunluğa sahip karma kısa versiyonunu döndürmesidir. En azından git'in son sürümlerinde.
Ilia Sidorenko

4
Bunu yapmanın kötü / yanlış bir yoludur, çünkü müstakbel bir kafanız varsa bu yöntem size yanlış karmayı verecektir. Örneğin, şu anki işlem 12ab34 ise ... ve önceki işlem 33aa44 ise ... o zaman 'git checkout 33aa44' yaparsam ve sonra komutunu çalıştırırsam 12ab34'e geri döneceğim ... to 33aa44 ...
theQuestionMan

3
@TheQuestionMan Açıkladığınız davranışı deneyimlemiyorum; git checkout 33aa44; git log -n 1verir 33aa44. Git'in hangi sürümünü kullanıyorsunuz?
outofculture

150

Bir diğeri, git log'u kullanarak:

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

Biraz daha kısa @outofculture çok benzer.


Ve sonuç tek tırnaklı değildir.
crokusek

5
Bu doğru cevaptır, çünkü yerine belirli bir taahhüdü kontrol etseniz bile çalışır HEAD.
Parsa

1
@Parsa: HEADBu taahhüt için belirli bir taahhüt noktasını kontrol ederken adlandırılmış bir branştan ziyade bağımsız kafa olarak bilin .
ChristofSenn

124

SHA'nın tamamını almak için:

$ git rev-parse HEAD
cbf1b9a1be984a9f61b79a05f23b19f66d533537

Kısaltılmış sürümü edinmek için:

$ git rev-parse --short HEAD
cbf1b9a

İki Eğer git commitkarmaları ihtiyaç vardır, örneğin gelen biri olarak branchşu anda çalışıyorsanız ve bir master branch, ayrıca kullanabilirsiniz git rev-parse FETCH_HEADsizin için karma gerekiyorsa master commito mergesenin akıma d branch. Eğer branches varsa masterve feature/new-featurebelirli bir repo için., üzerinde iken feature/new-featurekullanabilirsiniz git fetch origin master && git merge FETCH_HEADve sonra git rev-parse --short FETCH_HEADsizden commitkarma gerekiyorsa mastersadece merged olabilir herhangi bir komut dosyaları için.
EVAL

72

Tamlık için, kimse henüz önermedi. .git/refs/heads/masteryalnızca bir satır içeren bir dosyadır: en son taahhüdün karması master. Böylece oradan okuyabilirsiniz.

Veya komut olarak:

cat .git/refs/heads/master

Güncelleme:

Git'in artık / refs / heads / klasöründe bir dosya yerine pack-ref dosyasında bazı head ref'lerinin depolanmasını desteklediğini unutmayın. https://www.kernel.org/pub/software/scm/git/docs/git-pack-refs.html


10
Bu, mevcut dalın masterdoğru olmadığı varsayılır .
gavrie

12
Aslında. Bu yüzden açıkça bunun için olduğunu söyledim master.
Deestan

20
.git/HEADtipik olarak bir ref'ye işaret eder, eğer orada bir SHA1 varsa, ayrı kafa modundasınız.
eckes

8
Bu, diğer yaklaşımlara kıyasla çok sağlam değildir, özellikle de böyle bir .gitalt dizinin olduğunu varsaydığı için , durum böyle değildir. Man sayfasındaki --separate-git-dirbayrağa bakın git init.
jub0bs

16
+1 çünkü bazen git yürütülebilir dosyasının yüklenmesini istemiyorsunuz (örneğin Dockerfile dosyasında)
wim

50

Karma işlem

git show -s --format=%H

Kısaltılmış işleme karması

git show -s --format=%h

Daha fazla örnek için buraya tıklayın git show.


50

Her zaman git describeda var. Varsayılan olarak size -

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

18
Git tanımlaması, bir taahhütten erişilebilen ilk TAG'ı döndürür. Bu SHA'yı almama nasıl yardımcı olur?
Sardaukar

42
Gibi git describe --long --dirty --abbrev=10 --tagso bana böyle bir şey verecek 7.2.0.Final-447-g65bf4ef2d4"65bf4ef2d4" dir 447 7.2.0.Final etiketinden sonra kaydedilmesini ve ilk 10 cari BAŞ küresel SHA-1'in sindirmek olan. Bu sürüm dizeleri için çok iyi. --Long ile etiket tam olarak eşleşse bile her zaman sayıyı (-0-) ve karmayı ekler.
Eckes

14
Hiçbir etiket yoksa git describe --always"benzersiz olarak kısaltılmış tamamlama nesnesini yedek olarak göster"
Ronny Andersson

Ben kullanıyorum git describe --tags --first-parent --abbrev=11 --long --dirty --always. --alwaysSeçenek hiçbir etiket vardır bile sonuç (karma) sağlar anlamına gelir. --first-parentVasıta bunun birleştirme kaydedilmesini tarafından şaşkın ve yalnızca geçerli dalı öğeleri aşağıda almaz. Ayrıca , geçerli dalda taahhüt edilmemiş değişiklikler varsa sonuca --dirtyekleneceğini unutmayın -dirty.
Ocak'ta

30

kullanım git rev-list --max-count=1 HEAD


3
git-rev-list, işleme nesneleri listesi oluşturmakla ilgilidir; nesne adını (örn. HEAD) SHA-1'e çevirmek git-rev-ayrıştırmadır
Jakub Narębski

21

Komut dosyası sırasında karmayı bir değişkende depolamanız gerekiyorsa,

last_commit=$(git rev-parse HEAD)

Veya yalnızca ilk 10 karakteri istiyorsanız (github.com gibi)

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

26
Ayrıca --shortveya --short=numberparametreleri vardır git rev-parse; boru kullanmaya gerek yok ve cut.
Julian D.

15

Bunu yapmanın süper hacky yolunu istiyorsanız:

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

Temel olarak git, HEAD'in konumunu .git / HEAD biçiminde saklar ref: {path from .git}. Bu komut bunu okur, "ref:" bölümünü keser ve işaret ettiği dosyayı okur.

Bu, elbette, HEAD "ref: ..." değil, karma'nın kendisi olmayacağından bağımsız kafa modunda başarısız olacak - ama biliyorsunuz, bash'ınızda bu kadar akıllı olmasını beklediğinizi sanmıyorum. -liners. Noktalı virgüllerin aldattığını düşünmüyorsanız ...

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

1
git'i yüklemeye gerek yok, beğendim. (liman işçiliğimin imajı gitmiyor)
Helin Wang

Ayrıca yararlı çünkü git repo dışından kolayca çalıştırabilirsiniz
samaspin

Bunu yerel makinem için bir betikte resmileştirdim. Sonra düşündüm, hey: Yaptığım uygulama, ilgisiz bir sorunun nasıl çözüleceğini (harici programlar olmadan ham POSIX kabuk komut dosyalarında argümanları ayrıştırma) gösterecek kadar basit, ancak küçük bir varyasyon sağlamak ve çoğunu kullanmak için yeterince karmaşık özellikleri sh. Daha sonra yarım saatlik dokümantasyon yorumları ve işte bir özeti: gist.github.com/Fordi/29b8d6d1ef1662b306bfc2bd99151b07
Fordi

Ona baktığımda, Git ve SVN'yi tespit etmek ve git hash / svn revizyonunu almak için daha kapsamlı bir versiyon yaptım. Bu sefer temiz bir dize değil, ancak komut satırı kolayca ayrıştırıldı ve sürüm etiketi olarak kullanılabilir: gist.github.com/Fordi/8f1828efd820181f24302b292670b14e
Fordi

14

Bildiğim en kısa yol:

git show --pretty=%h 

Karma'nın belirli sayıda basamağını isterseniz ekleyebilirsiniz:

--abbrev=n

14
Bu teknik olarak çalışırken, git showbir porselen komutu olarak bilinen şeydir (yani kullanıcının gördüğü) ve böylece gerektiği değil çıkış değişikliğine tabi olduğu için komut kullanılmak. Bunun git rev-parse --short HEADyerine yukarıdaki ( ) yanıtı kullanılmalıdır.
jm3

4
@ jm3 bu geriye doğru. "Porselen" komutları komut dosyalarına yönelik kararlı çıktılara sahiptir. Arama git help showiçin porcelain.
John Tyree

2
@JohnTyree Bu kafa karıştırıcı bir konu, ama jm3 haklıydı: porselen komutlarının ayrıştırılması değil, insan tarafından okunabilir olması gerekiyor. Bir komut dosyasında porselen komutunu kullanmanız ve kararlı bir formata sahip olmak istiyorsanız, bazen (örneğin git durumu, itme ve suçlama ile) bunu yapan bir seçenek vardır. Ne yazık ki, bu seçenek denir --porcelain, bu yüzden bu kafa karıştırıcıdır. VonC tarafından verilen bu harika yanıtın
Fabio, Reinstate Monica

1
Bu seçeneği adlandırmaya karar veren sevgili tanrı - porselen onları bulmak istiyorum ve ... oh bekle onları bulmak için git kullanmalıyım nevermind
Britton Kerin

14

Belki de bir takma ad istersiniz, böylece tüm şık ayrıntıları hatırlamanız gerekmez. Aşağıdaki adımlardan birini yaptıktan sonra yazmanız yeterlidir:

$ git lastcommit
49c03fc679ab11534e1b4b35687b1225c365c630

Kabul edilen cevabı takiben , bunu ayarlamanın iki yolu şunlardır:

1) Git global yapılandırmayı düzenleyerek açık yolu öğretin (orijinal cevabım):

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

2) Ya da Adrien tarafından son zamanlarda yorumlandığı gibi git'e bir kısayol öğretmek için bir kısayol isterseniz:

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

Buradan sonra, git lastcommitson taahhüdün karmasını göstermek için kullanın .


3
Adrien de Sentenac git config dosyasını manuel olarak düzenlemek yerine şunları yapabileceğinizi not eder:git config --global alias.lastcommit "rev-parse HEAD"
cgmb

12

Biraz daha farklı bir şeye ihtiyacım vardı: taahhüdün tam sha1'ini göster, ancak çalışma dizini temiz değilse sonuna bir yıldız ekleyin. Birden fazla komut kullanmak istemedikçe, önceki yanıtlardaki seçeneklerin hiçbiri çalışmaz.

İşte bunu yapan tek astar:
git describe --always --abbrev=0 --match "NOT A TAG" --dirty="*"
Sonuç:f5366ccb21588c0d7a5f7d9fa1d3f85e9f9d1ffe*

Açıklama: yalnızca "A ETİKETİ DEĞİL" etiketli etiketlerle geçerli açıklamayı (açıklamalı etiketler kullanılarak) tanımlar. Etiketler boşluk içeremediğinden, bu hiçbir zaman bir etiketle eşleşmez ve bir sonuç göstermek istediğimizden --always, komut, --abbrev=0kesinliğin tam ( ) sha1'ini görüntüleyerek geri döner ve çalışma dizini ise bir yıldız ekler --dirty.

Yıldız işaretini eklemek istemiyorsanız, önceki yanıtlardaki diğer tüm komutlar gibi çalışır:
git describe --always --abbrev=0 --match "NOT A TAG"
Sonuç:f5366ccb21588c0d7a5f7d9fa1d3f85e9f9d1ffe


Teşekkürler, sadece tökezledi ve bana bunun için bir ya da başka bir yankı
yedekliyor

1
Olmadan benim için çalışıyor --match "NOT A TAG". Git 2.18.0 ve 2.7.4'te test edilmiştir. Bu argümanın gerekli olduğu herhangi bir durum var mı?
Thomas

@ Mevcut işlem geçmişinin herhangi bir yerinde ek açıklama eklenmiş bir etiketiniz varsa işe yaramaz. Sahte etiket, description komutunun taahhüdü tanımlamak için bir etiket kullanmadığından emin olur,
Rado

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

Yine de hız için gidiyorsanız, Deestan'ın bahsettiği yaklaşım

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

burada listelenen diğer yöntemlerden önemli ölçüde daha hızlıdır.


show-refBir sıhhi tesisat komutu var ve gelecek sürümlerde istikrarlı kalması dolayısıyla garantili (veya çok büyük olasılıkla en azından) bu yana, komut dosyası için en iyi seçenek olarak bana öyle geliyor: Başka cevaplar kullanmak rev-parse, show, describe, veya log, bütün porselen komutları olan. Ve hızın önemli olmadığı durumlarda , show-refmanpagedeki not geçerlidir: 'Bu yardımcı programın kullanımı .git dizini altındaki dosyalara doğrudan erişilmesi lehine teşvik edilir.'
Pont

6

İşte git dosyalarından doğrudan okuma kullanan Bash kabuğunda tek astar:

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

Git root klasörünüzde yukarıdaki komutu çalıştırmanız gerekir.

Bu yöntem, depo dosyalarınız olduğunda yararlı olabilir, ancak gitkomut yüklenmemişse.

Eğer işe yaramazsa, .git/refs/headsne tür kafalarınız olduğunu kontrol edin .


5

home-dir dosyasında ".gitconfig" dosyasında aşağıdakileri ekleyin

[alias]
sha = rev-parse HEAD

hatırlamanız daha kolay bir komutunuz olacaktır:

$ git sha
59fbfdbadb43ad0b6154c982c997041e9e53b600

3

Git bash'da $ git log -1 komutunu çalıştırmanız yeterlidir

göreceksiniz, bu satırlar emrinizi takip ediyor.

commit d25c95d88a5e8b7e15ba6c925a1631a5357095db .. (info about your head)

d25c95d88a5e8b7e15ba6c925a1631a5357095db, is your SHA for last commit.

0

İşte başka bir doğrudan erişim uygulaması:

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

Bu aynı zamanda yerel paket arşivleri için yararlı olan http üzerinde çalışır (Biliyorum: genel web siteleri için .git dizinini erişilebilir hale getirmeniz önerilmez):

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


0
cat .git/HEAD

Örnek çıktı:

ref: refs/heads/master

Ayrıştırma:

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

Pencereleriniz varsa, wsl.exe kullanmayı düşünebilirsiniz:

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

Çıktı:

refs/heads/master

Bu değer, daha sonra ödeme yapmak için kullanılabilir, ancak SHA'sını gösterir. Gerçek dalın adını göstermesini sağlamak için şunları yapın:

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

Çıktılar:

master

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.