Jak posortować tagi git według kolejności ciągów wersji w postaci rc-XYZW?

109

Kiedy wprowadzam polecenie:

git tag -l

Uzyskuję takie wyniki:

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

Zamiast tego chcę:

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

Jak można posortować aktualną listę, aby uzyskać takie wyniki?

Viacheslav Kondratiuk
źródło
1
Dzięki Git 2.0 wkrótce będziesz mógł wykonać git tag -l --sort=version:refname "rc-*"i uzyskać żądane wyniki. zobacz moją odpowiedź poniżej
VonC
1
Git 2.0 jest już dostępny i wszystkie poniższe odpowiedzi przy użyciu polecenia „sort” nie są już potrzebne. --sortjest dostępny dla tagu git
VonC

Odpowiedzi:

157

Użyj sortowania wersji

git tag -l | sort -V

lub dla wersji git> = 2.0

git tag -l --sort=v:refname
git tag -l --sort=-v:refname # reverse
Robert Mutke
źródło
@miku, proszę sprawdzić! dla mnie tak
Robert Mutke
5
Argument -V nie jest dostępny w sortowanej wersji systemu OS X (10.8) (5.93). :(
Julien,
2
możesz użyć homebrew lub macports do zainstalowania sortowanej wersji gnu. brew install gsortnastępnie możesz zmodyfikować powyższy wiersz na git tag -l | gsort -Vi powinien on działać dla Ciebie.
Goran
4
Musiałem użyć, brew install coreutilsaby uzyskać gsortpolecenie. brew install gsortnie powiodło się, mówiąc, że nie wywołano żadnego pakietu gsort.
nwinkler
Nie
udało się też na msysgit
78

Dzięki Git 2.0 (czerwiec 2014) będziesz mógł określić kolejność sortowania!

Zobacz commit b6de0c6 , z commit 9ef176b , autorstwa Nguyễn Thái Ngọc Duy ( pclouds) :

 --sort=<type>

Sortuj w określonej kolejności .
Obsługiwany typ to:

  • " refname" (porządek leksykograficzny),
  • version:refname” lub „ v:refname” (nazwy tagów są traktowane jako wersje).

Dołącz „ -” na początku, aby odwrócić kolejność sortowania.


Więc jeśli masz:

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

Oto, co byś otrzymał:

# 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

Ponieważ zatwierdzenie b150794 (autorstwa Jacoba Kellera, git 2.1.0, sierpień 2014), możesz określić tę domyślną kolejność:

tag.sort

Ta zmienna steruje porządkiem sortowania tagów wyświetlanych przez git-tag.
Bez --sort=<value>podanej opcji „ ” wartość tej zmiennej będzie używana jako domyślna.

robinst komentarze :

kolejność sortowania wersji można teraz (Git 2.1+) skonfigurować jako domyślną:

git config --global tag.sort version:refname

Jak zauważył Leo Galleguillos w komentarzach :

Aby skonfigurować Git tak, aby najpierw wyświetlał najnowsze tagi (w kolejności malejącej ), po prostu dodaj myślnik przed wersją .
Polecenie staje się:

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

Z Git 2.4 (Q2 2015) , zmienna konfiguracja może być używana do określenia, że jest przed .versionsort.prereleasev1.0-pre1v1.0

Zobacz commit f57610a autorstwa Junio ​​C Hamano ( gitster) .

Uwaga (patrz poniżej) versionsort.prereleaseSuffixjest teraz (2017) przestarzałym aliasem dla platformy versionsort.suffix.


git 2.7.1 (luty 2016) poprawi swoją wydajność git tag.

Zobacz commit 0571979 (26 stycznia 2016) i commit 1d094db (24 stycznia 2016) autorstwa Jeffa Kinga ( peff) .
(Scalony przez Junio ​​C Hamano - gitster- w zatwierdzeniu 8bad3de , 01 lutego 2016)

tag: nie pokazuj niejednoznacznych nazw tagów jako „ tags/foo

Od b7cc53e ( tag.c: użyj ref-filterinterfejsów API „ ”, 11.07.2015), git tagzaczął wyświetlać tagi o niejednoznacznych nazwach (tj. Gdy zarówno „ heads/foo”, jak i „ tags/foo” istnieją) jako „ tags/foo” zamiast tylko „ foo”.
To jest zarówno:

  • bezcelowy; wyjście „ git tag” obejmuje tylko refs/tags, więc wiemy, że „ foo” oznacza ten w „ refs/tags”.
  • i niejednoznaczne; w oryginalnym wyniku wiemy, że wiersz „ foo” oznacza, że ​​„ refs/tags/foo” istnieje. W nowym wydaniu nie jest jasne, czy mamy na myśli „ refs/tags/foo” czy „ refs/tags/tags/foo”.

Powodem tego jest to, że commit b7cc53e przełączył się git tagna %(refname:short)formatowanie wyjścia " " filtru ref , z którego zostało zaadaptowane for-each-ref. Ten bardziej ogólny kod nie wie, że zależy nam tylko na tagach i używa shorten_unambiguous_refdo uzyskania short-name.
Musimy mu powiedzieć, że zależy nam tylko na " refs/tags/" i powinno skrócić się względem tej wartości.

dodajmy nowy modyfikator do języka formatowania, " strip", aby usunąć określony zestaw komponentów przedrostków.
To naprawia „ git tag” i pozwala użytkownikom wywoływać to samo zachowanie z ich własnych niestandardowych formatów (dla „ tag” lub „ for-each-ref”), pozostawiając „ :short” z tym samym spójnym znaczeniem we wszystkich miejscach.

Jeśli strip=<N>jest dołączone, usuwa <N>oddzielone ukośnikiem komponenty ścieżki z początku nazwy odniesienia (np. %(refname:strip=2)Zamienia się refs/tags/foow foo.
<N>Musi być dodatnią liczbą całkowitą.
Jeśli wyświetlany odnośnik ma mniej składników niż <N>, polecenie przerywa działanie z błędem.

Do git tagkiedy nieokreślone, domyślnie %(refname:strip=2).


Zaktualizuj Git 2.12 (I kwartał 2017)

Zobacz zatwierdzenie c026557 , zatwierdzenie b178464 , zatwierdzenie 51acfa9 , zatwierdzenie b823166 , zatwierdzenie 109064a , zatwierdzenie 0c1b487 , zatwierdzenie 9ffda48 , zatwierdzenie eba286e (08 grudnia 2016) autorstwa SZEDER Gábor ( szeder) .
(Scalone przez Junio ​​C Hamano - gitster- w zatwierdzeniu 1ac244d , 23 stycznia 2017 r.)

versionsort.prereleaseSuffixjest przestarzałym aliasem dla versionsort.suffix.

prereleaseSuffixCechą porównania wersji, która jest używana w „ git tag -l” nie poprawnie, gdy dwa lub więcej prereleases dla tej samej wersji były obecne (np kiedy 2.0, 2.0-beta1i 2.0-beta2 są tam i potrzebuje kod do porównania 2.0-beta1i 2.0-beta2).

VonC
źródło
--sortnie istnieje na git 1.9.1. (pracował nad 2.0.0)
Tibor Vass
@TeaBee prawda, odpowiednio zredagowałem odpowiedź, ponieważ Git 2.0 jest teraz dostępny.
VonC
1
W Git 2.1.0 kolejność sortowania wersji można teraz skonfigurować jako domyślną:git config --global tag.sort version:refname
robinst,
1
Warto byłoby wyjaśnić, dlaczego jest to lepsze niż sort -V. Jedyną zaletą, jaką widzę, jest przenośność na systemy, które nie mają sortowania GNU. Ale jeśli masz to | sort -Vgolfa lepiej. Rzecz w tym, że ta metoda sortowania nie używa żadnych informacji specyficznych dla Gita (w przeciwieństwie np. Do topologicznej kolejności obiektu wskazywanego jak w stackoverflow.com/questions/6900328/ ... )
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
@LeoGalleguillos Dziękuję. W odpowiedzi zawarłem Twój komentarz, aby uzyskać lepszą widoczność.
VonC
12

Zgodnie z tą odpowiedzią na platformach, które nie obsługują, sort -Vtakich jak Windows i OSX, możesz użyć

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

Cédric
źródło
1
@ Ovi-WanKenobi musisz go uruchomić na powłoce Cygwin (lub mingw).
Cédric
10

Łącząc odpowiedzi już tutaj:

Lokalne repozytorium

git -c 'versionsort.suffix=-' tag --list --sort=-v:refname
  • suffix=-zapobiegnie 2.0-rcprzyjściu „po”2.0
  • --sort=- umieści najwyższy numer wersji na górze.

Zdalne repozytorium

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

Zaletą tego jest to, że żadne obiekty nie są pobierane z pilota.

Aby uzyskać więcej informacji, zobacz tę odpowiedź .

Tom Hale
źródło
Bardzo ciekawe użycie versionsort.suffix. +1.
VonC
2

Aby uzyskać odwrotne sortowanie z sort -Vpodejściem:

git tag -l | sort -V --reverse
model13
źródło
1

Dostosuj ten skrypt Perla , który sortuje wyglądające tagi client_release/7.2/7.2.25, do konkretnego schematu tagowania.

David Tonhofer
źródło
1

Skończyło się na napisaniu prostego skryptu powłoki, aby uprościć to zadanie.

#!/usr/bin/env bash

TAGS=$(git tag)
CODE=$?

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

exit $CODE

Zapisałem to jako git-tagsmoje $PATHi uruchamiam, git tagsgdy chcę wyświetlić tagi.

Kevin Herrera
źródło
2
tag git | sort -V; exit $ PIPESTATUS
luxigo