web-dev-qa-db-fra.com

Dans Git, comment puis-je écrire le hachage de validation actuel dans un fichier dans le même commit

J'essaie de faire des trucs fantaisistes ici avec des crochets Git, mais je ne sais pas vraiment comment le faire (ou si c'est possible).

Ce que je dois faire est: dans chaque commit, je veux prendre son hachage puis mettre à jour un fichier dans le commit avec ce hachage.

Des idées?

112
Felipe Kamakura

Je recommanderais de faire quelque chose de similaire à ce que vous avez en tête: placer le SHA1 dans un fichier non suivi, généré dans le cadre du processus de construction/installation/déploiement. C'est évidemment facile à faire (git rev-parse HEAD > filename ou peut-être git describe [--tags] > filename), et cela évite de faire quelque chose de fou comme se retrouver avec un fichier différent du suivi de git.

Votre code peut ensuite référencer ce fichier lorsqu'il a besoin du numéro de version, ou un processus de génération pourrait incorporer les informations dans le produit final. Ce dernier est en fait la façon dont git lui-même obtient ses numéros de version - le processus de construction saisit le numéro de version du référentiel, puis le construit dans l'exécutable.

76
Cascabel

Quelqu'un m'a signalé la section "man gitattributes" sur ident, qui a ceci:

ident

Lorsque l'identifiant d'attribut est défini pour un chemin, git remplace $ Id $ dans l'objet blob par $ Id :, suivi du nom de l'objet blob hexadécimal à 40 caractères, suivi du signe dollar $ lors du paiement. Toute séquence d'octets commençant par $ Id: et se terminant par $ dans le fichier d'arbre de travail est remplacée par $ Id $ lors de l'enregistrement.

Si vous y réfléchissez, c'est ce que font également CVS, Subversion, etc. Si vous regardez le référentiel, vous verrez que le fichier dans le référentiel contient toujours, par exemple, $ Id $. Il ne contient jamais l'expansion de cela. Ce n'est qu'à la caisse que le texte est développé.

12
Baron Schwartz

Il est impossible d'écrire le hachage de validation actuel: si vous parvenez à pré-calculer le futur hachage de validation, il changera dès que vous modifiez un fichier.

Cependant, il existe trois options:

  1. Utilisez un script pour incrémenter "commit id" et l'inclure quelque part. Laid
  2. .gitignore le fichier dans lequel vous allez stocker le hachage. Pas très pratique
  3. Dans pre-commit, stockez le hachage de validation précédent :) Vous ne modifiez/insérez pas les validations dans 99,99% des cas, cela fonctionnera donc. Dans le pire des cas, vous pouvez toujours identifier la révision source.

Je travaille sur un script de hook, je le posterai ici `` quand c'est fait '', mais toujours - avant la sortie de Duke Nukem Forever :))

UPD : code pour .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

Maintenant, la seule chose dont nous avons besoin est un outil qui convertit prev_commit,branch paire à un vrai hachage de validation :)

Je ne sais pas si cette approche peut distinguer les commits de fusion. Le vérifiera bientôt

11
kolypto

Ceci peut être réalisé en utilisant l'attribut filter dans gitattributes . Vous devez fournir une commande smudge qui insère l'ID de validation et une commande clean qui le supprime, de telle sorte que le fichier dans lequel il est inséré ne change pas simplement à cause de l'ID de validation .

Ainsi, l'ID de validation n'est jamais stocké dans le blob du fichier; il est simplement développé dans votre copie de travail. (L'insertion en fait de l'identifiant de validation dans le blob deviendrait une tâche infiniment récursive. ☺) Toute personne qui clone cet arbre devrait configurer les attributs pour elle-même.

9
legoscia

Pensez en dehors de la boîte de validation!

pop cela dans les crochets de fichiers/post-checkout

#!/bin/sh
git describe --all --long > config/git-commit-version.txt

La version sera disponible partout où vous l'utiliserez.

4
Keith Patrick

Je ne pense pas que vous vouliez réellement le faire, car lorsqu'un fichier dans la validation est modifié, le hachage de la validation est également modifié.

3
midtiby

Permettez-moi d'explorer pourquoi c'est un problème difficile en utilisant les internes de git. Vous pouvez obtenir le sha1 du commit actuel en

#!/bin/bash
commit=$(git cat-file commit HEAD) #
sha1=($((printf "commit %s\0" $(echo "$commit" | wc -c); echo "$commit") | sha1sum))
echo ${sha1[0]}

Essentiellement, vous exécutez une somme de contrôle sha1 sur le message renvoyé par git cat-file commit HEAD. Deux choses sautent immédiatement aux yeux lorsque vous examinez ce message. L'un est l'arborescence sha1 et le second est le temps de validation.

Maintenant, le temps de validation est facilement pris en charge en modifiant le message et en devinant combien de temps il faut pour effectuer une validation ou planifier la validation à un moment précis. Le vrai problème est l'arborescence sha1, que vous pouvez obtenir à partir de git ls-tree $(git write-tree) | git mktree. Essentiellement, vous effectuez une somme de contrôle sha1 sur le message de ls-tree, qui est une liste de tous les fichiers et de leur somme de contrôle sha1.

Par conséquent, votre somme de contrôle sha1 de validation dépend de votre somme de contrôle sha1 de l'arborescence, qui dépend directement de la somme de contrôle sha1 des fichiers, qui termine le cercle et dépend de la validation sha1. Vous avez donc un problème circulaire avec les techniques dont je dispose.

Avec sommes de contrôle moins sécurisées , il a été démontré qu'il était possible d'écrire la somme de contrôle du fichier dans le fichier lui-même par la force brute; cependant, je ne connais aucun travail ayant accompli cette tâche avec sha1. Ce n'est pas impossible, mais presque impossible avec notre compréhension actuelle (mais qui sait peut-être que dans quelques années, ce sera trivial). Cependant, cela est encore plus difficile à utiliser en force brute, car vous devez écrire la somme de contrôle (validation) d'une somme de contrôle (arborescente) d'une somme de contrôle (blob) dans le fichier.

0
Novice C