Apa yang setara dengan Git untuk nomor revisi?

244

Kami menggunakan SVN di tempat kerja, tetapi untuk proyek pribadi saya, saya memutuskan untuk menggunakan Git. Jadi saya menginstal Git kemarin, dan saya ingin tahu apa yang setara dengan angka revisi di Git .

Katakanlah kita bekerja pada versi 3.0.8 dan setiap perbaikan bug memiliki nomor revisi sendiri yang dapat kita gunakan ketika kita berbicara tentang perbaikan bug ini. Jadi jika saya memberi tag kode di Git ke 3.0.8 lalu apa yang bisa saya gunakan sebagai nomor revisi atau jenis identifikasi yang lebih rinci? Saya menemukan hash tidak begitu ramah pengguna untuk manusia.

Radek
sumber
duplikat yang mungkin dari Bagaimana cara mendapatkan git commit count?
Laurence Gonsalves
Ada artikel untuk salah satu solusi yang mungkin. Itu bisa terlihat agak berat tetapi terintegrasi ke dalam "git log" output dan tidak memerlukan perintah tambahan selain "git push / pull / fetch".
Dmitry Pavlenko
Sayangnya artikel yang ditautkan dari @DmitryPavlenko berada pada domain mati: gitsvn.x10.mx. Tanpa indikasi subjek, akan sulit bagi siapa pun untuk menemukannya di tempat lain.
Michael Donohue
Catatan: tidak diperlukan singkatan dengan git menjelaskan: lihat stackoverflow.com/a/41308073/6309
VonC
1
Tidak, Laurence Gonsalves, ini bukan duplikat dari "bagaimana cara mendapatkan git commit count?" - Ini tentang nomor versi, dan meskipun jumlah komit dapat
diputar-putar

Jawaban:

149

Kabar baik atau buruk untuk Anda, hash ADALAH nomor revisi. Saya juga mengalami masalah dengan ini ketika saya beralih dari SVN ke git.

Anda dapat menggunakan "pemberian tag" di git untuk menandai revisi tertentu sebagai "rilis" untuk versi tertentu, membuatnya mudah untuk merujuk pada revisi itu. Lihat posting blog ini .

Hal utama yang harus dipahami adalah git tidak dapat memiliki angka revisi - pikirkan tentang sifat desentralisasi. Jika pengguna A dan B keduanya berkomitmen untuk repositori lokal mereka, bagaimana bisa git secara wajar menetapkan nomor revisi berurutan? A tidak memiliki pengetahuan tentang B sebelum mereka mendorong / menarik perubahan satu sama lain.

Hal lain yang perlu dilihat adalah percabangan disederhanakan untuk cabang bugfix:

Mulai dengan rilis: 3.0.8. Kemudian, setelah rilis itu, lakukan ini:

git branch bugfixes308

Ini akan membuat cabang untuk perbaikan bug. Periksa cabang:

git checkout bugfixes308

Sekarang buat perubahan bug apa pun yang Anda inginkan.

git commit -a

Komit mereka, dan kembali ke cabang utama:

git checkout master

Kemudian tarik perubahan-perubahan itu dari cabang lain:

git merge bugfixes308

Dengan begitu, Anda memiliki cabang bugfix khusus rilis terpisah, tetapi Anda masih menarik perubahan bugfix ke trunk dev utama Anda.

makdad
sumber
11
Saya mengerti bahwa hash adalah angka revisi tetapi saya berharap bukan :-))) terima kasih atas penjelasan yang sangat bagus dan atas saran sekarang untuk menghadapinya.
Radek
3
Sama-sama. Saya sangat frustrasi dengan git ketika saya pertama kali mengambilnya dari SVN, tapi sekarang saya mengayunkannya ke arah lain ...
makdad
4
JUGA, sudah beberapa saat sejak saya memposting ini, tetapi ingat bahwa Anda juga dapat melakukan "git checkout -b new_branch_name" untuk melakukan "git branch foo" dan "git checkout foo" sebagai one-liner.
makdad
1
Apakah saya benar bahwa hash adalah hash "benar", dan bahkan tidak berurutan? Jadi, yang penting, jika database bug mengatakan fixed in 547cc3e..c4b2eba, dan Anda memiliki beberapa revisi lain, Anda tidak tahu apakah kode Anda seharusnya berisi perbaikan ?! Tentunya para git di git-central punya solusi untuk ini?!?!
Olie
3
Di SVN, fakta bahwa bug diperbaiki di r42 tidak memberi tahu Anda apakah bug itu juga diperbaiki di r43 segera setelah Anda menggunakan cabang sebenarnya.
Matthieu Moy
186

Dengan Git modern (1.8.3.4 dalam kasus saya) dan tidak menggunakan cabang, Anda dapat melakukannya:

$ git rev-list --count HEAD
68
maks
sumber
22
Pertimbangkan untuk menggunakangit rev-list --count --first-parent HEAD
Flimm
8
Dengan informasi ini (nomor 68), apakah ada cara untuk menentukan revisi untuk memperoleh kembali kode? Misalkan "revisi 68" dilepaskan ke lingkungan pengujian, pengembangan berlanjut, dan kemudian pengembang perlu memperoleh kembali "revisi 68" dari kontrol sumber. Bagaimana dia menargetkan versi tertentu untuk dikloning? Atau apakah saya melewatkan sesuatu tentang Git yang membuat ini tidak perlu?
David
9
Perlu diingat bahwa solusi ini akan menghasilkan hasil yang berbeda untuk pengembang yang berbeda. Juga, menghitung mundur dari "hitungan" ke komit akan menghasilkan komitmen berbeda untuk pengembang yang berbeda !! Ini karena sifat didistribusikan dari Git dan bahwa komit terjadi dalam repositori yang berbeda selama potongan waktu yang sama tetapi mungkin tidak dihitung git rev-list --count HEADtergantung pada kapan dorongan dan tarikan terakhir dilakukan.
Jason
2
@Jason, apakah komentar David tentang menambahkan --first-parentalamat perhatian Anda? Aku benci untuk menghindari solusi yang tampaknya paling sederhana karena kasus tepi yang langka jika ada solusi atau cara yang sama-sederhana untuk membuatnya lebih kuat.
MarkHu
4
@MarkHu, --first-parentbantu. Selama tidak ada rebasing yang dilakukan dan cabang yang sama selalu digunakan untuk membuat rilis (dan menghitung nomor rilis ini, tentu saja), saya pikir ini bisa digunakan. Meskipun, saya masih ragu itu akan selalu mengidentifikasi secara unik komit yang berasal dari rilis. Ada begitu banyak hal yang bisa salah di sini ... tetapi saat ini saya tidak dapat memikirkan sesuatu yang pasti akan mematahkan ini (mengingat pernyataan saya di atas "selama"). The git describemetode yang disebutkan dalam jawaban lain adalah cara untuk pergi. Buat tag jika Anda ingin sesuatu yang dapat dibaca manusia.
Jason
104

The git describePerintah menciptakan nama yang dapat dibaca sedikit lebih manusia yang mengacu pada tertentu komit. Misalnya, dari dokumentasi:

Dengan sesuatu seperti pohon git.git saat ini, saya mendapatkan:

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

yaitu kepala saat ini dari cabang "induk" saya didasarkan pada v1.0.4, tetapi karena memiliki beberapa commit di atas itu, jelaskan telah menambahkan jumlah komit tambahan ("14") dan nama objek singkatan untuk komit sendiri ("2414721") pada akhirnya.

Selama Anda menggunakan tag dengan nama yang masuk akal untuk menandai rilis tertentu, ini dapat dianggap kira-kira setara dengan "nomor revisi" SVN.

Greg Hewgill
sumber
7
Saya hanya ingin mencatat bahwa ini hanya berfungsi jika gitrepositori Anda sudah memiliki tag; jika tidak, Anda mungkin mendapatkan git uraikan gagal dengan "fatal: Tidak ada nama yang ditemukan, tidak dapat menggambarkan apa pun." - Stack Overflow ; artinya Anda harus membuat tag sendiri.
sdaau
14
@daau: Jika Anda menggunakan ini dalam skrip atau sesuatu dan ingin git describetidak pernah gagal, gunakan git describe --alwaysopsi.
Greg Hewgill
Bisakah output git describedigunakan untuk menemukan sumber melakukan, entah bagaimana? Pendek menghitung secara manual komit dalam log, maksud saya.
Lii
@ Lii: Apa yang Anda maksud dengan "komit sumber"? Tag terdekat ( v1.0.4) dan id komit terbaru ( 2414721) sudah menjadi bagian dari git yang menggambarkan output.
Greg Hewgill
@GregHewgill: Ya, terima kasih, ketika saya mengajukan pertanyaan, saya tidak menyadari bahwa "nama objek yang disingkat" adalah nilai yang dapat digunakan untuk mengidentifikasi komit. Itu brilian!
Lii
67

Poster-poster lainnya benar, tidak ada "nomor revisi".

Saya pikir cara terbaik adalah menggunakan Tag untuk "rilis"!

Tapi saya menggunakan yang berikut ini untuk angka revisi palsu (hanya untuk klien melihat revisi dan kemajuan, karena mereka ingin memiliki revisi peningkatan yang sama dari git seperti yang mereka gunakan dengan subversi).

Perlihatkan "revisi saat ini" dari "KEPALA" disimulasikan dengan menggunakan ini:

git rev-list HEAD | wc -l

Tetapi bagaimana jika klien memberi tahu saya bahwa ada bug dalam "revisi" 1302?

Untuk ini saya menambahkan yang berikut ke bagian [alias] dari ~ / .gitconfig saya:

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

menggunakan git show-rev-number 1302kemudian akan mencetak hash untuk "revisi" :)

Saya membuat Posting Blog (dalam bahasa Jerman) tentang "teknik" itu beberapa waktu lalu.

OderWat
sumber
@Radek - "terkadang perlu tahu apa 'perubahan kode = komit' memperbaiki sesuatu" - lalu git bisect(tautan) adalah alat yang tepat untuk mengidentifikasi apa yang berubah ketika oleh siapa.
michael
@ Radek Ya, ini adalah angka yang terus meningkat. Itu hanya menghitung revisi yang Anda periksa di KEPALA. Jadi setiap komit adalah revisi baru. Ini tidak akan berfungsi untuk cabang yang berbeda.
OderWat
1
Saya suka solusi Anda. Harap perhatikan bahwa Anda dapat menyederhanakannya: show-rev-number =! Sh -c 'git rev-list --reverse HEAD | awk NR == $ 0 '
avner
@ David Terima kasih! Saya tidak menggunakan banyak awk dalam hidup saya, jelas :)
OderWat
3
Saya harus menggunakangit rev-list --reverse HEAD | awk "{ print NR }" | tail -n 1
Gerry
27

Git tidak memiliki konsep angka revisi yang sama dengan subversi. Sebaliknya setiap snapshot yang diberikan dibuat dengan komit ditandai oleh checksum SHA1. Mengapa? Ada beberapa masalah dengan revno yang berjalan di sistem kontrol versi terdistribusi:

Pertama, karena pengembangan tidak linier sama sekali, lampiran nomor agak sulit sebagai masalah untuk dipecahkan dengan cara yang akan memenuhi kebutuhan Anda sebagai seorang programmer. Mencoba memperbaikinya dengan menambahkan nomor mungkin dengan cepat menjadi bermasalah ketika nomor tersebut tidak berperilaku seperti yang Anda harapkan.

Kedua, angka revisi dapat dihasilkan pada mesin yang berbeda. Ini membuat sinkronisasi angka menjadi lebih sulit - terutama karena konektivitas bersifat satu arah; Anda bahkan mungkin tidak memiliki akses ke semua mesin yang memiliki repositori.

Ketiga, dalam git, agak dipelopori oleh sistem OpenCM yang sekarang sudah tidak ada, identitas dari sebuah commit (apa itu commit) setara dengan namanya (id SHA). Ini penamaan = identitas konsep yang sangat kuat. Saat Anda duduk dengan nama komit di tangan, komit juga mengidentifikasi komit dengan cara yang tidak bisa dikalahkan. Ini pada gilirannya memungkinkan Anda memeriksa semua komit Anda kembali ke yang pertama awal untuk korupsi dengan git fsckperintah.

Sekarang, karena kami memiliki DAG (Grafik Acyclic yang Diarahkan) dari revisi dan ini merupakan pohon saat ini, kami membutuhkan beberapa alat untuk menyelesaikan masalah Anda : Bagaimana kami membedakan versi yang berbeda. Pertama, Anda dapat menghilangkan bagian dari hash jika awalan yang diberikan, 1516bd katakan, secara unik mengidentifikasi komit Anda. Tapi ini juga agak dibuat-buat. Sebaliknya, caranya adalah dengan menggunakan tag dan atau cabang. Tag atau cabang mirip dengan "catatan tempel kuning" yang Anda lampirkan ke kom-SHA1-id yang diberikan. Tag, pada dasarnya, dimaksudkan untuk tidak bergerak sedangkan cabang akan bergerak ketika komit baru dibuat untuk KEPALA nya. Ada beberapa cara untuk merujuk komit di sekitar tag atau cabang, lihat halaman manual git-rev-parse.

Biasanya, jika Anda perlu mengerjakan bagian kode tertentu, bagian itu sedang mengalami perubahan dan harus menjadi cabang dengan nama topik yang disebutkan. Menciptakan banyak cabang (20-30 per programmer tidak pernah terdengar, dengan beberapa 4-5 diterbitkan untuk dikerjakan oleh orang lain) adalah trik untuk git yang efektif. Setiap karya harus dimulai sebagai cabangnya sendiri dan kemudian digabung saat diuji. Cabang-cabang yang tidak diterbitkan dapat ditulis ulang seluruhnya dan bagian dari menghancurkan sejarah ini adalah kekuatan git.

Ketika perubahan diterima menjadi master itu agak membeku dan menjadi arkeologi. Pada titik itu, Anda dapat menandai itu, tetapi lebih sering referensi ke komit tertentu dibuat dalam pelacak bug atau pelacak masalah melalui jumlah sha1. Tag cenderung dicadangkan untuk gundukan versi dan titik cabang untuk cabang pemeliharaan (untuk versi lama).

SAYA MEMBERI JAWABAN CRAP
sumber
18

Jika Anda tertarik, saya mengatur nomor versi secara otomatis dari git infos di sini dalam format

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

di mana build adalah jumlah total komitmen. Anda akan melihat kode menarik di Makefile. Inilah bagian yang relevan untuk mengakses bagian yang berbeda dari nomor versi:

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)
Sebastien Varrette
sumber
9

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

menghasilkan sesuatu seperti

$ git_rev
2:0f8e14e:20130220

Itu adalah

commit_count:last_abbrev_commit:date_YYmmdd
siznax
sumber
Hal semacam itu bisa berguna, tetapi jika seseorang tertarik pada nomor versi tambahan, mereka akan bertukar posisi lapangan sehingga hash (non-incremental) adalah yang terakhir.
MarkHu
8

The SHA1 hash dari komit adalah setara dengan nomor revisi Subversion.

Richard Fearn
sumber
7
Sayangnya ia memiliki properti yang sangat berbeda dari angka revisi. Itu agak panjang, dan itu tidak meningkat secara monoton. Kira itu harga yang harus dibayar untuk distribusi ...
CodesInChaos
1
@CodeInChaos: Saya tahu apa yang Anda maksud, tetapi umumnya memungkinkan untuk merujuk ke git commit dengan hanya 6 atau 8 karakter pertama dari kode hash.
Chris Pitman
5
@ Radek: Mereka tidak dijamin unik (meskipun jika Anda menemukan tabrakan Anda dapat memenangkan sejumlah kecil selebriti).
Slartibartfast
8
@ Radek Menurut en.wikipedia.org/wiki/Collision_attack , dengan 4 karakter hash Anda memiliki 16bit Id, yang berarti bahwa dalam repo dengan 256 (= 2 ^ (16/2)) komit ada 50 % kemungkinan dua komit memiliki awalan empat-char yang sama (dan dengan 65536 komit sudah pasti, sejak saat itu kisaran 4-char Id sudah habis). Ketika Anda menambahkan satu karakter, Anda memiliki ID 20 bit, yang berarti bahwa ambang 50% adalah 1024 komit. Tetapi karena ini adalah parameter statistik, tidak ada yang menjamin bahwa tabrakan seperti itu tidak terjadi sebelumnya.
Rudi
2
Karena hash didasarkan pada konten, masih ada kemungkinan apakah dua commit memiliki awalan hash yang sama, bukan kepastian. Pada 65536 commit, sangat mungkin bahwa dua akan memiliki awalan empat-char yang sama, tetapi masih belum pasti. Selain itu, hash lengkap belum memiliki tabrakan, tetapi git sedang mengusahakannya :) stackoverflow.com/questions/3475648/…
goodeye
6

Inilah yang saya lakukan di makefile saya berdasarkan solusi orang lain. Catatan tidak hanya memberi kode Anda nomor revisi, tetapi juga menambahkan hash yang memungkinkan Anda untuk membuat ulang rilis.

# 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
sumber
3
Tampaknya cara paling aman untuk digunakan git-describeuntuk menghindari kesalahan, adalah dengan git describe --always --dirty --long --tagsyang berfungsi dalam semua kasus yang dapat saya pikirkan.
MarkHu
5

Masalah dengan menggunakan hash git sebagai nomor build adalah bahwa itu tidak meningkat secara monoton. OSGi menyarankan menggunakan cap waktu untuk nomor build. Sepertinya jumlah komit ke cabang bisa digunakan sebagai pengganti nomor perubahan subversi atau terpaksa.

Jim Belton
sumber
5

Saya menulis beberapa utilitas PowerShell untuk mengambil informasi versi dari Git dan menyederhanakan penandaan

fungsi: Get-LastVersion, Get-Revisi, 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
sumber
4

Setiap komit memiliki hash yang unik. Selain itu tidak ada angka revisi di git. Anda harus menandai komitmen sendiri jika Anda ingin lebih ramah pengguna.

Core Xii
sumber
3

Saya hanya ingin mencatat pendekatan lain yang mungkin - dan itu adalah dengan menggunakan git git-note (1) , yang ada sejak v 1.6.6 ( Note to Self - Git ) (Saya menggunakan gitversi 1.7.9.5).

Pada dasarnya, saya dulu git svnmengkloning repositori SVN dengan histori linier (tanpa tata letak standar, tanpa cabang, tanpa tag), dan saya ingin membandingkan angka revisi di gitrepositori yang dikloning . Klon git ini tidak memiliki tag secara default, jadi saya tidak bisa menggunakan git describe. Strategi di sini kemungkinan hanya akan bekerja untuk sejarah linier - tidak yakin bagaimana hasilnya dengan penggabungan dll .; tapi inilah strategi dasarnya:

  • Minta git rev-listdaftar semua riwayat komit
    • Karena rev-listsecara default dalam "urutan kronologis terbalik", kami akan menggunakan --reversesakelar untuk mendapatkan daftar komit yang diurutkan berdasarkan yang terlama terlebih dahulu
  • Gunakan bashshell untuk
    • menambah variabel penghitung pada setiap komit sebagai penghitung revisi,
    • menghasilkan dan menambahkan catatan git "sementara" untuk setiap komit
  • Kemudian, isi log dengan menggunakan git logdengan --notes, yang juga akan membuang catatan komit, yang dalam hal ini akan menjadi "nomor revisi"
  • Setelah selesai, hapus catatan sementara ( NB: Saya tidak yakin apakah catatan ini dilakukan atau tidak; mereka tidak benar-benar muncul digit status )

Pertama, mari kita catat yang gitmemiliki lokasi default catatan - tetapi Anda juga dapat menentukan ref(erence) untuk catatan - yang akan menyimpannya di direktori berbeda di bawah .git; misalnya, saat berada di gitfolder repo, Anda dapat menelepon git notes get-refuntuk melihat direktori apa yang akan:

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

Hal yang perlu diperhatikan adalah bahwa jika Anda notes adddengan --ref, Anda juga harus kemudian menggunakan referensi itu lagi - jika tidak, Anda mungkin mendapatkan kesalahan seperti " Tidak ditemukan catatan untuk objek XXX ... ".

Untuk contoh ini, saya telah memilih untuk memanggil refcatatan "linrev" (untuk revisi linear) - ini juga berarti tidak mungkin prosedur akan mengganggu catatan yang sudah ada. Saya juga menggunakan --git-dirsaklar, karena menjadi gitpemula, saya memiliki beberapa masalah memahaminya - jadi saya ingin "mengingat nanti" :); dan saya juga gunakan --no-pageruntuk menekan pemijahan lesssaat menggunakan git log.

Jadi, dengan asumsi Anda berada di direktori, dengan subfolder myrepo_gityang merupakan gitrepositori; yang bisa dilakukan:

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

Jadi, setidaknya dalam kasus khusus saya tentang riwayat linear penuh tanpa cabang, angka revisi tampaknya cocok dengan pendekatan ini - dan tambahan, tampaknya pendekatan ini akan memungkinkan penggunaan git logdengan rentang revisi, sambil tetap mendapatkan angka revisi yang tepat - YMMV dengan konteks yang berbeda, meskipun ...

Semoga ini bisa membantu seseorang,
Ceria!


EDIT: Ok, ini dia sedikit lebih mudah, dengan gitalias untuk loop di atas, dipanggil setlinrevdan unsetlinrev; ketika di folder repositori git Anda, lakukan ( Perhatikan bashpelolosan jahat , lihat juga # 16136745 - Tambahkan alias Git yang mengandung tanda titik koma ):

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

... jadi Anda bisa memohon git setlinrevsebelum mencoba melakukan log yang melibatkan catatan revisi linear; dan git unsetlinrevuntuk menghapus catatan itu setelah selesai; contoh dari dalam direktori 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 <<

Waktu yang dibutuhkan shell untuk menyelesaikan alias ini, akan tergantung pada ukuran riwayat repositori.

sdaau
sumber
2

Untuk orang-orang yang memiliki proses pembuatan Semut , Anda dapat menghasilkan nomor versi untuk proyek di git dengan target ini:

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

Hasilnya terlihat seperti ini:

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

Bendera kotor ada di sini ketika Anda memiliki file yang tidak dikomit ketika Anda menghasilkan nomor versi. Karena biasanya, ketika Anda membangun / mengemas aplikasi Anda, setiap modifikasi kode harus ada di repositori.

Fredo
sumber
1

Seiring dengan id SHA-1 dari komit, tanggal dan waktu waktu server akan membantu?

Sesuatu seperti ini:

komit terjadi pada 11:30:25 pada 19 Agustus 2013 akan ditampilkan sebagai 6886bbb7be18e63fc4be68ba41917b48f02e09d7_19aug2013_113025

Manoranjan Sahu
sumber
1

Dari manual Git, tag adalah jawaban yang brilian untuk masalah ini:

Membuat tag beranotasi di Git itu mudah. Cara termudah adalah menentukan -a saat Anda menjalankan perintah tag:

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

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

Lihat 2.6 Dasar-Dasar Git - Penandaan

DJ Far
sumber
Sayang sekali Anda harus melewati rintangan untuk mengubah default:By default, the git push command doesn’t transfer tags to remote servers.
MarkHu
1

Kami menggunakan perintah ini untuk mendapatkan versi dan revisi dari git:

git describe --always --tags --dirty

Ia kembali

  • komit hash sebagai revisi ketika tidak ada penandaan digunakan (misalnya gcc7b71f)
  • nama tag sebagai versi ketika pada tag (misalnya v2.1.0, digunakan untuk rilis)
  • nama tag, nomor revisi sejak tag terakhir dan komit hash ketika setelah tag (mis. v5.3.0-88-gcc7b71f)
  • sama seperti di atas ditambah tag "kotor" jika pohon kerja memiliki modifikasi lokal (mis. v5.3.0-88-gcc7b71f-dirty)

Lihat juga: https://www.git-scm.com/docs/git-describe#Documentation/git-describe.txt

ini adalah desainku
sumber
0

Acara posting membangun untuk Visual Studio

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

Pertimbangkan untuk menggunakannya

git-rev-label

Memberikan informasi tentang revisi repositori Git dalam format seperti master-c73-gabc6bec. Dapat mengisi string atau file template dengan variabel lingkungan dan informasi dari Git. Berguna untuk memberikan informasi tentang versi program: cabang, tag, komit hash, jumlah komit, status kotor, tanggal dan waktu. Salah satu hal yang paling berguna adalah hitungan komit, tidak memperhitungkan cabang gabungan - hanya orang tua pertama.

Kyb
sumber