Як отримати хеш для поточного комітету в Git?


1931

Я хотів би зберегти (поки що) можливість зв’язати набори змін Git з робочими, що зберігаються в TFS.

Я вже написав інструмент (використовуючи гачок від Git), за допомогою якого я можу вставити workitemidentifiers у повідомлення набору змін Git.

Однак я також хотів би зберегти ідентифікатор комісії Git (хеша) у користувальницькому полі TFS. Таким чином я можу перевірити робочу програму в TFS і побачити, які набори змін Git пов'язані з робочим.

Як я можу легко отримати хеш з поточного комітету від Git?

Відповіді:


2808

Щоб включити довільну розширену посилання на об'єкт в SHA-1, використовувати просто ГИТ-Rev-розбір , наприклад

git rev-parse HEAD

або

git rev-parse --verify HEAD

Сторінка: Якщо ви хочете перетворити посилання ( гілки та теги ) в SHA-1, єgit show-refіgit for-each-ref.


81
--verifyмається на увазі, що:The parameter given must be usable as a single, valid object name. Otherwise barf and abort.
Linus 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.
Якуб Нарбський

36
Додавши до того, що сказав Тайн, Тайсон та Якуб, ви можете надрукувати повний хеш, але виділити шестикутники, необхідні для ідентифікації синього кольоруgit rev-parse HEAD | GREP_COLORS='ms=34;1' grep $(git rev-parse --short=0 HEAD)
Заз

423

Якщо ви хочете лише скорочений хеш:

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

Крім того, використання% H - це ще один спосіб отримати довгий хеш.


106
Або, здається, додавання --ort в команду rev-синтаксизу, здається, працює.
ауткультура

15
Я думаю git log, що фарфор і git rev-parseсантехніка.
Амеді Ван Гассе

Однією з переваг цього методу є те, що він поверне коротку версію хеша з правильною довжиною, пристосованою до колізійних зіткнень, які трапляються для більшого репосту. Принаймні, в останніх версіях git.
Ілля Сидоренко

4
Це поганий / неправильний спосіб зробити це, оскільки цей метод дасть вам неправильний хеш, якщо у вас відірвана голова. Наприклад, якщо поточна комісія - 12ab34 ... а попередня комісія - 33aa44 ... тоді, якщо я виконую "git checkout 33aa44", а потім я запускаю вашу команду, я все одно повернусь 12ab34 ... незважаючи на те, що моя голова фактично вказує до 33aa44 ...
theQuestionMan

3
@theQuestionMan Я не відчуваю поведінки, яку ви описуєте; git checkout 33aa44; git log -n 1дає мені 33aa44. Яку версію git ви використовуєте?
ауткультура

150

Ще один із використанням git log:

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

Він дуже схожий на @outofculture, хоча трохи коротший.


І результат не одноцитований.
crokusek

5
Це правильна відповідь, оскільки вона працює навіть у тому випадку, якщо ви перевіряєте певну комісію замість HEAD.
Парса

1
@Parsa: під час перевірки конкретних фіксів HEADвказує на це зобов’язання, а не на ім'я розгалужених знань як відокремлену голову .
КрістофСенн

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для даної репортажу, тоді як feature/new-featureви можете використовувати, git fetch origin master && git merge FETCH_HEADа потім, git rev-parse --short FETCH_HEADякщо вам потрібен commitхеш від masterвас, просто ви знайдете mergeбудь-які сценарії.
EVAL

72

Для повноти, оскільки ніхто ще не запропонував цього. .git/refs/heads/master- це файл, що містить лише один рядок: хеш останньої версії master. Тож ви могли просто прочитати його звідти.

Або, як команда:

cat .git/refs/heads/master

Оновлення:

Зауважте, що git тепер підтримує збереження деяких головних записів у файлі pack-ref замість файлу в папці / refs / heads /. https://www.kernel.org/pub/software/scm/git/docs/git-pack-refs.html


10
Це передбачає, що поточна галузь є master, що не обов'язково відповідає дійсності.
gavrie

12
Справді. Тому я прямо сказав, що це за master.
Деестан

20
.git/HEADяк правило, вказує на перелік, якщо у вас там є SHA1, ви перебуваєте в режимі відокремленої голови.
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 description повертає перший TAG, доступний з комітів. Як це допомагає мені отримати SHA?
Сардаукар

42
Мені подобається, що git describe --long --dirty --abbrev=10 --tagsце дасть мені щось на зразок 7.2.0.Final-447-g65bf4ef2d4447 фіксованих знаків після 7.2.0. Фінальний тег і перші 10 дайджестів глобального SHA-1 в поточній ГЛАВІ "65bf4ef2d4". Це дуже добре для рядків версій. З - довгий, він завжди додаватиме кількість (-0-) та хеш, навіть якщо тег точно збігається.
eckes

14
Якщо немає тегів, то git describe --always"відображатиметься однозначно скорочений об'єкт фіксації як резервний"
Ronny Andersson,

Я використовую 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 - це створення списку об'єктів комісій; це git-rev-parse для перекладу імені об’єкта (наприклад, HEAD) на SHA-1
Jakub Narębski

21

Якщо вам потрібно зберігати хеш у змінній під час сценарію, ви можете використовувати

last_commit=$(git rev-parse HEAD)

Або якщо ви хочете лише перших 10 символів (як це робить github.com)

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

26
Є також параметри --shortабо --short=numberдля git rev-parse; не потрібно використовувати трубу і cut.
Джуліан Д.

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
не потрібно встановлювати git, мені це подобається. (у мого зображення для створення докерів немає git)
Хелін Ван

також корисно, тому що ви можете легко запустити це за межами git repo
samaspin

Я формалізував це під сценарій для своєї локальної машини. Тоді, я подумав, ей: реалізація, яку я зробив, є досить простою, що ілюструє вирішення непов'язаної проблеми (розбір аргументів у необроблених скриптах оболонки POSIX без зовнішніх програм), але достатньо складна, щоб забезпечити невелику варіацію та використовувати більшість особливості sh. Півгодини документації коментарі пізніше, і ось суть
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.
Джон Тайрі

2
@JohnTyree Це заплутаний предмет, але jm3 був правильний: порцелянові команди призначені не для розбору, а для того, щоб прочитати людину. Якщо вам потрібно використовувати порцелянову команду в скрипті, і ви хочете мати стабільний формат, іноді (наприклад, зі статусом git, push і звинувачення) є варіант, який робить саме це. На жаль, такий варіант називається --porcelain, тому це заплутано. Подробиці ви можете знайти у цій чудовій відповіді VonC
Фабіо каже, що

1
шановний бог, який вирішив назвати цей варіант - порцеляновий, я хочу їх знайти і ... о, зачекайте, мені потрібно буде використовувати git, щоб знайти їх неважливо
Бріттон Керін

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) Або якщо вам подобається ярлик, щоб викладати ярлик ярлика, як недавно прокоментував Адрієн:

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

З цього git lastcommitмоменту використовуйте, щоб показати хеш останньої комісії.


3
Адріан де Сентенак зазначає, що замість того, щоб вручну редагувати файл git config, ви могли просто зробити:git config --global alias.lastcommit "rev-parse HEAD"
cgmb

12

Мені потрібно було дещо інше: відобразити повний sha1 комітету, але додати зірочку до кінця, якщо робочий каталог не чистий. Якщо я не хотів використовувати декілька команд, жоден із варіантів попередніх відповідей не працює.

Ось один вкладиш, який робить:
git describe --always --abbrev=0 --match "NOT A TAG" --dirty="*"
Результат:f5366ccb21588c0d7a5f7d9fa1d3f85e9f9d1ffe*

Пояснення: описує (використовуючи помічені теги) поточну комісію, але лише з тегами, що містять "NOT TAG". Оскільки в тегах не може бути пробілів, це ніколи не відповідає тегу, і оскільки ми хочемо показати результат --always, команда опускається, відображаючи повний ( --abbrev=0) sha1 комітету, і додає зірочку, якщо робочий каталог--dirty .

Якщо ви не хочете додати зірочку, це працює, як і всі інші команди в попередніх відповідях:
git describe --always --abbrev=0 --match "NOT A TAG"
Результат:f5366ccb21588c0d7a5f7d9fa1d3f85e9f9d1ffe


Дякую, просто наткнувшись на це, і це
позбавить

1
Це працює для мене без --match "NOT A TAG". Тестували в git 2.18.0, а також 2.7.4. Чи є якась ситуація, коли цей аргумент потрібен?
Томас

@Thomas не працюватиме, якщо у вас є дедалі помічені теги десь в історії поточного комітету. Підроблений тег переконує, що команда description не використовує тег для опису фіксації,
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."
Понт

6

Ось один вкладиш в оболонці Bash з використанням прямого зчитування з файлів git:

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

Вам потрібно запустити вище команду у вашій кореневій папці git.

Цей метод може бути корисним, коли у вас є файли репозиторію, але 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.