Bagaimana cara mengurutkan tag git berdasarkan urutan string versi dari bentuk rc-XYZW?

109

Saat saya memasukkan perintah:

git tag -l

Saya mendapatkan hasil seperti itu:

rc-0.9.0.0
rc-0.9.0.1
rc-0.9.0.10
rc-0.9.0.11
rc-0.9.0.12
rc-0.9.0.2
rc-0.9.0.3
rc-0.9.0.4
rc-0.9.0.5
rc-0.9.0.6
rc-0.9.0.7
rc-0.9.0.8
rc-0.9.0.9

Daripada ini saya ingin:

rc-0.9.0.0
rc-0.9.0.1
rc-0.9.0.2
rc-0.9.0.3
rc-0.9.0.4
rc-0.9.0.5
rc-0.9.0.6
rc-0.9.0.7
rc-0.9.0.8
rc-0.9.0.9
rc-0.9.0.10
rc-0.9.0.11
rc-0.9.0.12

Bagaimana mungkin mengurutkan daftar saat ini untuk mendapatkan hasil seperti itu?

Viacheslav Kondratiuk
sumber
1
Dengan Git 2.0, Anda akan segera dapat melakukan git tag -l --sort=version:refname "rc-*", dan mendapatkan keluaran yang Anda inginkan. lihat jawaban saya di bawah
VonC
1
Git 2.0 sudah keluar sekarang, dan semua jawaban di bawah ini menggunakan 'sort' tidak lagi diperlukan. --sorttersedia untuk git tag
VonC

Jawaban:

157

Gunakan urutan versi

git tag -l | sort -V

atau untuk versi git> = 2.0

git tag -l --sort=v:refname
git tag -l --sort=-v:refname # reverse
Robert Mutke
sumber
@miku tolong periksa! bagi saya itu
Robert Mutke
5
Argumen -V tidak tersedia di OS X (10.8) versi yang disediakan (5.93). :(
Julien
2
Anda dapat menggunakan homebrew atau macports untuk menginstal versi gnu dari sort. brew install gsortkemudian Anda dapat mengubah baris di atas menjadi git tag -l | gsort -Vdan itu akan bekerja untuk Anda.
Goran
4
Saya harus menggunakan brew install coreutilsuntuk mendapatkan gsortperintah. brew install gsortgagal, mengatakan tidak ada paket yang dipanggil gsort.
nwinkler
Tidak beruntung di msysgit juga
cchamberlain
78

Dengan Git 2.0 (Juni 2014), Anda akan dapat menentukan urutan penyortiran!

Lihat commit b6de0c6 , dari commit 9ef176b , ditulis oleh Nguyễn Thái Ngọc Duy ( pclouds) :

 --sort=<type>

Sortir dalam urutan tertentu .
Jenis yang didukung adalah:

  • " refname" (urutan leksikografik),
  • " version:refname" atau " v:refname" (nama tag diperlakukan sebagai versi).

Tambahkan " -" untuk membalik urutan sortir.


Jadi, jika Anda memiliki:

git tag foo1.3 &&
git tag foo1.6 &&
git tag foo1.10

Inilah yang akan Anda dapatkan:

# lexical sort
git tag -l --sort=refname "foo*"
foo1.10
foo1.3
foo1.6

# version sort
git tag -l --sort=version:refname "foo*"
foo1.3
foo1.6
foo1.10

# reverse version sort
git tag -l --sort=-version:refname "foo*"
foo1.10
foo1.6
foo1.3

# reverse lexical sort
git tag -l --sort=-refname "foo*"
foo1.6
foo1.3
foo1.10

Sejak commit b150794 (oleh Jacob Keller, git 2.1.0, Agustus 2014), Anda dapat menentukan pesanan default tersebut:

tag.sort

Variabel ini mengontrol pengurutan tag saat ditampilkan oleh git-tag.
Tanpa opsi " --sort=<value>" yang diberikan, nilai variabel ini akan digunakan sebagai default.

komentar robinst :

urutan versi sekarang dapat (Git 2.1+) dikonfigurasi sebagai default:

git config --global tag.sort version:refname

Seperti dicatat oleh Leo Galleguillos di komentar :

Untuk mengkonfigurasi Git agar menampilkan tag terbaru terlebih dahulu ( urutan menurun ), cukup tambahkan tanda hubung sebelum versi .
Perintahnya menjadi:

git config --global tag.sort -version:refname

Dengan Git 2.4 (Q2 2015) , yang versionsort.prereleasevariabel konfigurasi dapat digunakan untuk menentukan bahwa v1.0-pre1datang sebelumv1.0 .

Lihat commit f57610a oleh Junio ​​C Hamano ( gitster) .

Catatan (lihat di bawah) versionsort.prereleaseSuffixsekarang (2017) adalah alias yang tidak digunakan lagi untuk versionsort.suffix.


git 2.7.1 (Februari 2016) akan meningkatkan outputnya git tagsendiri.

Lihat commit 0571979 (26 Jan 2016), dan commit 1d094db (24 Jan 2016) by Jeff King ( peff) .
(Digabung oleh Junio ​​C Hamano - gitster- di commit 8bad3de , 01 Feb 2016)

tag: jangan tampilkan nama tag yang ambigu sebagai " tags/foo"

Sejak b7cc53e ( tag.c: use ' ref-filter' APIs, 2015-07-11), git tagtelah mulai menampilkan tag dengan nama yang ambigu (yaitu, saat " heads/foo" dan " tags/foo" ada) sebagai " tags/foo" bukan hanya " foo".
Ini keduanya:

  • tak berarti; keluaran dari " git tag" hanya mencakup refs/tags, jadi kita tahu bahwa " foo" berarti yang ada di " refs/tags".
  • dan ambigu; pada keluaran aslinya, kita tahu bahwa baris " foo" berarti " refs/tags/foo" ada. Dalam keluaran baru, tidak jelas apakah yang kami maksud " refs/tags/foo" atau " refs/tags/tags/foo".

Alasan ini terjadi adalah karena komit b7cc53e dialihkan git taguntuk menggunakan %(refname:short)pemformatan keluaran " " ref-filter , yang diadaptasi dari for-each-ref. Kode yang lebih umum ini tidak mengetahui bahwa kita hanya peduli tentang tag, dan menggunakan shorten_unambiguous_refuntuk mendapatkan short-name.
Kita perlu mengatakan bahwa kita hanya peduli tentang " refs/tags/", dan itu harus dipersingkat sehubungan dengan nilai itu.

mari tambahkan pengubah baru ke bahasa pemformatan, " strip", untuk menghapus sekumpulan komponen awalan tertentu.
Ini memperbaiki " git tag", dan memungkinkan pengguna menjalankan perilaku yang sama dari format khusus mereka sendiri (untuk " tag" atau " for-each-ref") sambil meninggalkan " :short" dengan arti konsisten yang sama di semua tempat.

Jika strip=<N>ditambahkan, strip <N>komponen jalur dipisahkan garis miring dari depan refname (misalnya, %(refname:strip=2)berubah refs/tags/foomenjadi foo.
<N>Harus berupa bilangan bulat positif.
Jika ref yang ditampilkan memiliki lebih sedikit komponen daripada <N>, perintah dibatalkan dengan kesalahan.

Karena git tag, jika tidak ditentukan, defaultnya adalah %(refname:strip=2).


Perbarui Git 2.12 (Q1 2017)

Lihat commit c026557 , commit b178464 , commit 51acfa9 , commit b823166 , commit 109064a , commit 0c1b487 , commit 9ffda48 , commit eba286e (08 Dec 2016) oleh SZEDER Gábor ( szeder) .
(Digabung oleh Junio ​​C Hamano - gitster- di commit 1ac244d , 23 Jan 2017)

versionsort.prereleaseSuffixadalah alias yang tidak digunakan lagi untuk versionsort.suffix.

The prereleaseSuffixfitur perbandingan versi yang digunakan dalam " git tag -l" tidak benar ketika dua atau lebih prereleases untuk rilis yang sama hadir (misalnya ketika 2.0, 2.0-beta1dan 2.0-beta2 yang ada dan kebutuhan kode untuk membandingkan 2.0-beta1dan 2.0-beta2).

VonC
sumber
--sorttidak ada di git 1.9.1. (Bekerja pada 2.0.0)
Tibor Vass
@TeaBee benar, saya telah mengedit jawabannya, sejak Git 2.0 dirilis sekarang.
VonC
1
Dengan Git 2.1.0, urutan versi sekarang dapat dikonfigurasi sebagai default:git config --global tag.sort version:refname
robinst
1
Akan bermanfaat untuk menjelaskan mengapa ini lebih baik daripada sort -V. Satu-satunya keuntungan yang saya lihat adalah portabilitas ke sistem yang tidak memiliki jenis GNU. Tetapi jika Anda memilikinya, | sort -Vgolf lebih baik. Masalahnya adalah: metode pengurutan ini tidak menggunakan informasi spesifik Git (tidak seperti misalnya, urutan topologi objek yang ditunjukkan seperti di stackoverflow.com/questions/6900328/… )
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
@LeoGalleguillos Terima kasih. Saya telah memasukkan komentar Anda dalam jawaban untuk visibilitas lebih lanjut.
VonC
12

Menurut jawaban ini , pada platform yang tidak mendukung sort -Vseperti Windows dan OSX, Anda dapat menggunakan

git tag -l | sort -n -t. -k1,1 -k2,2 -k3,3 -k4,4

Cédric
sumber
1
@ Ovi-WanKenobi Anda harus menjalankannya di shell Cygwin (atau mingw).
Cédric
10

Menggabungkan jawaban sudah ada di sini:

Repositori lokal

git -c 'versionsort.suffix=-' tag --list --sort=-v:refname
  • suffix=-akan mencegah 2.0-rcdatangnya "setelah"2.0
  • --sort=- akan menempatkan nomor versi tertinggi di bagian atas.

Repositori jarak jauh

git -c 'versionsort.suffix=-' ls-remote -t --exit-code --refs --sort=-v:refname "$repo_url" \
    | sed -E 's/^[[:xdigit:]]+[[:space:]]+refs\/tags\/(.+)/\1/g'

Keuntungannya adalah tidak ada objek yang diunduh dari jarak jauh.

Untuk info lebih lanjut lihat jawaban ini .

Tom Hale
sumber
Penggunaan yang sangat menarik versionsort.suffix. +1.
VonC
2

Untuk mendapatkan pengurutan terbalik dengan sort -Vpendekatan:

git tag -l | sort -V --reverse
modle13
sumber
1

Sesuaikan skrip perl ini , yang akan mengurutkan tag yang terlihat client_release/7.2/7.2.25, dengan skema pemberian tag khusus Anda.

David Tonhofer
sumber
1

Saya akhirnya menulis skrip shell sederhana untuk menyederhanakan tugas ini.

#!/usr/bin/env bash

TAGS=$(git tag)
CODE=$?

if [ $CODE = 0 ]; then
    echo "$TAGS" | sort -V
fi

exit $CODE

Saya menyimpannya seperti git-tagsdi saya $PATHdan menjalankan git tagssetiap kali saya perlu membuat daftar tag.

Kevin Herrera
sumber
2
git tag | urutkan -V; keluar $ PIPESTATUS
luxigo