Quel est l'équivalent Git pour le numéro de révision?

244

Nous utilisons SVN au travail, mais pour mes projets personnels, j'ai décidé d'utiliser Git. J'ai donc installé Git hier, et je me demande quel est le numéro de révision équivalent dans Git .

Disons que nous travaillons sur la version 3.0.8 et chaque correction de bogue a son propre numéro de révision que nous pouvons utiliser lorsque nous parlons de cette correction de bogue. Donc, si je marque le code dans Git en 3.0.8, que puis-je utiliser comme numéro de révision ou un autre type d'identification plus détaillé? Je trouve que le hachage n'est pas si convivial pour les humains.

Radek
la source
doublon possible de Comment obtenir le nombre de validations git?
Laurence Gonsalves
Il y a un article pour l'une des solutions possibles. Il pourrait sembler un peu lourd mais intégré à la sortie "git log" et ne nécessite aucune commande supplémentaire autre que "git push / pull / fetch".
Dmitry Pavlenko
Malheureusement, l'article lié de @DmitryPavlenko se trouve sur un domaine mort: gitsvn.x10.mx. Sans indication du sujet, il sera difficile pour quiconque de le trouver ailleurs.
Michael Donohue
Remarque: plus d'abréviation nécessaire avec git describe: voir stackoverflow.com/a/41308073/6309
VonC
1
Non, Laurence Gonsalves, ce n'est pas un doublon de "comment obtenir le nombre de commit git?" - il s'agit du numéro de version, et même si le nombre de validations peut sembler un peu différent - la version de hachage est très différente du nombre de validations :-)
David Svarrer

Réponses:

149

Bonne ou mauvaise nouvelle pour vous, ce hachage EST le numéro de révision. J'ai également eu des problèmes avec cela lorsque je suis passé de SVN à git.

Vous pouvez utiliser le «balisage» dans git pour baliser une certaine révision en tant que «version» pour une version spécifique, ce qui facilite la référence à cette révision. Consultez cet article de blog .

L'essentiel à comprendre est que git ne peut pas avoir de numéros de révision - pensez à la nature décentralisée. Si les utilisateurs A et B s'engagent tous les deux dans leurs référentiels locaux, comment git peut-il raisonnablement attribuer un numéro de révision séquentiel? A n'a aucune connaissance de B avant de pousser / tirer les changements de l'autre.

Une autre chose à regarder est la ramification simplifiée pour les branches de correction de bogues:

Commencez avec une version: 3.0.8. Ensuite, après cette version, procédez comme suit:

git branch bugfixes308

Cela va créer une branche pour les corrections de bugs. Commander la succursale:

git checkout bugfixes308

Maintenant, apportez les modifications de correction de bogue que vous souhaitez.

git commit -a

Validez-les et revenez à la branche principale:

git checkout master

Tirez ensuite ces changements de l'autre branche:

git merge bugfixes308

De cette façon, vous avez une branche de correctif de bogue spécifique à la version distincte, mais vous tirez toujours les modifications du correctif de bogue dans votre tronc de développement principal.

makdad
la source
11
J'ai compris que le hachage est le numéro de révision mais j'espérais que ce n'était pas :-))) merci pour la très belle explication et pour la suggestion maintenant de le traiter.
Radek
3
De rien. J'étais très frustré par git quand je l'ai récupéré chez SVN, mais maintenant je balance dans l'autre sens ...
makdad
4
ÉGALEMENT, cela fait un moment que je n'ai pas posté cela, mais rappelez-vous que vous pouvez également faire "git checkout -b new_branch_name" pour faire "git branch foo" et "git checkout foo" en une ligne.
makdad
1
Ai-je raison de dire que les hachages sont des "vrais" hachages, et même pas à distance séquentiels? Donc, surtout, si la base de données des bogues le dit fixed in 547cc3e..c4b2ebaet que vous avez une autre révision, vous ne savez pas si votre code est censé contenir le correctif?! Les gits de git-central ont sûrement une solution à cela?!?!
Olie
3
Dans SVN, le fait qu'un bogue soit corrigé dans r42 ne vous indique pas s'il est également corrigé dans r43 dès que vous utilisez des branches.
Matthieu Moy
186

Avec Git moderne (1.8.3.4 dans mon cas) et sans utiliser de branches, vous pouvez faire:

$ git rev-list --count HEAD
68
max
la source
22
Envisagez d'utilisergit rev-list --count --first-parent HEAD
Flimm
8
Compte tenu de ces informations (le nombre 68), existe-t-il un moyen de déterminer la révision pour la ré-acquisition du code? Supposons que la «révision 68» soit publiée dans un environnement de test, le développement continue et plus tard, un développeur doit réacquérir la «révision 68» à partir du contrôle de code source. Comment ciblerait-il la version spécifique à cloner? Ou est-ce que je manque quelque chose à propos de Git qui rend cela inutile?
David
9
Gardez à l'esprit que cette solution produirait des résultats différents pour différents développeurs. De plus, le calcul en arrière du "count" au commit donnerait des commits différents pour différents développeurs !! Cela est dû à la nature distribuée de Git et à ce que les commits se produisent dans différents référentiels au cours du même laps de temps mais peuvent ne pas être pris en compte en git rev-list --count HEADfonction du moment où les dernières poussées et tirages ont été effectuées.
Jason
2
@Jason, le commentaire de David sur l'ajout --first-parentrépond-il à votre préoccupation? Je détesterais éviter une solution apparemment plus simple en raison d'un cas de bord rare s'il existe une solution de contournement tout aussi simple ou un moyen de le rendre plus robuste.
MarkHu
4
@MarkHu, --first-parentaide. Tant qu'aucun rebasage n'est effectué et que la même branche est toujours utilisée pour faire des versions (et calculer ce numéro de version, bien sûr), je pense que cela pourrait être utilisé. Cependant, je ne suis toujours pas certain qu'il identifierait toujours de manière unique le commit dont la version est issue. Il y a tellement de choses qui peuvent mal tourner ici ... mais pour le moment je ne peux pas penser à quelque chose qui pourrait définitivement casser cela (étant donné mes déclarations ci-dessus "aussi longtemps que"). La git describeméthode mentionnée dans une autre réponse est la voie à suivre. Créez une balise si vous voulez quelque chose de lisible par l'homme.
Jason
104

La git describecommande crée un nom légèrement plus lisible par l'homme qui fait référence à une validation spécifique. Par exemple, à partir de la documentation:

Avec quelque chose comme l'arbre actuel de git.git, j'obtiens:

[torvalds@g5 git]$ git describe parent
v1.0.4-14-g2414721

c'est-à-dire que la tête actuelle de ma branche "parent" est basée sur la v1.0.4, mais comme elle a quelques validations en plus de cela, décrire a ajouté le nombre de validations supplémentaires ("14") et un nom d'objet abrégé pour la validation lui-même ("2414721") à la fin.

Tant que vous utilisez des balises judicieusement nommées pour baliser des versions particulières, cela peut être considéré à peu près comme un "numéro de révision" SVN.

Greg Hewgill
la source
7
Je voudrais juste noter que cela ne fonctionne que si votre gitréférentiel a déjà des balises; si ce n'est pas le cas, git describe échoue avec "fatal: aucun nom trouvé, ne peut rien décrire". - Débordement de pile ; ce qui signifie que vous devrez configurer vous-même les balises.
sdaau
14
@sdaau: Si vous l'utilisez dans un script ou quelque chose et que git describevous ne voulez jamais échouer, utilisez l' git describe --alwaysoption.
Greg Hewgill
La sortie de git describepeut -elle être utilisée pour trouver le commit source, d'une manière ou d'une autre? À moins de compter manuellement les commits dans le journal, je veux dire.
Lii
@Lii: Qu'entendez-vous par "source commit"? La balise la plus proche ( v1.0.4) et l'ID de validation le plus récent ( 2414721) font déjà partie de la sortie git describe.
Greg Hewgill
@GregHewgill: Oui, merci, quand j'ai posé la question, je ne savais pas que le "nom d'objet abrégé" est une valeur qui peut être utilisée pour identifier le commit. C'est brillant!
Lii
67

Les autres affiches ont raison, il n'y a pas de "numéro de révision".

Je pense que la meilleure façon est d'utiliser des balises pour les "versions"!

Mais j'ai utilisé les éléments suivants pour falsifier les numéros de révision (juste pour que les clients voient les révisions et les progrès, car ils voulaient avoir les mêmes révisions croissantes de git que lorsqu'elles étaient utilisées par subversion).

Afficher la "révision actuelle" de "HEAD" est simulée en utilisant ceci:

git rev-list HEAD | wc -l

Mais que faire si le client me dit qu'il y a un bug dans la "révision" 1302?

Pour cela, j'ai ajouté ce qui suit à la section [alias] de mon ~ / .gitconfig:

show-rev-number = !sh -c 'git rev-list --reverse HEAD | nl | awk \"{ if(\\$1 == "$0") { print \\$2 }}\"'

utilisant git show-rev-number 1302affichera alors le hachage pour la "révision" :)

J'ai fait un article de blog (en allemand) sur cette "technique" il y a quelque temps.

OderWat
la source
@Radek - "parfois besoin de savoir ce que 'code change = commit' a corrigé quelque chose" - alors git bisect(lien) est l'outil approprié pour identifier ce qui a changé quand et par qui.
michael
@Radek Oui, c'est un nombre toujours croissant. Il compte simplement les révisions que vous avez enregistrées sur la tête. Chaque commit est donc une nouvelle révision. Cela ne fonctionnera pas pour différentes branches.
OderWat
1
J'aime ta solution. Veuillez noter que vous pouvez le simplifier: show-rev-number =! Sh -c 'git rev-list --reverse HEAD | awk NR == $ 0 '
avner
@avner Merci! Je n'ai pas utilisé beaucoup de awk dans ma vie, évidemment :)
OderWat
3
Je devais utilisergit rev-list --reverse HEAD | awk "{ print NR }" | tail -n 1
Gerry
27

Git n'a pas le même concept de numéros de révision que subversion. Au lieu de cela, chaque instantané donné effectué avec une validation est marqué par une somme de contrôle SHA1. Pourquoi? Il y a plusieurs problèmes avec un revno en cours d'exécution dans un système de contrôle de version distribué:

Premièrement, comme le développement n'est pas linéaire du tout, l'attachement d'un nombre est plutôt difficile à résoudre d'une manière qui satisfera votre besoin en tant que programmeur. Essayer de résoudre ce problème en ajoutant un numéro peut rapidement devenir problématique lorsque le numéro ne se comporte pas comme prévu.

Deuxièmement, des numéros de révision peuvent être générés sur différentes machines. Cela rend la synchronisation des nombres beaucoup plus difficile - d'autant plus que la connectivité est unidirectionnelle; il se peut que vous n'ayez même pas accès à toutes les machines disposant du référentiel.

Troisièmement, dans git, quelque peu pionnier du système OpenCM aujourd'hui disparu, l' identité d'un commit (ce qu'est le commit) est équivalente à son nom (l'ID SHA). Ce concept de dénomination = identité est très fort. Lorsque vous vous asseyez avec un nom de validation à la main, il identifie également la validation d'une manière infalsifiable. À son tour, cela vous permet de vérifier toutes vos validations dans le premier initial pour la corruption avec la git fsckcommande.

Maintenant, comme nous avons un DAG (Directed Acyclic Graph) de révisions et que celles-ci constituent l'arborescence actuelle, nous avons besoin de quelques outils pour résoudre votre problème: Comment pouvons-nous distinguer les différentes versions. Tout d'abord, vous pouvez omettre une partie du hachage si un préfixe donné, par exemple 1516bd , identifie de manière unique votre commit. Mais c'est aussi assez artificiel. Au lieu de cela, l'astuce consiste à utiliser des balises et ou des branches. Une balise ou une branche s'apparente à une "note jaune" que vous attachez à un ID SHA1 de validation donné. Les balises sont, par essence, censées être immobiles alors qu'une branche se déplacera lorsque de nouveaux commits seront effectués sur sa HEAD. Il existe des moyens de faire référence à un commit autour d'une balise ou d'une branche, voir la page de manuel de git-rev-parse.

Habituellement, si vous devez travailler sur un morceau de code spécifique, ce morceau subit des modifications et devrait en tant que tel être une branche avec un nom de sujet disant. Créer beaucoup de branches (20-30 par programmeur n'est pas inconnu, avec environ 4-5 publiés pour que d'autres travaillent) est l'astuce pour un git efficace. Chaque travail doit commencer comme sa propre branche, puis être fusionné lorsqu'il est testé. Les branches non publiées peuvent être entièrement réécrites et cette partie de la destruction de l'histoire est une force de git.

Lorsque le changement est accepté en maître, il se fige quelque peu et devient archéologie. À ce stade, vous pouvez le marquer, mais le plus souvent, une référence au commit particulier est faite dans un suivi des bogues ou un suivi des problèmes via la somme sha1. Les balises sont généralement réservées aux sauts de version et aux points de branche pour les branches de maintenance (pour les anciennes versions).

JE DONNE DES RÉPONSES CRAP
la source
18

Si vous êtes intéressé, j'ai géré les numéros de version automatiquement depuis git infos ici sous le format

<major>.<minor>.<patch>-b<build>

où build est le nombre total de validations. Vous verrez le code intéressant dans le Makefile. Voici la partie pertinente pour accéder aux différentes parties du numéro de version:

LAST_TAG_COMMIT = $(shell git rev-list --tags --max-count=1)
LAST_TAG = $(shell git describe --tags $(LAST_TAG_COMMIT) )
TAG_PREFIX = "latex-tutorial-v"

VERSION  = $(shell head VERSION)
# OR try to guess directly from the last git tag
#VERSION    = $(shell  git describe --tags $(LAST_TAG_COMMIT) | sed "s/^$(TAG_PREFIX)//")
MAJOR      = $(shell echo $(VERSION) | sed "s/^\([0-9]*\).*/\1/")
MINOR      = $(shell echo $(VERSION) | sed "s/[0-9]*\.\([0-9]*\).*/\1/")
PATCH      = $(shell echo $(VERSION) | sed "s/[0-9]*\.[0-9]*\.\([0-9]*\).*/\1/")
# total number of commits       
BUILD      = $(shell git log --oneline | wc -l | sed -e "s/[ \t]*//g")

#REVISION   = $(shell git rev-list $(LAST_TAG).. --count)
#ROOTDIR    = $(shell git rev-parse --show-toplevel)
NEXT_MAJOR_VERSION = $(shell expr $(MAJOR) + 1).0.0-b$(BUILD)
NEXT_MINOR_VERSION = $(MAJOR).$(shell expr $(MINOR) + 1).0-b$(BUILD)
NEXT_PATCH_VERSION = $(MAJOR).$(MINOR).$(shell expr $(PATCH) + 1)-b$(BUILD)
Sébastien Varrette
la source
9

Une fonction Bash:

git_rev ()
{
    d=`date +%Y%m%d`
    c=`git rev-list --full-history --all --abbrev-commit | wc -l | sed -e 's/^ *//'`
    h=`git rev-list --full-history --all --abbrev-commit | head -1`
    echo ${c}:${h}:${d}
}

sort quelque chose comme

$ git_rev
2:0f8e14e:20130220

C'est

commit_count:last_abbrev_commit:date_YYmmdd
siznax
la source
Ce genre de chose pourrait être utile, mais si l'on s'intéresse aux numéros de version incrémentiels, ils permuteraient les positions de champ pour que le hachage (non incrémentiel) soit le dernier.
MarkHu
8

Le hachage SHA1 de la validation est l'équivalent d'un numéro de révision Subversion.

Richard Fearn
la source
7
Malheureusement, il a des propriétés très différentes d'un numéro de révision. C'est assez long et ça n'augmente pas de façon monotone. Je suppose que c'est le prix à payer pour la distribution ...
CodesInChaos
1
@CodeInChaos: Je sais où vous voulez en venir, mais il est généralement possible de se référer à git commits avec seulement les 6 ou 8 premiers caractères du code de hachage.
Chris Pitman
5
@Radek: Ils ne sont pas garantis uniques (bien que si vous trouvez une collision, vous pouvez gagner une petite quantité de célébrité).
Slartibartfast
8
@Radek Selon le en.wikipedia.org/wiki/Collision_attack , avec 4 caractères du hachage, vous avez un identifiant 16 bits, ce qui signifie que dans un dépôt avec 256 (= 2 ^ (16/2)), il y a un 50 % de chances que deux validations aient le même préfixe à quatre caractères (et avec 65536 validations, il est certain, car la plage d'ID à 4 caractères est épuisée). Lorsque vous ajoutez un caractère, vous avez un identifiant 20 bits, ce qui signifie que le seuil de 50% est à 1024 commits. Mais comme il s'agit d'un paramètre statistique, rien ne garantit que de telles collisions ne se produisent pas plus tôt.
Rudi
2
Étant donné que le hachage est basé sur le contenu, il est toujours probable que deux validations aient le même préfixe de hachage, pas une certitude. À 65536, il est très probable que deux aient le même préfixe à quatre caractères, mais ce n'est toujours pas certain. En passant, le hachage complet n'a pas encore de collision, mais git y travaille :) stackoverflow.com/questions/3475648/…
goodeye
6

C'est ce que j'ai fait dans mon makefile basé sur d'autres solutions. Remarque non seulement cela donne à votre code un numéro de révision, mais il ajoute également le hachage qui vous permet de recréer la version.

# Set the source control revision similar to subversion to use in 'c'
# files as a define.
# You must build in the master branch otherwise the build branch will
# be prepended to the revision and/or "dirty" appended. This is to
# clearly ID developer builds.
REPO_REVISION_:=$(shell git rev-list HEAD --count)
BUILD_BRANCH:=$(shell git rev-parse --abbrev-ref HEAD)
BUILD_REV_ID:=$(shell git rev-parse HEAD)
BUILD_REV_ID_SHORT:=$(shell git describe --long --tags --dirty --always)
ifeq ($(BUILD_BRANCH), master)
REPO_REVISION:=$(REPO_REVISION_)_g$(BUILD_REV_ID_SHORT)
else
REPO_REVISION:=$(BUILD_BRANCH)_$(REPO_REVISION_)_r$(BUILD_REV_ID_SHORT)
endif
export REPO_REVISION
export BUILD_BRANCH
export BUILD_REV_ID
Ralph Williamson
la source
3
Il semble que le moyen le plus sûr à utiliser git-describepour éviter les erreurs soit celui avec git describe --always --dirty --long --tagslequel je travaille dans tous les cas.
MarkHu
5

Le problème avec l'utilisation du hachage git comme numéro de build est qu'il n'augmente pas de façon monotone. OSGi suggère d'utiliser un horodatage pour le numéro de build. Il semble que le nombre de validations dans la branche puisse être utilisé à la place du numéro de subversion ou de changement forcé.

Jim Belton
la source
5

J'ai écrit quelques utilitaires PowerShell pour récupérer les informations de version de Git et simplifier le balisage

fonctions: Get-LastVersion, Get-Revision, Get-NextMajorVersion, Get-NextMinorVersion, TagNextMajorVersion, TagNextMinorVersion:

# Returns the last version by analysing existing tags,
# assumes an initial tag is present, and
# assumes tags are named v{major}.{minor}.[{revision}]
#
function Get-LastVersion(){
  $lastTagCommit = git rev-list --tags --max-count=1
  $lastTag = git describe --tags $lastTagCommit
  $tagPrefix = "v"
  $versionString = $lastTag -replace "$tagPrefix", ""
  Write-Host -NoNewline "last tagged commit "
  Write-Host -NoNewline -ForegroundColor "yellow" $lastTag
  Write-Host -NoNewline " revision "
  Write-Host -ForegroundColor "yellow" "$lastTagCommit"
  [reflection.assembly]::LoadWithPartialName("System.Version")

  $version = New-Object System.Version($versionString)
  return $version;
}

# Returns current revision by counting the number of commits to HEAD
function Get-Revision(){
   $lastTagCommit = git rev-list HEAD
   $revs  = git rev-list $lastTagCommit |  Measure-Object -Line
   return $revs.Lines
}

# Returns the next major version {major}.{minor}.{revision}
function Get-NextMajorVersion(){
    $version = Get-LastVersion;
    [reflection.assembly]::LoadWithPartialName("System.Version")
    [int] $major = $version.Major+1;
    $rev = Get-Revision
    $nextMajor = New-Object System.Version($major, 0, $rev);
    return $nextMajor;
}

# Returns the next minor version {major}.{minor}.{revision}
function Get-NextMinorVersion(){
    $version = Get-LastVersion;
    [reflection.assembly]::LoadWithPartialName("System.Version")
    [int] $minor = $version.Minor+1;
    $rev = Get-Revision
    $next = New-Object System.Version($version.Major, $minor, $rev);
    return $next;
}

# Creates a tag with the next minor version
function TagNextMinorVersion($tagMessage){
    $version = Get-NextMinorVersion;
    $tagName = "v{0}" -f "$version".Trim();
    Write-Host -NoNewline "Tagging next minor version to ";
    Write-Host -ForegroundColor DarkYellow "$tagName";
    git tag -a $tagName -m $tagMessage
}

# Creates a tag with the next major version (minor version starts again at 0)
function TagNextMajorVersion($tagMessage){
    $version = Get-NextMajorVersion;
    $tagName = "v{0}" -f "$version".Trim();
    Write-Host -NoNewline "Tagging next majo version to ";
    Write-Host -ForegroundColor DarkYellow "$tagName";
    git tag -a $tagName -m $tagMessage
}
toeb
la source
4

Chaque commit a un hachage unique. En dehors de cela, il n'y a pas de numéros de révision dans git. Vous devrez marquer vous-même les commits si vous voulez plus de convivialité.

Core Xii
la source
3

Je voudrais juste noter une autre approche possible - et c'est en utilisant git git-notes (1) , existant depuis la v 1.6.6 ( Note to Self - Git ) (j'utilise la gitversion 1.7.9.5).

Fondamentalement, j'avais l'habitude git svnde cloner un référentiel SVN avec un historique linéaire (pas de disposition standard, pas de branches, pas de balises), et je voulais comparer les numéros de révision dans le gitréférentiel cloné . Ce clone git n'a pas de balises par défaut, donc je ne peux pas l'utiliser git describe. La stratégie ici ne fonctionnerait probablement que pour l'histoire linéaire - je ne sais pas comment cela se passerait avec les fusions, etc .; mais voici la stratégie de base:

  • Demander la git rev-listliste de tous les historiques de commit
    • Puisqu'il rev-listest par défaut dans "l'ordre chronologique inverse", nous utiliserions son --reversecommutateur pour obtenir la liste des validations triées par les plus anciennes en premier
  • Utilisez bashshell pour
    • augmenter une variable de compteur à chaque validation comme compteur de révision,
    • générer et ajouter une note git "temporaire" pour chaque commit
  • Ensuite, parcourez le journal en utilisant git logavec --notes, qui videra également une note de commit, qui dans ce cas serait le "numéro de révision"
  • Une fois terminé, effacez les notes temporaires ( NB: je ne sais pas si ces notes sont validées ou non; elles n'apparaissent pas vraimentgit status )

Tout d'abord, notons qu'il gita un emplacement par défaut des notes - mais vous pouvez également spécifier une ref(érence) pour les notes - qui les stockerait dans un répertoire différent sous .git; par exemple, dans un gitdossier repo, vous pouvez appeler git notes get-refpour voir de quel répertoire il s'agit:

$ git notes get-ref
refs/notes/commits
$ git notes --ref=whatever get-ref
refs/notes/whatever

La chose à noter est que si vous avez notes addun --ref, vous devez également utiliser à nouveau cette référence - sinon vous pouvez obtenir des erreurs comme " Aucune note trouvée pour l'objet XXX ... ".

Pour cet exemple, j'ai choisi d'appeler la refnote "linrev" (pour la révision linéaire) - cela signifie également qu'il est peu probable que la procédure interfère avec les notes déjà existantes. J'utilise également le --git-dircommutateur, car étant un gitdébutant, j'ai eu quelques problèmes à le comprendre - je voudrais donc "me souvenir de plus tard" :); et j'utilise également --no-pagerpour supprimer le frai lesslors de l'utilisation git log.

Donc, en supposant que vous êtes dans un répertoire, avec un sous-dossier myrepo_gitqui est un gitréférentiel; on pourrait faire:

### check for already existing notes:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.

### iterate through rev-list three, oldest first,
### create a cmdline adding a revision count as note to each revision

$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
  TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
  TCMD="$TCMD add $ih -m \"(r$((++ix)))\""; \
  echo "$TCMD"; \
  eval "$TCMD"; \
done

# git --git-dir=./myrepo_git/.git notes --ref linrev add 6886bbb7be18e63fc4be68ba41917b48f02e09d7 -m "(r1)"
# git --git-dir=./myrepo_git/.git notes --ref linrev add f34910dbeeee33a40806d29dd956062d6ab3ad97 -m "(r2)"
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev add 04051f98ece25cff67e62d13c548dacbee6c1e33 -m "(r15)"

### check status - adding notes seem to not affect it:

$ cd myrepo_git/
$ git status
# # On branch master
# nothing to commit (working directory clean)
$ cd ../

### check notes again:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# (r15)

### note is saved - now let's issue a `git log` command, using a format string and notes:

$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)
# 77f3902: _user_: Sun Apr 21 18:29:00 2013 +0000:  >>test message 14<< (r14)
# ...
# 6886bbb: _user_: Sun Apr 21 17:11:52 2013 +0000:  >>initial test message 1<< (r1)

### test git log with range:

$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)

### erase notes - again must iterate through rev-list

$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
  TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
  TCMD="$TCMD remove $ih"; \
  echo "$TCMD"; \
  eval "$TCMD"; \
done
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# Removing note for object 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# git --git-dir=./myrepo_git/.git notes --ref linrev remove f34910dbeeee33a40806d29dd956062d6ab3ad97
# Removing note for object f34910dbeeee33a40806d29dd956062d6ab3ad97
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 04051f98ece25cff67e62d13c548dacbee6c1e33
# Removing note for object 04051f98ece25cff67e62d13c548dacbee6c1e33

### check notes again:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.

Donc, au moins dans mon cas spécifique d'historique entièrement linéaire sans branches, les numéros de révision semblent correspondre à cette approche - et en outre, il semble que cette approche permettra d'utiliser git logavec des plages de révision, tout en obtenant les bons numéros de révision - YMMV avec un contexte différent, cependant ...

J'espère que cela aide quelqu'un,
Cheers!


EDIT: Ok, ici c'est un peu plus facile, avec des gitalias pour les boucles ci-dessus, appelées setlinrevet unsetlinrev; lorsque dans votre dossier de dépôt git, faites ( Notez l' bashéchappement méchant , voir aussi # 16136745 - Ajoutez un alias Git contenant un point-virgule ):

cat >> .git/config <<"EOF"
[alias]
  setlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
      TCMD=\"git notes --ref linrev\"; \n\
      TCMD=\"$TCMD add $ih -m \\\"(r\\$((++ix)))\\\"\"; \n\
      #echo \"$TCMD\"; \n\
      eval \"$TCMD\"; \n\
    done; \n\
    echo \"Linear revision notes are set.\" '"

  unsetlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
      TCMD=\"git notes --ref linrev\"; \n\
      TCMD=\"$TCMD remove $ih\"; \n\
      #echo \"$TCMD\"; \n\
      eval \"$TCMD 2>/dev/null\"; \n\
    done; \n\
    echo \"Linear revision notes are unset.\" '"
EOF

... afin que vous puissiez simplement l'invoquer git setlinrevavant d'essayer de créer un journal impliquant des notes de révision linéaires; et git unsetlinrevpour supprimer ces notes lorsque vous avez terminé; un exemple à l'intérieur du répertoire git repo:

$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 <<

$ git setlinrev
Linear revision notes are set.
$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)
$ git unsetlinrev
Linear revision notes are unset.

$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 <<

Le temps qu'il faudrait au shell pour terminer ces alias dépendrait de la taille de l'historique du référentiel.

sdaau
la source
2

Pour les personnes qui ont un processus de génération Ant , vous pouvez générer un numéro de version pour un projet sur git avec cette cible:

<target name="generate-version">

    <exec executable="git" outputproperty="version.revisions">
        <arg value="log"/>
        <arg value="--oneline"/>
    </exec>

    <resourcecount property="version.revision" count="0" when="eq">
        <tokens>
            <concat>
                <filterchain>
                    <tokenfilter>
                        <stringtokenizer delims="\r" />
                    </tokenfilter>
                </filterchain>
            <propertyresource name="version.revisions" />
            </concat>
        </tokens>
    </resourcecount>
    <echo>Revision : ${version.revision}</echo>

    <exec executable="git" outputproperty="version.hash">
        <arg value="rev-parse"/>
        <arg value="--short"/>
        <arg value="HEAD"/>
    </exec>
    <echo>Hash : ${version.hash}</echo>


    <exec executable="git" outputproperty="version.branch">
        <arg value="rev-parse"/>
        <arg value="--abbrev-ref"/>
        <arg value="HEAD"/>
    </exec>
    <echo>Branch : ${version.branch}</echo>

    <exec executable="git" outputproperty="version.diff">
        <arg value="diff"/>
    </exec>

    <condition property="version.dirty" value="" else="-dirty">
        <equals arg1="${version.diff}" arg2=""/>
    </condition>

    <tstamp>
        <format property="version.date" pattern="yyyy-mm-dd.HH:mm:ss" locale="en,US"/>
    </tstamp>
    <echo>Date : ${version.date}</echo>

    <property name="version" value="${version.revision}.${version.hash}.${version.branch}${version.dirty}.${version.date}" />

    <echo>Version : ${version}</echo>

    <echo file="version.properties" append="false">version = ${version}</echo>

</target>

Le résultat ressemble à ceci:

generate-version:
    [echo] Generate version
    [echo] Revision : 47
    [echo] Hash : 2af0b99
    [echo] Branch : master
    [echo] Date : 2015-04-20.15:04:03
    [echo] Version : 47.2af0b99.master-dirty.2015-04-20.15:04:03

Le drapeau sale est là lorsque vous avez des fichiers non validés lorsque vous générez le numéro de version. Parce que généralement, lorsque vous créez / empaquetez votre application, chaque modification de code doit être dans le référentiel.

Fredo
la source
1

Avec l'id SHA-1 du commit, la date et l'heure de l'heure du serveur auraient aidé?

Quelque chose comme ça:

le commit a eu lieu à 11h30:25 le 19 août 2013 montrerait que 6886bbb7be18e63fc4be68ba41917b48f02e09d7_19aug2013_113025

Manoranjan Sahu
la source
1

Dans le manuel Git, les balises sont une réponse brillante à ce problème:

La création d'une balise annotée dans Git est simple. La manière la plus simple consiste à spécifier -a lorsque vous exécutez la commande tag:

$ git tag -a v1.4 -m 'my version 1.4'

$ git tag
v0.1
v1.3
v1.4

Découvrez 2.6 Git Basics - Tagging

DJ Far
la source
Dommage que vous deviez sauter à travers des cerceaux pour changer les valeurs par défaut:By default, the git push command doesn’t transfer tags to remote servers.
MarkHu
1

Nous utilisons cette commande pour obtenir la version et la révision de git:

git describe --always --tags --dirty

Il revient

  • valider le hachage comme révision lorsqu'aucun marquage n'est utilisé (par exemple gcc7b71f)
  • nom de la balise comme version lorsqu'elle est sur une balise (par exemple v2.1.0, utilisée pour les versions)
  • nom de la balise, numéro de révision depuis la dernière balise et validation du hachage après une balise (par ex. v5.3.0-88-gcc7b71f )
  • comme ci-dessus plus une balise "sale" si l'arbre de travail a des modifications locales (par exemple v5.3.0-88-gcc7b71f-dirty)

Voir également: https://www.git-scm.com/docs/git-describe#Documentation/git-describe.txt

thisismydesign
la source
0

Événement post-génération pour Visual Studio

echo  >RevisionNumber.cs static class Git { public static int RevisionNumber =
git  >>RevisionNumber.cs rev-list --count HEAD
echo >>RevisionNumber.cs ; }
Polluks
la source
-1

Pensez à utiliser

git-rev-label

Donne des informations sur la révision du référentiel Git au format comme master-c73-gabc6bec. Peut remplir une chaîne de modèle ou un fichier avec des variables d'environnement et des informations de Git. Utile pour fournir des informations sur la version du programme: branche, tag, hachage de validation, nombre de validations, statut incorrect, date et heure. L'une des choses les plus utiles est le nombre de validations, sans tenir compte des branches fusionnées - uniquement le premier parent.

kyb
la source