Comment puis-je remplir l'ID git commit dans un fichier lorsque je commets?

je voudrais créer git hook (s) qui remplira l'id de propagation de la propagation que je suis sur le point de faire dans un fichier (essentiellement la substitution de variables) dans mon code source. Est-ce possible avec Git? Ou est le fait qu'en résolvant la variable à l'id git, je vais changer le sha 1, se terminant ainsi avec un problème "poulet ou l'œuf".

26
git
demandé sur BestPractices 2013-05-13 18:13:45

9 réponses

la solution que j'ai utilisée pour une situation similaire est celle-ci:

  1. Mettre la chaîne $Id$ quelque part dans le fichier que vous voulez avoir identifié (par exemple,test.html), probablement dans un commentaire ou une autre section non fonctionnelle du fichier où il ne causera pas de problèmes.
  2. Dans votre .gitattributes, marquez le fichier en question avec le ident mot clé (par exemple,*.html ident).

Le résultat de cela est que lorsque git checkout copie le fichier de l'objet base de données dans votre répertoire de travail, il étend le $Id$ chaîne de caractères à lire $Id: <sha-1 of file>$ et git add inverse cette transformation quand vous voulez la Vérifier, donc les versions de ce fichier dans votre base de données d'objets ne contiennent que $Id$, pas les formulaires élargis.

C'est un début, mais malheureusement, trouver le commit qui contient un fichier avec un hash n'est pas si facile, et pas nécessairement un-à-un. Donc, en plus, j'étiquette aussi ces fichiers avec le export-subst attribut (par exemple,*.html ident export-subst.gitattributes), et ajouter une chaîne supplémentaire, comme $Format:%ci$ ($Format:%h$) quelque part dans le fichier.

git checkout et git add n'affecte pas ces balises, donc les versions de mon dépôt ont toujours exactement cette chaîne. Pour obtenir ces balises étendues, vous devez utiliser git archive pour créer une boule de goudron (or .zip) d'une version spécifique de votre projet, que vous utilisez ensuite pour déployer cette version - vous ne pourrez pas simplement copier les fichiers, ou make install ou quoi que, depuis git archive est la seule chose qui permettra d'élargir ces balises.

les deux balises que j'ai données comme exemple s'étendent à YYYY-MM-DD HH:MM:SS +TZOFFSET (HASH)HASH dans ce cas est le hachage de propagation réel, donc c'est plus utile.

Vous pouvez trouver d'autres potentiellement utile $Format:$ prescripteurs dans le git log Page d'aide sous le --pretty-format les prescripteurs.

31
répondu twalberg 2013-05-13 18:54:53

vous pouvez créer un filtre qui effectue la substitution des fichiers sur commit et checkout. Ces filtres sont appelés "smudge" et "clean" et leur fonctionnement est contrôlé par .gitattributes. Par exemple:

*.c     filter=yourfilter

Ceci indique à git de lancer le yourfilter filtre pour tous .c fichiers. Vous devez alors dire à git ce que yourfilter signifie:

git config --global filter.yourfilter.clean script1
git config --global filter.yourfilter.smudge script2

vous écririez alors un script (sed, Perl, Python, ou autre) pour remplacer une expression comme $LastSha$$LastSha: <sha>$ à la caisse ("bavure"). L'autre script inverse l'extension avant commit ("clean").)

Rechercher dans le Pro Git livre pour "Keyword Expansion" pour un exemple détaillé.

7
répondu Andomar 2013-05-13 14:26:33

il est impossible de faire ce que vous voulez: le hachage SHA-1 de la propagation est calculé sur l'ensemble du dépôt d'instantanés, y compris chaque fichier membre, donc il y a le problème du poulet et de l'œuf - pour calculer le hachage de la propagation, vous devez connaître le contenu de tous les fichiers qui le composent.

6
répondu kostix 2013-05-13 15:12:11

vous pouvez le faire avec le post-commit crochet. Voici un extrait de git-scm site web

une fois le processus de propagation terminé, le crochet post-propagation s'exécute. Il ne prend aucun paramètre, mais vous pouvez facilement obtenir la dernière propagation en exécutant la tête git log -1. En général, ce script est utilisé pour la notification ou quelque chose de similaire.

il s'agirait d'obtenir la sortie de git log -1 HEAD, puis en utilisant un outil comme sed pour remplacer les variables dans votre fichier. Cependant, cela modifie votre répertoire de travail, et à moins que vous n'alliez jeter ces changements, alors vous finiriez avec un répertoire de travail modifié de façon permanente.

si vous voulez juste utiliser le hachage de propagation courant dans une variable quelque part dans votre code, vous pouvez juste exécuter git log -1 HEAD ou cat .git/HEAD et stockez la sortie dans votre variable

si vous voulez seulement l'id (hash) comme dans le titre de la question, vous pouvez utiliser le --format drapeau. git log -1 HEAD --format=%H

4
répondu Jon Cairns 2015-06-26 17:06:55

OK, inspiré par la réponse de Jon Cairns, j'ai trouvé ce petit morceau que vous pourriez mettre dans votre Makefile.

version.h:
        git log -n 1 --format=format:"#define GIT_COMMIT \"%h\"%n" HEAD > $@

ce n'est pas une solution tout à fait générale, mais elle pourrait s'avérer utile. Je connais un ou deux endroits où je l'utiliserai.

2
répondu Edward Falk 2016-06-28 23:31:33

la clé ici est de mettre votre identifiant de révision dans un fichier dont Git ne se soucie pas. Voici un fragment d'un de mes projets:

.
.
.
AssemblyCS="Properties/AssemblyInfo.cs"
rev="$(git log -n 1 --date=short --format=format:"rev.%ad.%h" HEAD)"
sed  "$AssemblyCS"
.
.
.

ce script est exécuté dans le cadre de mon processus de compilation (il peut aussi s'agir d'un hook post-commit). Dans ce cas Properties/AssemblyInfo.cs.gitignore alors que Properties/AssemblyInfo.cs.in est sous contrôle de version. La construction utilise le .csfilewh qui inclut un identifiant de révision qui se retrouve dans l'exécutable déployé.

1
répondu Adrian Ratnapala 2013-05-13 19:12:56

comme d'autres l'ont mentionné, vous ne pouvez pas mettre le SHA-1 d'un commit lui-même dans le fichier pendant le même commit. Cela serait d'une utilité limitée de toute façon puisque en regardant deux fichiers que vous ne seriez pas immédiatement en mesure de dire ce qui est plus récent.

cela étant dit, il y a en fait un moyen de mettre automatiquement les informations de suivi de version dans les fichiers engagés. J'ai fait cela pour mon projet actuel (FrauBSD; une version de FreeBSD sur laquelle je travaille).

je l'ai réalisé sans l'aide d'un git-attributs de filtre. Alors que les filtres git-attributes permettent d'obtenir facilement le contraire (mettre l'information dans le ou les fichiers sur la commande), ce que je voulais était d'étendre certains mots-clés au moment de la propagation afin que les données soient dans le dépôt(par exemple, après un "git push origin master", github montre des valeurs étendues dans le ou les fichiers engagés). La réalisation de ce dernier s'est avérée extrêmement difficile avec un filtre git-attributs précisément parce qu'un simple" diff git " invoquera le filtre.propre attribut et, comme c'était le cas dans mon cas, si vous mettez des informations de date/heure dans l'extension, avoir la valeur change chaque fois que vous effectuez "git diff" est indésirable et inacceptable.

J'ai donc développé un crochet pre-commit et un crochet commit-msg qui, en agissant ensemble, résolvent le problème de savoir comment (spécifiquement dans le cas de FrauBSD) remplacer ce qui suit dans les fichiers engagés:

$FrauBSD$

avec quelque chose de similaire à ce qui suit avant l'enregistrement (les valeurs élargies vont en amont pour que les autres aillent à la caisse):

$FrauBSD: filepath AAAA-MM-JJ HH: MM: ZZ GMTOFFSET committer $

lorsque quelqu'un parcourt le fichier sur github ou effectue une vérification ou une fusion du(des) fichier (s), l'information étendue suit son cours.

NOTE: la valeur augmentée ne changera jamais sauf s'il y a un autre changement (non lié) qui accompagne, respectivement.

par exemple, voir la commit suivante dans laquelle je supprimer une nouvelle ligne d'un fichier. Le fichier commit contient à la fois la suppression de la nouvelle ligne de départ et une majoration de la date/heure dans le mot-clé $FrauBSD$:

https://github.com/freebsdfrau/FrauBSD/commit/060d943d86bb6a79726065aad397723a9c704ea4

Pour produire ce commit, j'ai fait ce que la plupart des [git] les développeurs sont familiarisés avec:

  1. licence vi
  2. Maj-G # aller à la fin du fichier
  3. dd # supprimer l'actuel ligne
  4. ZZ # enregistrez le fichier et quittez
  5. git diff # diff illustre le retrait de fuite de saut de ligne NOTE: diff does afficher un changement à $FrauBSD$ value [yet]
  6. git add LICENSE
  7. git diff # rien (pas de unstaged modifications)
  8. git diff --cached # diff illustre le retrait de fuite de saut de ligne NOTE: diff [encore] afficher un changement à la valeur $FrauBSD$
  9. git status # montre modifié Licence
  10. git commit # $ÉDITEUR vient
  11. Ctrl-Z # $RÉDACTEUR en arrière-plan, afin que nous puissions enquêter
  12. git diff --cached # diff [maintenant] montre $FrauBSD$ mise à jour ainsi que l'enlèvement de fuite de retour à la ligne
  13. fg # resume $ EDITOR
  14. : q! # quittez l'Éditeur sans modifications NOTE: parce que vous avez avorté le commit, $FrauBSD$ a été inversé
  15. git diff --cached # diff [nouveau] montre seulement de fuite de saut de ligne retrait
  16. git commit # cette fois, nous n'avortent pas
  17. BumpZZ # Insérer "Bosse", enregistrer et quitter
  18. le Fichier est engagé en tant que-est

REMARQUE: Rien ne doit être fait pour le fichier post-commit

C'est parce que j'ai les fichiers suivants dans mon projet:

  • .git/hooks / pre-commit (lien symbolique vers ../../.crochets/pre-commit)
  • .git/hooks / commit-msg (lien symbolique vers ../../.crochets/commit-msg)
  • .crochets/pre-commit
  • .crochets/commit-msg
  • .filtres/fraubsd de mots-clés

La première révisions de laquelle vous pouvez obtenir ici:

"Ajouter des crochets/filtres de pré-commettre des bavures"

https://github.com/freebsdfrau/FrauBSD/commit/63fa0edf40fe8f5936673cb9f3e3ed0514d33673

NOTE: les filtres sont utilisés par les crochets (non utilisés dans git-attributs).

Et une mise à jour ici:

https-//github.com/freebsdfrau/FrauBSD/commit/b0a0a6c7b2686db2e8cdfb7253aba7e4d7617432

Ou vous pouvez voir la tête des révisions ici:

https - / github.com / freebsdfrau/FrauBSD/tree/master/.filtres

https - / github.com / freebsdfrau/FrauBSD/tree/master/.hooks

NOTE: colon modifié à-dans les URLs ci-dessus afin que je puisse poster plus de 2 liens (puisque la réputation est faible)

Profitez de, FreeBSDFrau

1
répondu src committer 2016-01-10 00:08:51

je cherchais quelque chose de similaire, en ce que je voulais une variable unique que je pourrais ajouter à la fin des fichiers de ressources (comme CSS/JS) dans notre face avant, ce qui nous permettrait de définir des temps de cache Très longs pour réduire la bande passante et augmenter les performances, mais les forcer facilement à être rechargés après n'importe quelle propagation. Essentiellement versioning fichier, mais totalement automatisé. Je m'en fichais que ce soit le MOST récente, tant qu'il était unique, automatisé, et cohérentes sur l'ensemble de notre application serveur.

notre script de déploiement utilise simplement "git clone" pour extraire une copie du code le plus récent dans nos serveurs app, mais nous restreignons l'accès via .htaccess pour les fichiers et les répertoires.

/.git/ répertoire contient un fichier appelé ORIG_HEAD qui est mis à jour après toute fusion (ou toute autre dangereux opération) avec le numéro D'identification de son prédécesseur. Puisque nous utilisons git flow, c'est parfait car il met à jour chaque fois que nous poussons un release ou fix maître branche et à déployer.

vous pouvez le faire je suppose dans n'importe quel langage de script mais dans notre cas, PHP, Je l'ai fait comme ça...

define("MY_VERSION",substr(file_get_contents(realpath(__DIR__.'/../.git/ORIG_HEAD')),0,3));

votre chemin devrait évidemment être modifié pour vos propres besoins, mais cela se traduit par un 3 char assez unique id pour nos fins, qui est ajoutée à la fin de notre URL de ressource est maintenant.

espoir qui aide quelqu'un dans la même situation.

0
répondu oucil 2016-06-15 14:27:00
./.git/refs/heads/master Ainsi, dans notre solution de livraison continue (il télécharge le .git dossier avec le code source), nous pouvons simplement cat ./.git/refs/heads/${BRANCH} pour associer le hash de commit actuel avec notre build

0
répondu Paul Sambolin 2017-01-31 15:31:35