Jaki jest odpowiednik Git dla numeru wersji?


244

Używamy SVN w pracy, ale do moich osobistych projektów zdecydowałem się użyć Git. Więc zainstalowałem Git wczoraj i zastanawiam się, jaki jest odpowiednik numeru wersji w Git .

Załóżmy, że pracujemy nad wersją 3.0.8, a każda poprawka błędu ma swój własny numer wersji, którego możemy użyć, gdy mówimy o tej poprawce. Więc jeśli otaguję kod w Git do 3.0.8, co wtedy mogę użyć jako numeru wersji lub innego bardziej szczegółowego rodzaju identyfikacji? Uważam, że skrót nie jest tak przyjazny dla ludzi.



Jest artykuł na temat jednego z możliwych rozwiązań. Może wyglądać nieco ciężko, ale jest zintegrowany z wyjściem „git log” i nie wymaga żadnych dodatkowych poleceń poza „git push / pull / fetch”.
Dmitry Pavlenko

Niestety link do artykułu z @DmitryPavlenko znajduje się w martwej domenie: gitsvn.x10.mx. Bez wskazania tematu nikomu trudno będzie go znaleźć w innym miejscu.
Michael Donohue

Uwaga: nie trzeba już używać skrótu w git opisz: patrz stackoverflow.com/a/41308073/6309
VonC

1
Nie, Laurence Gonsalves, to nie jest duplikat „jak uzyskać liczbę zatwierdzeń git?” - chodzi o numer wersji i chociaż liczba zatwierdzeń może być nieco zmieniona, aby wyglądać trochę podobnie - wersja skrótu różni się znacznie od liczby zatwierdzeń :-)
David Svarrer

Odpowiedzi:


149

Dobra lub zła wiadomość dla Ciebie, że skrót to numer wersji. Miałem też z tym problem, kiedy przestawiłem się z SVN na git.

Możesz użyć „tagowania” w git, aby oznaczyć określoną wersję jako „wydanie” dla konkretnej wersji, dzięki czemu można łatwo odnieść się do tej wersji. Sprawdź ten post na blogu .

Kluczową rzeczą do zrozumienia jest to, że git nie może mieć numerów wersji - pomyśl o zdecentralizowanej naturze. Jeśli użytkownicy A i B zobowiązują się do swoich lokalnych repozytoriów, w jaki sposób git może rozsądnie przypisać sekwencyjny numer rewizji? A nie ma wiedzy o B, zanim nie popchną / nie pociągną za siebie zmian.

Inną rzeczą, na którą warto zwrócić uwagę, jest uproszczone rozgałęzianie gałęzi z poprawkami:

Zacznij od wydania: 3.0.8. Następnie po wydaniu wykonaj następujące czynności:

git branch bugfixes308

Spowoduje to utworzenie gałęzi dla poprawek błędów. Kasa w oddziale:

git checkout bugfixes308

Teraz wprowadź zmiany, które chcesz naprawić.

git commit -a

Zatwierdź je i wróć do głównej gałęzi:

git checkout master

Następnie pobierz te zmiany z drugiej gałęzi:

git merge bugfixes308

W ten sposób masz osobną gałąź poprawek błędów dla poszczególnych wydań, ale wciąż przenosisz zmiany do głównego pnia programistów.


11
Zrozumiałem, że skrót jest numerem wersji, ale miałem nadzieję, że tak nie było :-))) Dziękuję za bardzo miłe wyjaśnienie i sugestię, jak sobie z tym poradzić.
Radek,

3
Nie ma za co. Byłem bardzo sfrustrowany gitem, kiedy po raz pierwszy go
odebrałem

4
TAKŻE minęło trochę czasu, odkąd to opublikowałem, ale pamiętaj, że możesz także zrobić „git checkout -b nowa_nazwa_gałęzi”, aby zrobić „git branch foo” i „git checkout foo” jako jedno-liniowy.
makdad

1
Czy mam rację, że skróty to „prawdziwe” skróty, a nawet nie są sekwencyjne? Co ważne, jeśli baza błędów zawiera informację fixed in 547cc3e..c4b2eba, a masz inną wersję, nie masz pojęcia, czy Twój kod powinien zawierać poprawkę ?! Z pewnością gity w git-central mają na to rozwiązanie?!?!
Olie

3
W SVN fakt, że błąd został naprawiony w r42, nie mówi ci o tym, czy został naprawiony również w r43, gdy tylko faktycznie użyjesz rozgałęzień.
Matthieu Moy,

186

Dzięki nowoczesnemu Gitowi (w moim przypadku 1.8.3.4) i nie używaniu gałęzi możesz:

$ git rev-list --count HEAD
68

22
Rozważ użyciegit rev-list --count --first-parent HEAD
Flimm

8
Biorąc pod uwagę te informacje (liczba 68), czy istnieje sposób na określenie wersji ponownego uzyskania kodu? Załóżmy, że „wersja 68” została wydana w środowisku testowym, rozwój jest kontynuowany, a później programista musi ponownie uzyskać „wersję 68” z kontroli źródła. Jak skierowałby konkretną wersję do sklonowania? A może brakuje mi czegoś w Git, co sprawia, że ​​jest to niepotrzebne?
David

9
Należy pamiętać, że to rozwiązanie przyniosłoby różne wyniki dla różnych programistów. Również obliczenie wstecz od „count” do zatwierdzenia dałoby różne zatwierdzenia dla różnych programistów !! Wynika to z rozproszonej natury Git i że zatwierdzenia zachodzą w różnych repozytoriach w tym samym kawałku czasu, ale mogą nie być liczone w git rev-list --count HEADzależności od tego, kiedy zostały wykonane ostatnie pushy i pully.
Jason

2
@Jason, czy komentarz Davida dotyczący dodania --first-parentdotyczy twojego problemu? Nie chciałbym unikać pozornie najprostszego rozwiązania ze względu na rzadki przypadek, jeśli istnieje równie proste obejście lub sposób, aby uczynić go bardziej niezawodnym.
MarkHu

4
@MarkHu, --first-parentpomaga. Tak długo, jak nie dokonuje się zmiany baz, a ta sama gałąź jest zawsze używana do tworzenia wydań (i obliczania tego numeru wydania, oczywiście), myślę, że można to wykorzystać. Mimo to wciąż nie jestem pewien, czy zawsze jednoznacznie identyfikuje zatwierdzenie, z którego pochodzi wydanie. Jest tak wiele rzeczy, które mogą pójść nie tak ... ale w tej chwili nie mogę wymyślić czegoś, co na pewno by to zepsuło (biorąc pod uwagę moje powyższe „tak długo jak” stwierdzenia). git describeMetoda wspomniano w innym odpowiedź jest droga. Utwórz tag, jeśli chcesz coś czytelnego dla człowieka.
Jason

104

git describePolecenie tworzy nieco bardziej czytelnej nazwę, która odnosi się do konkretnego popełnił. Na przykład z dokumentacji:

Z czymś takim jak obecne drzewo git.git, otrzymuję:

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

tzn. obecny szef mojej gałęzi „nadrzędnej” jest oparty na wersji 1.0.4, ale ponieważ zawiera kilka zatwierdzeń, opis dodał liczbę dodatkowych zatwierdzeń („14”) i skróconą nazwę obiektu dla zatwierdzenia na końcu („2414721”).

Dopóki używasz rozsądnie nazwanych tagów do oznaczania poszczególnych wydań, można to uznać za w przybliżeniu równoważne „numerowi wersji” SVN.


7
Chciałbym tylko zauważyć, że działa to tylko wtedy, gdy twoje gitrepozytorium ma już tagi; jeśli nie, może się zdarzyć, że git description zakończy się niepowodzeniem słowem „fatal: Nie znaleziono nazw, nic nie można opisać”. - Przepełnienie stosu ; co oznacza, że ​​musisz sam skonfigurować tagi.
sdaau

14
@sdaau: Jeśli używasz tego w skrypcie lub coś i chcesz git describenigdy nie zawieść, skorzystaj z git describe --alwaysopcji.
Greg Hewgill

Czy wyjście może git describebyć użyte do znalezienia zatwierdzenia źródła? Mam na myśli brak ręcznego liczenia zatwierdzeń w dzienniku.
Lii

@Lii: Co rozumiesz przez „zatwierdzanie źródła”? Zarówno najbliższy tag ( v1.0.4), jak i najnowszy commit id ( 2414721) są już częścią danych wyjściowych git description.
Greg Hewgill

@GregHewgill: Tak, dziękuję, kiedy zadałem pytanie, nie zdawałem sobie sprawy, że „skrócona nazwa obiektu” jest wartością, której można użyć do identyfikacji zatwierdzenia. To wspaniale!
Lii

67

Inne plakaty mają rację, nie ma „numeru wersji”.

Myślę, że najlepszym sposobem jest użycie tagów do „wydań”!

Ale skorzystałem z poniższych do fałszywych numerów wersji (tylko dla klientów, aby zobaczyć wersje i postęp, ponieważ chcieli mieć takie same rosnące wersje z git, jak oni używali przez subversion).

Pokaż, że „bieżąca wersja” HEAD jest symulowana przy użyciu:

git rev-list HEAD | wc -l

Ale co, jeśli klient powie mi, że w „wersji” 1302 występuje błąd?

W tym celu do sekcji [alias] mojego ~ / .gitconfig dodałem:

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

użycie git show-rev-number 1302spowoduje wydrukowanie skrótu dla „wersji” :)

Jakiś czas temu napisałem post na blogu (w języku niemieckim) na temat tej „techniki”.


@Radek - „czasami trzeba wiedzieć, co„ zmiana kodu = zatwierdzenie ”naprawiło coś” - wtedy git bisect(link) jest odpowiednim narzędziem do identyfikacji tego, co się zmieniło przez kogo.
michael

@Radek Tak, to ciągle rosnąca liczba. Liczy tylko te wersje, które zameldowałeś na HEAD. Więc każde zatwierdzenie jest nową wersją. To nie zadziała dla różnych gałęzi.
OderWat

1
Podoba mi się twoje rozwiązanie. Zauważ, że możesz to uprościć: show-rev-number =! Sh -c 'git rev-list --reverse HEAD | awk NR == 0 $
avner

@avner Dziękujemy! Oczywiście nie
użyłem

3
Musiałem użyćgit rev-list --reverse HEAD | awk "{ print NR }" | tail -n 1
Gerry

27

Git nie ma tej samej koncepcji numerów wersji jak subversion. Zamiast tego każda podana migawka wykonana z zatwierdzeniem jest oznaczona sumą kontrolną SHA1. Czemu? Istnieje kilka problemów z działającym revno w rozproszonym systemie kontroli wersji:

Po pierwsze, ponieważ rozwój nie jest w ogóle liniowy, dołączenie liczby jest raczej trudne jako problem do rozwiązania w sposób, który zaspokoi twoją potrzebę jako programisty. Próba naprawienia tego przez dodanie numeru może szybko stać się problematyczna, gdy liczba nie będzie działać zgodnie z oczekiwaniami.

Po drugie, numery wersji mogą być generowane na różnych komputerach. To znacznie utrudnia synchronizację liczb - zwłaszcza, że ​​łączność jest jednokierunkowa; możesz nawet nie mieć dostępu do wszystkich komputerów, które mają repozytorium.

Po trzecie, w git, nieco zapoczątkowany przez nieistniejący już system OpenCM, tożsamość zatwierdzenia (czym jest zatwierdzenie) jest równoważna jego nazwie (identyfikator SHA). Ta koncepcja nazewnictwa = tożsamości jest bardzo silna. Kiedy siedzisz z nazwą zatwierdzenia w dłoni, identyfikuje ona także zatwierdzenie w sposób niewybaczalny. To z kolei pozwala sprawdzić wszystkie swoje zobowiązania z powrotem do pierwszego początkowego pod kątem uszkodzenia za pomocą git fsckpolecenia.

Teraz, ponieważ mamy DAG (Directed Acyclic Graph) wersji, które stanowią obecne drzewo, potrzebujemy narzędzi do rozwiązania twojego problemu: Jak rozróżnić różne wersje. Po pierwsze, możesz pominąć część skrótu, jeśli dany prefiks, powiedzmy 1516bd , jednoznacznie identyfikuje twoje zatwierdzenie. Ale jest to również wymyślone. Zamiast tego sztuczka polega na użyciu tagów i / lub gałęzi. Znacznik lub gałąź przypomina „żółtą karteczkę, którą dołączasz” do danego zatwierdzenia SHA1-id. Tagi są w zasadzie nieruchome, podczas gdy gałąź będzie się poruszać, gdy zostaną wprowadzone nowe zatwierdzenia do jej HEAD. Istnieją sposoby odwoływania się do zatwierdzenia wokół tagu lub gałęzi, zobacz stronę man git-rev-parse.

Zwykle, jeśli musisz pracować nad konkretnym fragmentem kodu, ten fragment podlega zmianom i jako taki powinien być gałęzią o mówiącej nazwie tematu. Tworzenie wielu gałęzi (20-30 na programistę nie jest niespotykane, z niektórymi 4-5 opublikowanymi dla innych do pracy) jest sztuczką dla skutecznego git. Każda praca powinna rozpocząć się jako osobna gałąź, a następnie zostać scalona podczas testowania. Niepublikowane gałęzie można całkowicie przepisać, a ta część niszczenia historii jest siłą rażenia.

Kiedy zmiana zostanie zaakceptowana jako master , nieco się zawiesza i staje się archeologią. W tym momencie możesz go oznaczyć, ale częściej w śledzeniu błędów lub śledzeniu błędów pojawia się odniesienie do konkretnego zatwierdzenia za pomocą sumy sha1. Tagi są zwykle zarezerwowane dla wypukłości wersji i punktów rozgałęzień dla gałęzi konserwacji (dla starszych wersji).


18

Jeśli jesteś zainteresowany, automatycznie zarządzałem numerami wersji z informacji git tutaj w formacie

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

gdzie build to całkowita liczba zatwierdzeń. Zobaczysz ciekawy kod w Makefile. Oto odpowiednia część umożliwiająca dostęp do innej części numeru wersji:

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)

9

Funkcja 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}
}

wypisuje coś podobnego

$ git_rev
2:0f8e14e:20130220

To jest

commit_count:last_abbrev_commit:date_YYmmdd

Tego rodzaju rzeczy mogą być przydatne, ale jeśli ktoś jest zainteresowany przyrostowymi numerami wersji, zamieniają pozycje pola, aby hash (nie przyrostowy) był ostatni.
MarkHu,

8

Hash SHA1 z popełnić jest odpowiednikiem numeru wersji Subversion.


7
Niestety ma zupełnie inne właściwości niż numer wersji. Jest raczej długi i nie rośnie monotonnie. To chyba cena za dystrybucję ...
CodesInChaos,

1
@CodeInChaos: Wiem, do czego zmierzasz, ale generalnie możliwe jest odwołanie się do git commits tylko z pierwszymi 6 lub 8 znakami kodu skrótu.
Chris Pitman,

5
@Radek: Nie są gwarantowane, że są wyjątkowe (chociaż jeśli znajdziesz kolizję, możesz wygrać niewielką ilość celebrytów).
Slartibartfast

8
@Radek Według en.wikipedia.org/wiki/Collision_attack , z 4 znakami skrótu masz 16-bitowy identyfikator, co oznacza, że ​​w repozytorium z 256 (= 2 ^ (16/2)) zobowiązaniami jest 50 % szansy, że dwa zatwierdzenia mają ten sam przedrostek czterech znaków (i przy 65536 zatwierdzeń jest pewne, od tego czasu zakres identyfikatorów 4 znaków jest wyczerpany). Kiedy dodajesz jeden znak, masz 20-bitowy identyfikator, co oznacza, że ​​próg 50% wynosi 1024 zatwierdzenia. Ale ponieważ jest to parametr statystyczny, nic nie gwarantuje, że takie kolizje nie zdarzają się wcześniej.
Rudi

2
Ponieważ skrót jest oparty na zawartości, nadal istnieje prawdopodobieństwo, że dwa zatwierdzenia mają ten sam prefiks skrótu, a nie pewność. Przy 65536 zatwierdzeń jest bardzo prawdopodobne, że dwa będą miały ten sam przedrostek czterech znaków, ale nadal nie jest pewne.
Nawiasem mówiąc

6

Tak zrobiłem w moim makefile opartym na innych rozwiązaniach. Uwaga: kod ten nie tylko nadaje kodowi numer wersji, ale także dodaje skrót, który pozwala odtworzyć wydanie.

# 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

3
Wydaje się najbezpieczniejszym sposobem na git-describeuniknięcie błędów, z git describe --always --dirty --long --tagsktórym działa we wszystkich przypadkach, o których myślę.
MarkHu

5

Problem z używaniem skrótu git jako numeru kompilacji polega na tym, że nie rośnie monotonicznie. OSGi sugeruje użycie znacznika czasu dla numeru kompilacji. Wygląda na to, że zamiast zatwierdzenia zmiany lub zmiany perforacji można użyć liczby zatwierdzeń do gałęzi.


5

Napisałem kilka narzędzi PowerShell do pobierania informacji o wersji z Git i uproszczenia tagowania

funkcje: 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
}

4

Każde zatwierdzenie ma unikatowy skrót. Poza tym w git nie ma numerów wersji. Będziesz musiał tagować zobowiązania, jeśli chcesz bardziej przyjazny dla użytkownika.


3

Chciałbym tylko zwrócić uwagę na inne możliwe podejście - i to za pomocą git git-notes (1) , istniejącego od wersji 1.6.6 ( Note to Self - Git ) (używam gitwersji 1.7.9.5).

Zasadniczo git svnklonowałem repozytorium SVN z historią liniową (bez standardowego układu, bez rozgałęzień, bez tagów) i chciałem porównać numery wersji w sklonowanym gitrepozytorium. Ten klon git nie ma domyślnie tagów, więc nie mogę go użyć git describe. Strategia tutaj prawdopodobnie działałaby tylko dla historii liniowej - nie jestem pewien, jak to się skończy z fuzjami itp .; ale oto podstawowa strategia:

  • Zapytaj git rev-listo listę wszystkich historii zatwierdzeń
    • Ponieważ rev-listdomyślnie jest w „odwrotnym porządku chronologicznym”, użyjemy jego --reverseprzełącznika, aby uzyskać listę zatwierdzeń posortowanych według najstarszych
  • Użyj bashpowłoki do
    • zwiększyć zmienną licznika przy każdym zatwierdzeniu jako licznik zmian,
    • wygeneruj i dodaj „tymczasową” notatkę git dla każdego zatwierdzenia
  • Następnie przejrzyj dziennik za pomocą git logprzy pomocy --notes, co spowoduje również zrzucenie notatki zatwierdzenia, która w tym przypadku byłaby „numerem wersji”
  • Po zakończeniu usuń tymczasowe notatki ( NB: Nie jestem pewien, czy te notatki sągit status zatwierdzone, czy nie; tak naprawdę nie pojawiają się )

Po pierwsze, zwróćmy uwagę, że gitma domyślną lokalizację notatek - ale możesz także określić ref(erence) dla notatek - która zapisałaby je w innym katalogu .git; na przykład, gdy jesteś w gitfolderze repo, możesz zadzwonić, git notes get-refaby zobaczyć, jaki to będzie katalog:

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

Należy zauważyć, że jeśli używasz notes addznaku a --ref, musisz także użyć tego odwołania ponownie - w przeciwnym razie mogą pojawić się błędy typu „ Nie znaleziono notatki dla obiektu XXX ... ”.

W tym przykładzie zdecydowałem się nazwać refnotatkę „linrev” (dla wersji liniowej) - oznacza to również, że jest mało prawdopodobne, że procedura będzie kolidować z już istniejącymi nutami. Używam również --git-dirprzełącznika, ponieważ będąc gitnowicjuszem miałem problemy z jego zrozumieniem - dlatego chciałbym „zapamiętać na później” :); i używam również --no-pagerdo tłumienia pojawiania się lesspodczas używania git log.

Zakładając, że jesteś w katalogu z podfolderem, myrepo_gitktóry jest gitrepozytorium; można zrobić:

### 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.

Tak więc, przynajmniej w moim konkretnym przypadku w pełni liniowej historii bez rozgałęzień, numery wersji wydają się pasować do tego podejścia - i dodatkowo wydaje się, że to podejście pozwoli na użycie git logz zakresami wersji, przy jednoczesnym uzyskaniu odpowiednich numerów wersji - YMMV jednak w innym kontekście ...

Mam nadzieję, że to komuś pomoże,
zdrowie!


EDYCJA: Ok, tutaj jest trochę łatwiej, z gitaliasami dla powyższych pętli, nazwanymi setlinrevi unsetlinrev; znajdując się w folderze repozytorium git, wykonaj następujące czynności ( zwróć uwagę na paskudną bashucieczkę, zobacz także # 16136745 - Dodaj alias Git zawierający średnik ):

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

... więc możesz po prostu wywołać git setlinrevprzed próbą wykonania dziennika zawierającego liniowe notatki z rewizji; i git unsetlinrevaby usunąć te notatki, gdy skończysz; przykład z katalogu 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 <<

Czas potrzebny powłoce na uzupełnienie tych aliasów będzie zależał od wielkości historii repozytorium.


2

Dla osób, które mają proces kompilacji Ant , możesz wygenerować numer wersji projektu na git z tym celem:

<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>

Wynik wygląda następująco:

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

Flaga „brudna” pojawia się, gdy pliki nie są zatwierdzone podczas generowania numeru wersji. Ponieważ zwykle podczas budowania / pakowania aplikacji każda modyfikacja kodu musi znajdować się w repozytorium.


1

Oprócz identyfikatora zatwierdzenia SHA-1, data i godzina czasu serwera pomogłyby?

Coś takiego:

zatwierdzenie stało się o 11:30:25 19 sierpnia 2013 r. pokazałoby się jako 6886bbb7be18e63fc4be68ba41917b48f02e09d7_19aug2013_113025


1

W podręczniku Git tagi są świetną odpowiedzią na ten problem:

Tworzenie tagów z adnotacjami w Git jest proste. Najprostszym sposobem jest podanie opcji -a po uruchomieniu polecenia tag:

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

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

Sprawdź 2.6 Podstawy Git - Tagowanie


Szkoda, że ​​musisz skakać przez obręcze, aby zmienić wartości domyślne:By default, the git push command doesn’t transfer tags to remote servers.
MarkHu

1

Używamy tego polecenia, aby pobrać wersję i wersję z git:

git describe --always --tags --dirty

Powraca

  • Zatwierdź skrót jako wersję, gdy nie jest używane tagowanie (np. gcc7b71f)
  • nazwa znacznika jako wersja na znaczniku (np. v2.1.0używana w wydaniach)
  • nazwa znacznika, numer rewizji od ostatniego znacznika i zatwierdzenie skrótu po znaczniku (np. v5.3.0-88-gcc7b71f)
  • to samo co powyżej plus „brudny” tag, jeśli działające drzewo ma lokalne modyfikacje (np. v5.3.0-88-gcc7b71f-dirty)

Zobacz także: https://www.git-scm.com/docs/git-describe#Documentation/git-describe.txt


0

Zdarzenie po kompilacji dla programu Visual Studio

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

-1

Rozważ użycie

git-rev-label

Podaje informacje o rewizji repozytorium Git w formacie podobnym do master-c73-gabc6bec. Może wypełnić ciąg szablonu lub plik zmiennymi środowiskowymi i informacjami z Git. Przydatne do dostarczenia informacji o wersji programu: gałąź, znacznik, hash zatwierdzenia, liczba zatwierdzeń, status „brudny”, data i godzina. Jedną z najbardziej przydatnych rzeczy jest liczba zatwierdzeń, nie biorąc pod uwagę połączonych gałęzi - tylko pierwszego rodzica.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.