Làm cách nào để sắp xếp các thẻ git theo thứ tự chuỗi phiên bản của biểu mẫu rc-XYZW?


109

Khi tôi nhập một lệnh:

git tag -l

Tôi nhận được kết quả như vậy:

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

Thay vì điều này, tôi muốn:

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

Làm thế nào có thể sắp xếp danh sách hiện tại để có được kết quả như vậy?


1
Với Git 2.0, bạn sẽ sớm có thể thực hiện git tag -l --sort=version:refname "rc-*"và nhận được kết quả như mong muốn. xem câu trả lời của tôi bên dưới
VonC

1
Git 2.0 hiện đã ra mắt và tất cả các câu trả lời bên dưới sử dụng 'sắp xếp' không còn cần thiết nữa. --sortcó sẵn cho thẻ git
VonC

Câu trả lời:


157

Sử dụng sắp xếp phiên bản

git tag -l | sort -V

hoặc cho phiên bản git> = 2.0

git tag -l --sort=v:refname
git tag -l --sort=-v:refname # reverse

@miku vui lòng kiểm tra! đối với tôi nó không
Robert Mutke

5
Đối số -V không khả dụng trên phiên bản cung cấp OS X (10.8) (5.93). :(
Julien

2
bạn có thể sử dụng homebrew hoặc macports để cài đặt phiên bản gnu. brew install gsortthì bạn có thể sửa đổi dòng ở trên thành git tag -l | gsort -Vvà nó sẽ phù hợp với bạn.
Goran

4
Tôi đã phải sử dụng brew install coreutilsđể có được gsortlệnh. brew install gsortkhông thành công, nói rằng không có gói nào được gọi gsort.
nwinkler

Cũng không gặp may trên msysgit
cchamberlain

78

Với Git 2.0 (tháng 6 năm 2014), bạn sẽ có thể chỉ định thứ tự sắp xếp!

Xem commit b6de0c6 , từ commit 9ef176b , tác giả Nguyễn Thái Ngọc Duy ( pclouds) :

 --sort=<type>

Sắp xếp theo một thứ tự cụ thể .
Loại được hỗ trợ là:

  • " refname" (thứ tự từ vựng),
  • " version:refname" hoặc " v:refname" (tên thẻ được coi là phiên bản).

Thêm " -" để đảo ngược thứ tự sắp xếp.


Vì vậy, nếu bạn có:

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

Đây là những gì bạn sẽ nhận được:

# 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

Kể từ commit b150794 (bởi Jacob Keller, git 2.1.0, tháng 8 năm 2014), bạn có thể xác định thứ tự mặc định đó:

tag.sort

Biến này kiểm soát thứ tự sắp xếp của các thẻ khi được hiển thị bởi git-tag.
Nếu không có --sort=<value>tùy chọn "" được cung cấp, giá trị của biến này sẽ được sử dụng làm giá trị mặc định.

bình luận trên robinst :

thứ tự sắp xếp phiên bản bây giờ có thể được cấu hình (Git 2.1+) làm mặc định:

git config --global tag.sort version:refname

Theo ghi nhận của Leo Galleguillos trong các bình luận :

Để cấu hình Git hiển thị các thẻ mới nhất trước ( thứ tự giảm dần ), chỉ cần thêm dấu gạch ngang trước phiên bản .
Lệnh trở thành:

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

Với Git 2.4 (Q2 năm 2015) , các versionsort.prereleasebiến cấu hình có thể được sử dụng để xác định rằng v1.0-pre1đến trướcv1.0 .

Xem cam kết f57610a của Junio ​​C Hamano ( gitster) .

Lưu ý (xem bên dưới) versionsort.prereleaseSuffixbây giờ (2017) là một bí danh không dùng nữa cho versionsort.suffix.


git 2.7.1 (tháng 2 năm 2016) sẽ cải thiện sản lượng của git tagchính nó.

Xem cam kết 0571979 (26 tháng 1 năm 2016) và cam kết 1d094db (24 tháng 1 năm 2016) bởi Jeff King ( peff) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- in cam kết 8bad3de , 01/02/2016)

tag: không hiển thị tên thẻ không rõ ràng là " tags/foo"

Kể từ khi b7cc53e ( tag.c: use ' ref-filter' API, 2015-07-11), git tagđã bắt đầu hiển thị các thẻ có tên không rõ ràng (tức là khi tồn tại cả " heads/foo" và " tags/foo") là " tags/foo" thay vì chỉ " foo".
Đây là cả hai:

  • vô nghĩa; đầu ra của " git tag" chỉ bao gồm refs/tags, vì vậy chúng tôi biết rằng " foo" có nghĩa là đầu ra trong " refs/tags".
  • và mơ hồ; trong đầu ra ban đầu, chúng ta biết rằng dòng " foo" có nghĩa là " refs/tags/foo" tồn tại. Trong đầu ra mới, không rõ chúng ta có nghĩa là " refs/tags/foo" hay " refs/tags/tags/foo".

Lý do điều này xảy ra là commit b7cc53e chuyển sang git tagsử dụng %(refname:short)định dạng đầu ra " " của ref-filter , được điều chỉnh từ đó for-each-ref. Mã tổng quát hơn này không biết rằng chúng tôi chỉ quan tâm đến các thẻ và sử dụng shorten_unambiguous_refđể lấy short-name.
Chúng tôi cần nói với nó rằng chúng tôi chỉ quan tâm đến "refs/tags/ " và nó phải rút ngắn lại so với giá trị đó.

hãy thêm một công cụ sửa đổi mới vào ngôn ngữ định dạng, " strip", để xóa một tập hợp cụ thể của các thành phần tiền tố.
Điều này sửa lỗi " git tag" và cho phép người dùng gọi cùng một hành vi từ các định dạng tùy chỉnh của riêng họ (cho " tag" hoặc " for-each-ref") trong khi vẫn để " :short" với cùng một ý nghĩa nhất quán ở tất cả các vị trí.

Nếu strip=<N>được nối thêm, dải các <N>thành phần đường dẫn được phân tách bằng dấu gạch chéo từ phía trước tên đổi tên (ví dụ: %(refname:strip=2)biến refs/tags/foothành foo.
<N>Phải là một số nguyên dương.
Nếu một tham chiếu được hiển thị có ít thành phần hơn <N>, lệnh hủy bỏ do lỗi.

Đối với git tag, khi không xác định, mặc định là %(refname:strip=2).


Cập nhật Git 2.12 (Q1 2017)

Xem cam kết c026557 , cam kết b178464 , cam kết 51acfa9 , cam kết b823166 , cam kết 109064a , cam kết 0c1b487 , cam kết 9ffda48 , cam kết eba286e (08 tháng 12 năm 2016) bởi SZEDER Gábor ( szeder) .
(Hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 1ac244d , ngày 23 tháng 1 năm 2017)

versionsort.prereleaseSuffixlà một bí danh không dùng nữa cho versionsort.suffix.

Các prereleaseSuffixtính năng của phiên bản so sánh được sử dụng trong " git tag -l" không chính xác khi hai hoặc nhiều prereleases cho việc phát hành cùng đã có mặt (ví dụ như khi 2.0, 2.0-beta12.0-beta2 đang có và nhu cầu mã để so sánh 2.0-beta12.0-beta2).


--sortkhông tồn tại trên git 1.9.1. (làm việc trên 2.0.0)
Tibor Vass

@TeaBee true, tôi đã chỉnh sửa câu trả lời cho phù hợp, vì Git 2.0 được phát hành ngay bây giờ.
VonC

1
Với Git 2.1.0, thứ tự phiên bản loại bây giờ có thể được cấu hình như mặc định:git config --global tag.sort version:refname
robinst

1
Nó sẽ là giá trị giải thích tại sao điều này tốt hơn sort -V. Ưu điểm duy nhất mà tôi thấy là tính di động cho các hệ thống không có phân loại GNU. Nhưng nếu bạn có nó, | sort -Vchơi gôn tốt hơn. Vấn đề là: phương pháp sắp xếp này không sử dụng bất kỳ thông tin cụ thể nào về Git (không giống như thứ tự tôpô của đối tượng được trỏ đến như trong stackoverflow.com/questions/6900328/… )
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

1
@LeoGalleguillos Cảm ơn bạn. Tôi đã bao gồm bình luận của bạn trong câu trả lời để hiển thị nhiều hơn.
VonC

12

Theo câu trả lời này , trên các nền tảng không hỗ trợ sort -Vnhư Windows và OSX, bạn có thể sử dụng

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


1
@ Ovi-WanKenobi bạn cần chạy nó trên Cygwin (hoặc mingw) shell.
Cédric

10

Tổng hợp các câu trả lời đã có ở đây:

Kho lưu trữ cục bộ

git -c 'versionsort.suffix=-' tag --list --sort=-v:refname
  • suffix=-sẽ ngăn việc 2.0-rcđến "sau"2.0
  • --sort=- sẽ đặt số phiên bản cao nhất ở trên cùng.

Kho lưu trữ từ xa

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

Ưu điểm của điều này là không có đối tượng nào được tải xuống từ điều khiển từ xa.

Để biết thêm thông tin, hãy xem câu trả lời này .


Sử dụng rất thú vị của versionsort.suffix. +1.
VonC

2

Để sắp xếp ngược lại với sort -Vcách tiếp cận:

git tag -l | sort -V --reverse


1

Tôi đã viết một kịch bản shell đơn giản để đơn giản hóa công việc này.

#!/usr/bin/env bash

TAGS=$(git tag)
CODE=$?

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

exit $CODE

Tôi đã lưu nó như git-tagstrong của tôi $PATHvà chạy git tagsbất cứ khi nào tôi cần liệt kê các thẻ.


2
thẻ git | sắp xếp -V; thoát $ PIPESTATUS
luxigo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.