Я намагаюся тут робити гаморні речі з гачками Git, але я не знаю, як це зробити (або якщо це можливо).
Що мені потрібно зробити: це в кожному комітеті я хочу взяти його хеш, а потім оновити файл у коміті з цим хешем.
Будь-які ідеї?
Я намагаюся тут робити гаморні речі з гачками Git, але я не знаю, як це зробити (або якщо це можливо).
Що мені потрібно зробити: це в кожному комітеті я хочу взяти його хеш, а потім оновити файл у коміті з цим хешем.
Будь-які ідеї?
Відповіді:
Я рекомендую зробити щось подібне до того, що ви маєте на увазі: розміщення SHA1 у нерозглянутому файлі, згенерованому як частина процесу збирання / встановлення / розгортання. Це, очевидно, легко зробити ( git rev-parse HEAD > filename
або, можливо, git describe [--tags] > filename
), і це дозволяє уникнути чогось божевільного, як, наприклад, закінчення файлу, який відрізняється від відстеження git.
Потім ваш код може посилатися на цей файл, коли йому потрібен номер версії, або якщо процес збирання може включити інформацію в кінцевий продукт. Останнє - це те, як git сам отримує номери версій - процес збирання вибирає номер версії з репо, потім вбудовує його у виконуваний файл.
Неможливо записати поточний хеш комісій: якщо вам вдасться заздалегідь обчислити майбутній хеш комісії - він зміниться, як тільки ви зміните будь-який файл.
Однак є три варіанти:
pre-commit
, зберігайте попередній хеш-комікс :) Ви не змінюєте / не вставляєте комісії у 99,99% випадків, тож, ЦЕ БУДЕ працювати. У гіршому випадку ви все одно можете визначити версію джерела.Я працюю над сценарієм гака, розміщу його тут "коли це буде зроблено", але все ж - раніше, ніж герцог Нукем назавжди випущений :))
Оновлення : код для .git/hooks/pre-commit
:
#!/usr/bin/env bash
set -e
#=== 'prev-commit' solution by o_O Tync
#commit_hash=$(git rev-parse --verify HEAD)
commit=$(git log -1 --pretty="%H%n%ci") # hash \n date
commit_hash=$(echo "$commit" | head -1)
commit_date=$(echo "$commit" | head -2 | tail -1) # 2010-12-28 05:16:23 +0300
branch_name=$(git symbolic-ref -q HEAD) # http://stackoverflow.com/questions/1593051/#1593487
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD} # 'HEAD' indicates detached HEAD situation
# Write it
echo -e "prev_commit='$commit_hash'\ndate='$commit_date'\nbranch='$branch'\n" > gitcommit.py
Тепер єдине, що нам потрібно - це інструмент, який перетворює prev_commit,branch
пару в реальний хеш-коміт :)
Я не знаю, чи може цей підхід роз'єднувати коміти. Перевіримо це незабаром
Хтось вказав мені на розділ "людина gitattributes" на ідентифікатор, який має таке:
ідентич
Коли ідентифікатор атрибута встановлений для шляху, git замінює $ Id $ в об'єкті blob на $ Id:, а потім - шістнадцятковий ім'я об'єкта blob у 40 символів, після чого знак $ долара при оформленні каси. Будь-яка послідовність байтів, яка починається з $ Id: і закінчується на $ у файлі робочого дерева, замінюється на $ Id $ при реєстрації.
Якщо ви подумаєте над цим, це також робить CVS, Subversion тощо. Якщо ви подивитеся на сховище, то побачите, що файл у сховищі завжди містить, наприклад, $ Id $. Він ніколи не містить розширення цього. Лише під час оформлення замовлення текст розгортається.
ident
- хеш для самого файлу, а не прискорення фіксації. Від git-scm.com/book/en/… : "Однак, цей результат має обмежене використання. Якщо ви використовували заміну ключових слів у CVS або Subversion, ви можете включити позначку дати - SHA не все так корисно, тому що це досить випадково, і ви не можете сказати, чи одна SHA старша чи новіша за іншу ". filter
займає роботу, але вона може отримати інформацію про фіксацію у файл (і з нього).
Цього можна досягти, використовуючи filter
атрибут у gitattributes . Вам потрібно буде вказати smudge
команду, яка вставляє ідентифікатор фіксації, і clean
команду, яка видаляє його, щоб файл, в який вставлено, не змінювався лише через ідентифікатор фіксації.
Таким чином, ідентифікатор фіксації ніколи не зберігається у краплі файлу; він просто розширений у вашій робочій копії. (Власне введення ідентифікатора фіксації в крапку стане нескінченно рекурсивним завданням. ☺) Кожен, хто клонує це дерево, повинен встановити атрибути для себе.
Подумайте поза коробкою фільмів!
вставте це в гачки файлів / після оформлення замовлення
#!/bin/sh
git describe --all --long > config/git-commit-version.txt
Версія буде доступна всюди, де ви її використовуєте.
Дозвольте мені вивчити, чому це складна проблема з використанням git Internals. Ви можете отримати sha1 поточної комісії за допомогою
#!/bin/bash
commit=$(git cat-file commit HEAD) #
sha1=($((printf "commit %s\0" $(echo "$commit" | wc -c); echo "$commit") | sha1sum))
echo ${sha1[0]}
По суті, ви запускаєте контрольну суму sha1 для поверненого повідомлення git cat-file commit HEAD
. Дві речі негайно вискакують як проблема, коли ви вивчаєте це повідомлення. Одне - дерево sha1, а друге - час фіксації.
Тепер легко здійснити час фіксації, змінивши повідомлення та здогадавшись, скільки часу потрібно, щоб здійснити фіксацію чи графік, щоб здійснити певний час. Справжня проблема - дерево sha1, з якого ви можете отримати git ls-tree $(git write-tree) | git mktree
. По суті, ви робите контрольну суму sha1 для повідомлення з ls-tree, що є переліком усіх файлів та їх контрольної суми sha1.
Тому ваша контрольна сума фіксації sha1 залежить від вашої контрольної суми sha1 дерева, що безпосередньо залежить від файлів контрольної суми sha1, яка завершує коло та залежить від sha1. Таким чином, у вас є кругова проблема з прийомами, доступними мені.
З менш захищеними контрольними сумами , було показано можливим записувати контрольну суму файлу у сам файл через грубу силу; однак я не знаю жодної роботи, яка б виконала це завдання з sha1. Це не неможливо, але поруч із неможливим із нашим теперішнім розумінням (але хто знає, можливо, через пару років це буде банально). Однак, це все ще важче піддається грубій силі, оскільки вам доведеться записати контрольну суму (фіксування) контрольної суми (дерева) контрольної суми (blob) контрольної суми у файл.