Cách đơn giản nhất để có thẻ gần đây nhất trong Git là gì?
git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag
đầu ra:
a
b
c
Tôi có nên viết một tập lệnh để lấy datetime của mỗi thẻ và so sánh chúng không?
Cách đơn giản nhất để có thẻ gần đây nhất trong Git là gì?
git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag
đầu ra:
a
b
c
Tôi có nên viết một tập lệnh để lấy datetime của mỗi thẻ và so sánh chúng không?
Câu trả lời:
Bạn có thể xem git describe
, cái mà gần với những gì bạn đang hỏi.
--abbrev=0
nó sẽ trả lại thẻ chú thích gần nhất
git describe --exact-match --abbrev=0
.
git describe --tags
và so sánh thẻ cuối cùng trong trang phát hành github
Để có được thẻ gần đây nhất:
git describe --tags
Để có được thẻ chú thích gần đây nhất :
git describe --abbrev=0
git describe
nói: --abbrev=<n> [...] An <n> of 0 will suppress long format, only showing the closest tag.
git describe --tags
git checkout $(git describe --abbrev=0 --tags)
Sẽ xuất thẻ của cam kết được gắn thẻ mới nhất trên tất cả các chi nhánh
git describe --tags $(git rev-list --tags --max-count=1)
TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
@ william-pursell
Để có được thẻ gần đây nhất, bạn có thể làm:
$ git for-Each-ref refs / tags --sort = -taggerdate --format = '% (refname)' --count = 1
Tất nhiên, bạn có thể thay đổi đối số đếm hoặc trường sắp xếp theo ý muốn. Có vẻ như bạn có thể có ý định hỏi một câu hỏi hơi khác, nhưng điều này không trả lời câu hỏi khi tôi diễn giải nó.
--sort=-authordate
và --sort=authordate
.
--sort=-taggerdate
. Đối với các thẻ authordate
và committerdate
trống (vì vậy vô dụng như các phím sắp xếp).
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1
thậm chí còn tốt hơn :)
--points-at=$SHA
sẽ cung cấp cho bạn thẻ cho một băm cam kết.
Còn cái này thì sao?
TAG=$(git describe $(git rev-list --tags --max-count=1))
Về mặt kỹ thuật, sẽ không nhất thiết phải có cho bạn thẻ mới nhất, nhưng cam kết mới nhất được gắn thẻ, có thể hoặc không phải là thứ bạn đang tìm kiếm.
--tags=<pattern>
trong rev-list
. Ví dụ: lấy thẻ phiên bản cuối cùnggit describe --tags $(git rev-list --tags='v[0-9].[0-9]*' --max-count=1)
git describe --tags $(git rev-list --tags --max-count=1)
Bạn có thể thực thi: git describe --tags $(git rev-list --tags --max-count=1)
đã nói ở đây: Làm thế nào để có được tên thẻ mới nhất?
git describe ...
trả lại thẻ trước đó?!)
--abbrev=0
câu trả lời và họ đã cắt bỏ một phần của thẻ mà tôi muốn.
"Gần đây nhất" có thể có hai ý nghĩa về mặt git.
Bạn có thể có nghĩa là "thẻ nào có ngày tạo mới nhất trong thời gian" và hầu hết các câu trả lời ở đây là dành cho câu hỏi đó. Về câu hỏi của bạn, bạn sẽ muốn trả lại thẻ c
.
Hoặc bạn có thể có nghĩa là "thẻ nào là gần nhất trong lịch sử phát triển với một số nhánh được đặt tên", thường là nhánh bạn đang ở , HEAD
. Trong câu hỏi của bạn, điều này sẽ trả về thẻa
.
Tất nhiên đây có thể khác nhau:
A->B->C->D->E->F (HEAD)
\ \
\ X->Y->Z (v0.2)
P->Q (v0.1)
Hãy tưởng tượng các nhà phát triển tag'ed Z
như v0.2
vào thứ hai, và sau đó tag'ed Q
như v0.1
hôm thứ Ba. v0.1
là gần đây hơn, nhưng v0.2
gần hơn trong lịch sử phát triển với HEAD, theo nghĩa là con đường mà nó đang đi bắt đầu tại một điểm gần hơn với HEAD.
Tôi nghĩ bạn thường muốn câu trả lời thứ hai này, gần hơn trong lịch sử phát triển. Bạn có thể tìm thấy điều đó bằng cách sử dụng git log v0.2..HEAD
vv cho mỗi thẻ. Điều này cung cấp cho bạn số lần xác nhận trên HEAD kể từ khi đường dẫn kết thúc tạiv0.2
chuyển hướng từ đường dẫn theo sau là HEAD.
Đây là tập lệnh Python thực hiện điều đó bằng cách lặp qua tất cả các thẻ đang chạy kiểm tra này, sau đó in ra thẻ với ít lần xác nhận nhất trên HEAD vì đường dẫn thẻ được chuyển hướng:
https://github.com/MacPython/terryfy/blob/master/git-closest-tag
git describe
thực hiện một cái gì đó hơi khác, trong đó nó theo dõi lại từ (ví dụ) ĐẦU để tìm thẻ đầu tiên nằm trên đường dẫn trong lịch sử từ HEAD. Theo thuật ngữ git, hãy git describe
tìm các thẻ "có thể truy cập" từ HEAD. Do đó, nó sẽ không tìm thấy các thẻ như thế v0.2
không nằm trên đường dẫn trở lại từ HEAD, mà là một đường dẫn được chuyển hướng từ đó.
git describe --tags
trả về thẻ cuối cùng có thể được nhìn thấy bởi chi nhánh hiện tại
git log --tags --no-walk --pretty="format:%d" | sed 2q | sed 's/[()]//g' | sed s/,[^,]*$// | sed 's ...... '
NẾU BẠN CẦN THÊM MỘT M TAG THỜI GIAN
(mô tả git - đôi khi đưa ra các giá trị băm sai, tôi không biết tại sao, nhưng đối với tôi - max-Count 2 không hoạt động)
đây là cách bạn có thể nhận danh sách với 2 tên thẻ mới nhất theo thứ tự thời gian đảo ngược, hoạt động hoàn hảo trên git 1.8.4. Đối với các phiên bản trước của git (như 1.7. *), Không có chuỗi "tag:" trong đầu ra - chỉ cần xóa cuộc gọi sed cuối cùng
Nếu bạn muốn có nhiều hơn 2 thẻ mới nhất - hãy thay đổi "sed 2q" này thành "sed 5q" hoặc bất cứ thứ gì bạn cần
Sau đó, bạn có thể dễ dàng phân tích từng tên thẻ thành biến.
git log --tags --no-walk --pretty="format:%D" | sed -nr '5q;s;^.*(tag: )([^,]*).*;\2;p'
trong đó %D
loại trừ các ()
ký tự xung quanh và sed
5q bắt đầu để lại 4 dòng trước 5, sau đó in ra tất cả các ký tự giữa 'tag: `và đầu tiên', '. Vì vậy, ... giả sử không có dấu phẩy được sử dụng trong thẻ, điều này hoạt động hoàn hảo.
Có gì sai với tất cả các đề xuất (ngoại trừ Matthew Brett lời giải thích của , đến ngày của bài trả lời này)?
Chỉ cần chạy bất kỳ lệnh nào được cung cấp bởi người khác trên lịch sử jQuery Git khi bạn ở điểm lịch sử khác nhau và kiểm tra kết quả với biểu diễn lịch sử gắn thẻ trực quan (Tôi đã làm đó là lý do tại sao bạn thấy bài đăng này):
$ git log --graph --all --decorate --oneline --simplify-by-decoration
Ngày nay, nhiều dự án thực hiện các bản phát hành (và do đó gắn thẻ) trong nhánh riêng biệt từ dòng chính .
Có lý do mạnh mẽ cho việc này. Chỉ cần nhìn vào bất kỳ dự án JS / CSS nào được thiết lập tốt. Đối với quy ước người dùng, họ mang các tệp phát hành nhị phân / rút gọn trong DVCS. Một cách tự nhiên như duy trì dự án bạn không muốn rác đường chính của bạn diff lịch sử với các đốm màu nhị phân vô dụng và thực hiện các cam kết hợp đồng xây dựng hiện vật ra khỏi đường chính .
Bởi vì Git sử dụng DAG chứ không phải lịch sử tuyến tính - thật khó để xác định số liệu khoảng cách nên chúng tôi có thể nói - ồ đó là rev gần nhất với tôi HEAD
!
Tôi bắt đầu hành trình của riêng mình (nhìn vào bên trong, tôi đã không sao chép những hình ảnh bằng chứng lạ mắt vào bài đăng dài này):
Thẻ gần nhất trong quá khứ liên quan đến phân nhánh trong Git là gì?
Hiện tại tôi có 4 định nghĩa hợp lý về khoảng cách giữa thẻ và sửa đổi với mức độ hữu dụng giảm dần:
HEAD
để hợp nhất cơ sở với thẻHEAD
và thẻTôi không biết cách tính chiều dài của con đường ngắn nhất .
Script rằng các thẻ loại theo ngày của cơ sở hợp nhất giữa HEAD
và gắn thẻ:
$ git tag \
| while read t; do \
b=`git merge-base HEAD $t`; \
echo `git log -n 1 $b --format=%ai` $t; \
done | sort
Nó có thể sử dụng trên hầu hết các dự án.
Script rằng các thẻ loại theo số vòng quay mà có thể truy cập từ TRỤ nhưng không thể truy cập từ thẻ:
$ git tag \
| while read t; do echo `git rev-list --count $t..HEAD` $t; done \
| sort -n
Nếu lịch sử dự án của bạn có ngày lạ trên các cam kết (vì các cuộc nổi loạn hoặc viết lại lịch sử khác hoặc một số moron quên thay pin BIOS hoặc các phép thuật khác mà bạn làm trong lịch sử), hãy sử dụng tập lệnh trên.
Đối với tùy chọn cuối cùng ( ngày của thẻ bất kể cơ sở hợp nhất ) để có danh sách các thẻ được sắp xếp theo ngày sử dụng:
$ git log --tags --simplify-by-decoration --pretty="format:%ci %d" | sort -r
Để biết ngày sửa đổi hiện tại, hãy sử dụng:
$ git log --max-count=1
Lưu ý rằng git describe --tags
có sử dụng trong các trường hợp riêng của mình nhưng không tìm thấy thẻ gần nhất dự kiến của con người trong lịch sử dự án .
LƯU Ý Bạn có thể sử dụng các công thức trên ở bất kỳ sửa đổi nào, chỉ cần thay thế HEAD
bằng những gì bạn muốn!
git tag -l ac* | tail -n1
Lấy thẻ cuối cùng với tiền tố "ac" . Ví dụ: thẻ có tên ac1.0.0
, hoặc ac1.0.5
. Các thẻ khác được đặt tên 1.0.0
, 1.1.0
sẽ bị bỏ qua.
git tag -l [0-9].* | tail -n1
Lấy thẻ cuối cùng, có char đầu tiên 0-9
. Vì vậy, những thẻ với char đầu tiêna-z
sẽ bị bỏ qua.
git tag --help # Help for `git tag`
git tag -l <pattern>
Liệt kê các thẻ có tên khớp với mẫu đã cho (hoặc tất cả nếu không có mẫu nào được cung cấp). Chạy "thẻ git" không có đối số cũng liệt kê tất cả các thẻ. Mẫu này là ký tự đại diện shell (nghĩa là được khớp bằng fnmatch (3)). Nhiều mẫu có thể được đưa ra; nếu bất kỳ trong số chúng phù hợp, thẻ được hiển thị.
tail -n <number> # display the last part of a file
tail -n1 # Display the last item
Với git tag --help
, về sort
tranh luận. Nó sẽ sử dụng lexicorgraphic order
theo mặc định, nếu thuộc tag.sort
tính không tồn tại.
Sắp xếp thứ tự mặc định cho giá trị được cấu hình cho biến tag.sort nếu nó tồn tại hoặc theo thứ tự từ điển khác. Xem git-config (1).
Sau google, có người nói git 2.8.0 hỗ trợ cú pháp theo sau.
git tag --sort=committerdate
git tag --sort=committerdate | tail -1
Các công việc sau đây cho tôi trong trường hợp bạn cần hai thẻ cuối cùng (ví dụ: để tạo nhật ký thay đổi giữa thẻ hiện tại và thẻ trước đó). Tôi đã thử nghiệm nó chỉ trong tình huống thẻ mới nhất là HEAD
.
PreviousAndCurrentGitTag=`git describe --tags \`git rev-list --tags --abbrev=0 --max-count=2\` --abbrev=0`
PreviousGitTag=`echo $PreviousAndCurrentGitTag | cut -f 2 -d ' '`
CurrentGitTag=`echo $PreviousAndCurrentGitTag | cut -f 1 -d ' '`
GitLog=`git log ${PreviousGitTag}..${CurrentGitTag} --pretty=oneline | sed "s_.\{41\}\(.*\)_; \1_"`
Nó phù hợp với nhu cầu của tôi, nhưng vì tôi không phải là phù thủy git, tôi chắc chắn rằng nó có thể được cải thiện hơn nữa. Tôi cũng nghi ngờ nó sẽ bị phá vỡ trong trường hợp lịch sử cam kết tiến lên. Tôi chỉ chia sẻ trong trường hợp nó giúp được ai đó.
Suy nghĩ đầu tiên của tôi là bạn có thể sử dụng git rev-list HEAD
, trong đó liệt kê tất cả các vòng quay theo thứ tự thời gian đảo ngược, kết hợp với git tag --contains
. Khi bạn tìm thấy một ref nơi git tag --contains
tạo ra một danh sách không trống, bạn đã tìm thấy (các) thẻ gần đây nhất.
Nếu bạn cần một lớp lót có tên thẻ mới nhất (theo ngày thẻ) trên nhánh hiện tại :
git for-each-ref refs/tags --sort=-taggerdate --format=%(refname:short) --count=1 --points-at=HEAD
Chúng tôi sử dụng điều này để đặt số phiên bản trong thiết lập.
Ví dụ đầu ra:
v1.0.0
Hoạt động trên Windows cũng vậy.
-bash: syntax error near unexpected token '('
--format="%(refname:short)"
) và bỏ qua phần --points-at=HEAD
đó hoạt động. Với công tắc cuối cùng đó, nó không trả về gì cả, tôi đoán vì tôi HEAD
không được gắn thẻ?
HEAD
không được gắn thẻ.
Đây là một chủ đề cũ, nhưng có vẻ như nhiều người đang thiếu câu trả lời đơn giản nhất, dễ nhất và đúng nhất cho câu hỏi của OP: để có được thẻ mới nhất cho chi nhánh hiện tại , bạn sử dụng git describe HEAD
. Làm xong.
Chỉnh sửa: bạn cũng có thể cung cấp bất kỳ tên gọi hợp lệ, thậm chí từ xa; tức là, git describe origin/master
sẽ cho bạn biết thẻ mới nhất có thể đạt được từ origin / master.
for-each-ref
lệnh ( stackoverflow.com/a/5261470/515973 ) và sự kết hợp của rev-list
và describe
( stackoverflow.com/a/7979255/515973 )
git describe branchname --tags
không hoạt động để tôi có được thẻ mới nhất trên chi nhánh (phiên bản git 2.12.2)
Để chỉ nhận được thẻ mới nhất trên tên chi nhánh / thẻ hiện tại có tiền tố với chi nhánh hiện tại, tôi đã phải thực hiện như sau
BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags --abbrev=0 $BRANCH^ | grep $BRANCH
Chủ chi nhánh:
git checkout master
BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags
--abbrev=0 $BRANCH^ | grep $BRANCH
master-1448
Chi nhánh tùy chỉnh:
git checkout 9.4
BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags
--abbrev=0 $BRANCH^ | grep $BRANCH
9.4-6
Và nhu cầu cuối cùng của tôi là tăng và lấy thẻ +1 để gắn thẻ tiếp theo.
BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags --abbrev=0 $BRANCH^ | grep $BRANCH | awk -F- '{print $NF}'
Đối với câu hỏi như đã hỏi,
Làm thế nào để có được tên thẻ mới nhất trong chi nhánh hiện tại
bạn muốn
git log --first-parent --pretty=%d | grep -m1 tag:
--first-parent
nói git log
không chi tiết bất kỳ lịch sử hợp nhất, --pretty=%d
nói chỉ hiển thị các trang trí tức là tên địa phương cho bất kỳ cam kết. grep -m1
nói "khớp chỉ một", vì vậy bạn chỉ nhận được thẻ gần đây nhất.
Không đề cập nhiều đến các thẻ không được quản lý so với các thẻ chú thích ở đây. 'mô tả' hoạt động trên các thẻ chú thích và bỏ qua các thẻ không được chú ý.
Điều này là xấu nhưng công việc được yêu cầu và nó sẽ không tìm thấy bất kỳ thẻ nào trên các nhánh khác (và không phải trên một thẻ được chỉ định trong lệnh: master trong ví dụ dưới đây)
Việc lọc nên được tối ưu hóa (hợp nhất), nhưng một lần nữa, điều này dường như với công việc.
git log --decorate --tags master |grep '^commit'|grep 'tag:.*)$'|awk '{print $NF}'|sed 's/)$//'|head -n 1
Các nhà phê bình hoan nghênh vì tôi sẽ sử dụng nó ngay bây giờ :)