Passer de CVS à Git: $Id:$ equivalent?
j'ai lu un tas de questions sur les outils simples de contrôle du code source et Git semblait un choix raisonnable. Je l'ai fait fonctionner, et ça fonctionne bien jusqu'à présent. Un aspect que J'aime chez CVS est l'incrémentation automatique d'un numéro de version.
je comprends que cela a moins de sens dans un dépôt distribué, mais en tant que développeur je veux/j'ai besoin de quelque chose comme ça. Laissez-moi vous expliquer pourquoi:
J'utilise Emacs. Périodiquement Je passe en revue et cherche de nouvelles versions des fichiers source Lisp pour les paquets tiers. Dire que j'ai un fichier foo.el, qui, selon l'en-tête, est la version 1.3; si je regarde la dernière version et qu'il est 1.143 ou 2.6 ou peu importe, je sais que je suis assez loin derrière.
si au lieu de cela je vois un couple de coups de fouet de 40 caractères, Je ne saurai pas qui est plus tard ou obtenir une idée de combien il est plus tard. Je détesterais absolument si je devais vérifier manuellement les ChangeLogs juste pour avoir une idée de comment sortir de la date à laquelle je suis.
en tant que développeur, je veux étendre cette courtoisie, comme je le vois, aux gens qui utilisent ma sortie (et peut-être que je me moque moi-même que n'importe qui est, mais laissons cela de côté pour un moment). Je ne veux pas avoir à me rappeler d'augmenter ce foutu nombre moi-même à chaque fois, ou un horodatage ou quelque chose comme ça. C'est une vraie PITA, et je le sais par expérience.
alors quelles alternatives ai-je? Si Je ne peux pas obtenir un $ Id:$ equivalent, Comment puis-je fournir ce que je cherche?
je devrais mentionner que mon attente est que l'utilisateur final ne sera pas installé Git et même si elles le font, ne sera pas un dépôt local (en effet, je m'attends à ne pas le rendre disponible de cette façon).
15 réponses
la SHA n'est qu'une représentation d'une version (quoique canonique). La commande git describe
en offre d'autres et le fait très bien.
par exemple, quand j'exécute git describe
dans ma branche principale de mon Java memcached client source, je reçois ceci:
2.2-16-gc0cd61a
qui dit deux choses importantes:
- il y a eu exactement 16 commits dans cet arbre depuis 2.2
- l'arbre des sources exact peut être affiché sur le clone de n'importe qui d'autre.
disons, par exemple, que vous avez empaqueté un fichier version
avec la source (ou même réécrit tout le contenu pour distribution) pour montrer ce nombre. Disons que la version empaquetée était 2.2-12-g6c4ae7a
(pas une version, mais une version valide).
vous pouvez maintenant voir exactement à quelle distance derrière vous êtes (4 commits), et vous pouvez voir exactement ce que 4 commet:
# The RHS of the .. can be origin/master or empty, or whatever you want.
% git log --pretty=format:"%h %an %s" 2.2-12-g6c4ae7a..2.2-16-gc0cd61a
c0cd61a Dustin Sallings More tries to get a timeout.
8c489ff Dustin Sallings Made the timeout test run on every protocol on every bui
fb326d5 Dustin Sallings Added a test for bug 35.
fba04e9 Valeri Felberg Support passing an expiration date into CAS operations.
à l'heure actuelle, il ya un soutien pour $Id:$ in Git. Pour l'activer pour le fichier README vous mettriez" README ident "dans .gitattributes . Les jokers sur les noms de fichiers sont supportés. Voir l'homme gitattributes pour plus de détails.
ce n'est pas une demande déraisonnable de L'OP.
mon étui est:
- j'utilise Git pour mon propre code personnel, donc pas de collaboration avec les autres.
- j'y garde des scripts de Bash système qui pourraient aller dans
/usr/local/bin
quand ils sont prêts.
j'utilise trois machines avec le même dépôt Git. Il serait bon de savoir quelle "version" de la le fichier que j'ai actuellement dans /usr/local/bin
sans avoir à faire un manuel de "diff -u
Pour ceux qui sont négatifs, rappelez-vous il y a d'autres cas d'utilisation. Tout le monde n'utilise pas Git pour travailler en collaboration avec les fichiers du dépôt Git étant leur emplacement "final".
de toute façon, la façon dont je l'ai fait était de créer un fichier d'attributs dans le dépôt comme ceci:
cat .git/info/attributes
# see man gitattributes
*.sh ident
*.pl ident
*.cgi ident
Puis mettez $ Id $ quelque part dans le fichier (j'aime le mettre après le shebang).
Le commettre. Notez que cela ne fait pas automatiquement l'expansion comme je m'y attendais. Vous devez re-co le fichier, par exemple,
git commit foo.sh
rm foo.sh
git co foo.sh
et ensuite vous verrez l'expansion, par exemple:
$ head foo.sh
#!/bin/sh
# $Id: e184834e6757aac77fd0f71344934b1cd774e6d4 $
quelques bonnes informations sont dans comment activer la chaîne ident pour un dépôt Git? .
Je ne suis pas sûr que ce sera jamais en Git. À cite Linus :
" toute la notion de substitution de mots clés est tout simplement totalement stupide. C'est trivial à faire de "l'extérieur" du contenu réel de suivi, si vous voulez avoir en faisant libérer les arbres comme tar-balls, etc."
il est assez facile de vérifier le journal, cependant - si vous traquez foo.branche stable d'el, vous pouvez voir ce que les nouvelles commits sont en le journal de la branche stable qui n'est pas dans votre copie locale. Si vous voulez simuler le numéro de version interne de CVS, vous pouvez comparer l'horodatage de la dernière propagation.
Edit: vous devriez écrire ou utiliser les scripts de quelqu'un d'autre pour cela, bien sûr, ne pas le faire manuellement.
comme j'ai écrit avant :
avoir généré automatiquement des étiquettes D'identification qui montrent un numéro de version sensible est impossible à faire avec des outils DSCM comme Bazaar parce que la ligne de développement de tout le monde peut être différente de tous les autres. Donc quelqu'un pourrait se référer à la version "1.41" d'un fichier, mais votre version "1.41" de ce fichier est différent.
en gros, $Id$ n'a aucun sens avec Bazaar, Git, et d'autres outils de gestion de code source distribués.
j'ai eu le même problème. J'avais besoin d'une version plus simple qu'une chaîne de hachage et disponible pour les personnes utilisant l'outil sans avoir besoin de se connecter au dépôt.
Je l'ai fait avec un crochet de pré-commit Git et j'ai changé mon script pour pouvoir se mettre à jour automatiquement.
je base la version sur le nombre de commits effectués. C'est une condition de race légère parce que deux personnes pourraient commettre en même temps et les deux pensent qu'ils sont en train de propager le même numéro de version, mais nous n'avons pas beaucoup de développeurs sur ce projet.
Mine est en rubis, mais ce n'est pas terriblement complexe code. Le script Ruby a:
MYVERSION = '1.090'
## Call script to do updateVersion from .git/hooks/pre-commit
def updateVersion
# We add 1 because the next commit is probably one more - though this is a race
commits = %x[git log #{"151900920"} | grep '^commit ' | wc -l].to_i + 1
vers = "1.%0.3d" % commits
t = File.read("151900920")
t.gsub!(/^MYVERSION = '(.*)'$/, "MYVERSION = '#{vers}'")
bak = "151900920"+'.bak'
File.open(bak,'w') { |f| f.puts t }
perm = File.stat("151900920").mode & 0xfff
File.rename(bak,"151900920")
File.chmod(perm,"151900920")
exit
end
et puis j'ai une option en ligne de commande (- updateVersion) qui appelle updateVersion pour l'outil.
enfin, je vais à la tête de Git et je crée un script exécutable dans .git/hooks/pre-commit
.
le script change simplement chef du répertoire Git et appelle mon script avec -updateVersion
.
chaque fois que je vérifie, la variable MYVERSION est mise à jour en fonction du nombre de propagations.
quelque chose qui est fait avec les dépôts Git est d'utiliser l'objet tag
. Cela peut être utilisé pour marquer un commit avec tout type de chaîne et peut être utilisé pour marquer les versions. Vous pouvez voir que les tags dans un dépôt avec la commande git tag
, qui renvoie toutes les tags.
Il est facile de vérifier une balise. Par exemple, s'il y a une balise v1.1
vous pouvez vérifier cette balise sur une branche comme celle-ci:
git checkout -b v1.1
comme c'est un niveau supérieur objet, vous verrez toute l'histoire qui s'engagent, ainsi que d'être en mesure d'exécuter des diffs, faire des changements, et les fusions.
non seulement cela, mais une étiquette persiste, même si la branche qu'il était sur a été supprimé sans être fusionné de nouveau dans la ligne principale.
si vous voulez juste que les gens puissent se faire une idée à quel point ils sont dépassés, Git peut les en informer de plusieurs façons assez faciles. Ils comparent les dates de la dernière propagation sur leur tronc et votre tronc, par exemple. Ils peuvent utiliser git cherry
pour voir combien de commits se sont produits dans votre tronc qui ne sont pas présents dans le leur.
si c'est tout ce que vous voulez, je chercherais un moyen de le fournir sans numéro de version.
aussi, je ne prendrais pas la peine d'étendre la courtoisie à quiconque à moins que vous êtes sûr qu'ils le veulent. :)
si je comprends bien, essentiellement, vous voulez savoir combien de commits se sont produits sur un fichier donné depuis votre dernière mise à jour.
obtenez D'abord les modifications de l'origine distante, mais ne les fusionnez pas dans votre master
branche:
% git fetch
puis obtenir un journal des changements qui se sont produits sur un fichier donné entre votre master
branche et la télécommande origin/master
.
% git log master..origin/master foo.el
cela vous donne les messages de journalisation de toutes les propagations qui se sont produites dans le dépôt distant depuis la dernière fusion de origin/master
dans votre master
.
si vous voulez simplement compter les changements, passez-le à wc
. Dis, comme ceci:
% git rev-list master..origin/master foo.el | wc -l
RCS Id sont sympa pour un seul fichier de projets, mais pour tous les autres le $Id$ ne dit rien sur le projet (à moins que vous ne contraint mannequin check-ins à un mannequin de fichier d'une version).
encore un pourrait être intéressé comment obtenir les équivalents de$ Author$, $Date$, $Revision$, $ RCSfile$, etc. fichier par fichier ou à la validation du niveau (comment les mettre où certains mots-clés sont, c'est une autre question). Je n'ai pas de réponse à ce sujet, mais voir la nécessité de mettre à jour ces, surtout lorsque les fichiers (maintenant dans Git) proviennent de systèmes compatibles avec RCS (CVS).
de tels mots-clés peuvent être intéressants si les sources sont distribuées séparément de n'importe quel dépôt Git (c'est ce que je fais aussi). Ma solution est la suivante:
Chaque projet a son propre répertoire, et dans la racine du projet, j'ai un fichier texte nommé .version
dont le contenu décrit la version actuelle (le nom qui sera utilisé lors de l'exportation des sources).
pendant que vous travaillez pour la prochaine version, un script extrait ce numéro .version
, un descripteur de version Git (comme git describe
) et un numéro de build monotone dans .build
(plus l'hôte et la date) vers un fichier source généré automatiquement qui est lié au programme final, de sorte que vous pouvez savoir à partir de quelle source et quand il a été construit.
je développe de nouvelles fonctionnalités dans des branches séparées, et la première chose que je fais est d'ajouter n
(pour "suivant") à la .version
chaîne (plusieurs branches provenant de la même racine utiliseraient le même numéro temporaire .version
). Avant de libérer je décide quelles branches fusionner (avec un peu de chance toutes ayant le même .version
). Avant de procéder à la fusion, je mets à jour .version
vers le numéro suivant (mise à jour majeure ou mineure, selon les fonctionnalités fusionnées).
je suis d'accord avec ceux qui pensent que le remplacement de token appartient à construire des outils plutôt qu'à des outils de contrôle de version.
vous devriez avoir un outil de version automatisé pour définir les ID de version dans vos sources au moment où la version est étiquetée.
puisque vous utilisez Emacs, vous pourriez être chanceux:)
je suis tombé sur cette question par coïncidence, et aussi par coïncidence je suis venu par Lively il y a quelques jours, un paquet Emacs qui permet d'avoir des pièces animées D'Emacs Lisp dans votre document. Je ne l'ai pas essayé pour être honnête, mais ça m'est venu à l'esprit en lisant ceci.
je suis également venu de SCC, RCS, et CVS ( %W% %G% %U%
).
j'ai eu un défi similaire. Je voulais savoir quelle version d'un morceau de code était sur n'importe quel système l'exécutant. Le système peut ou non être connecté à un réseau. Le système peut ou non avoir installé Git. Le système peut ou non avoir installé le dépôt GitHub.
je voulais la même solution pour plusieurs types de code (.sh,.aller. ,yml,.xml, etc.). Je voulais n'importe qui sans connaissance de Git ou GitHub pour pouvoir répondre à la question " quelle version utilisez-vous?"
donc, j'ai écrit ce que j'appelle un wrapper autour de quelques commandes Git. Je l'utilise pour marquer un fichier avec un numéro de version et de l'information. Il résout mon défi. Il peut vous aider.
https://github.com/BradleyA/markit
git clone https://github.com/BradleyA/markit
cd markit
pour appliquer l'extension à tous les fichiers de tous les sous-répertoires du dépôt, ajoutez un fichier .gitattributes
au répertoire supérieur du dépôt (c'est-à-dire à l'endroit où vous mettriez normalement le fichier .gitignore
) contenant:
* ident
pour voir cela en vigueur, vous aurez besoin de faire un checkout efficace du(DES) fichier (s) d'abord, comme les supprimer ou les éditer de quelque manière que ce soit. Puis les restaurer avec:
git checkout .
et vous devriez voir $Id$
remplacé par quelque chose comme:
$Id: ea701b0bb744c90c620f315e2438bc6b764cdb87 $
de man gitattributes
:
ident
lorsque l'attribut ident est défini pour un chemin, git remplace $Id$ dans le objet blob avec $ Id:, suivi de l'objet hexadécimal blob de 40 caractères nom, suivi d'un signe de dollar $ à la caisse. Toute séquence d'octets qui commence avec $Id: et se termine avec $ dans le fichier worktree est remplacé par $Id$ à l'arrivée.
cette ID changera chaque fois qu'une nouvelle version du fichier est engagée.