Làm cách nào để chỉnh sửa thông báo thẻ hiện có trong git?


225

Chúng tôi có một số thẻ chú thích trong kho git của chúng tôi. Các thẻ cũ hơn có thông báo không có thật mà chúng tôi muốn cập nhật theo phong cách mới của chúng tôi.

% git tag -n1
v1.0 message
v1.1 message
v1.2 message
v2.0 Version 2.0 built on 15 October 2011.

Trong ví dụ này, chúng tôi muốn làm cho các tin nhắn v1.x trông giống như tin nhắn v2.0. Bất cứ ai biết làm thế nào chúng ta sẽ làm điều này?


2
Lưu ý: với Git 2.17 (quý 2 năm 2018), một đơn giản git tag -m "A message" --edit v1.0sẽ là đủ. Xem câu trả lời của tôi dưới đây
VonC


@VonC Đã thử và nhận fatal: tag 'v6.6.2' already existsbằng 2.17.0.
Josh Habdas

1
Bạn luôn có thể xóa thẻ trước đó và làm lại.
RoadRunner

Câu trả lời:


264

git tag <tag name> <tag name>^{} -f -m "<new message>"

Điều này sẽ tạo ra một thẻ mới có cùng tên (bằng cách ghi đè lên bản gốc).


7
Điều này có duy trì ngày của thẻ gốc không?
James M. Greene

16
Câu trả lời cho câu hỏi bình luận của riêng tôi: Vâng, nó không thay đổi ngày. :(
James M. Greene

10
Xem phần "Trên thẻ Backdating" trong git tag --help.
dahlbyk

6
Cũng cần lưu ý rằng bạn cũng có thể nối thêm nhiều tin nhắn (chúng được phân tách bằng một dòng mới - trên GitHub)git tag <tag name> <tag name> -f -m "<new message>" -m "<new message>" -m "<new message>"
Blair McMillan

5
@ChrisMorley xem câu trả lời của tôi bên dưới stackoverflow.com/a/23532519/603949 - nói tóm lại, hãy sử dụng <tag name>^{}khi bạn muốn thay thếold tag
Sungam

87

Để cập nhật một thông báo phức tạp, chỉ cần chỉ định tùy chọn thẻ chú thích bằng -ahoặc tùy chọn thẻ đã ký với -s:

git tag <tag name> <tag name>^{} -f -a

Điều này sẽ mở một trình soạn thảo với nội dung của thông điệp thẻ cũ của bạn .


39

git tag <tag name> <tag name>^{} -f -a

Đây là một cải tiến: không có ^{}nó sẽ tạo ra một đối tượng thẻ mới tham chiếu đối tượng thẻ cũ, trong đó cả hai sẽ có cùng tên thẻ.

<tag name>^{} sẽ giải quyết thẻ / tham chiếu cho đến khi tìm thấy hàm băm cam kết đầu tiên.


4
@BrentFoust, chỉ hoạt động khi đầu của bạn ở mức cam kết được gắn thẻ usage: git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]
Sungam

33

TL; DR

Bạn có thể làm điều này bằng cách xóa thẻ của bạn và tạo lại nó trong khi giả mạo ngày và tác giả:

> git tag -d <tag-name>
> [GIT_COMMITTER_DATE=<original-commit-date>] \
> [GIT_AUTHOR_NAME=<original-author-name>] \
> git tag <tag-name> [commit]

Toàn bộ câu chuyện:

Dựa trên câu trả lời của Sungram (ban đầu được đề xuất là bản chỉnh sửa):

1. Câu trả lời được chấp nhận

Đây là một cải tiến so với câu trả lời của AndyEric Hu . Câu trả lời của họ sẽ tạo ra một đối tượng thẻ mới tham chiếu đến đối tượng thẻ cũ và cả hai sẽ có cùng tên.

Để minh họa điều này, hãy xem xét những điều sau đây:

> git tag tag1 tag1 -f -a  # accepted answer
> git rev-list --objects -g --no-walk --all
[ example output: ]
6bdcc347fca041a5138f89fdf5276b3ebf9095d5
260ab7928d986472895b8c55e54569b3f3cb9517 tag1
a5797673f610914a45ef7ac051e3ee831a6e7c25 tag1
f22d6308c3cd330a3b0d86b9bf05562faf6b6f17

> git show tag1
tag tag1
Tagger: [tagger]
Date:   [date of updated tag]
[Updated description]

tag tag1
Tagger: [tagger]
Date:   [date of original tag]
[Original description]

[tagged commit details]

2. Sự cải tiến của Sungram

Thay vào đó, sử dụng <tag name>^{}làm đối số thứ hai của git tagý chí sẽ xóa tất cả các thẻ trước đó có cùng tên.

Xem xét việc tiếp tục phiên cuối cùng trước đó:

> git tag tag1 tag1^{} -f -a  # suggested improvement
> git rev-list --objects -g --no-walk --all
[ example output: ]
6bdcc347fca041a5138f89fdf5276b3ebf9095d5
75f02acacfd7d91d55b5bcfdfb1f00aebeed15e3 tag1
f22d6308c3cd330a3b0d86b9bf05562faf6b6f17 

> git show tag1
tag tag1
Tagger: [tagger]
Date:   [date of updated tag]
[Updated description]

[tagged commit details]

3. Lưu lại ngày tháng

Cuối cùng, nếu bạn muốn giữ ngày của thẻ gốc là ngày của thẻ được cập nhật, hãy sử dụng một số phép thuật awk (hoặc tương tự) hoặc chỉ dán ngày bạn muốn thay thế. Sau đây là sự thay thế cho ví dụ thứ hai (nếu không thì ngày ban đầu sẽ bị mất do ghi đè):

> GIT_COMMITTER_DATE="$(git show tag1 |                              # get info about the tag cascade including the date original of the original tag
> awk '{
>     if ($1 == "Date:") {
>         print substr($0, index($0,$3))
>     }
> }' |                                                               # extract all the dates from the info
> tail -2 | head -1)"                                               `# get the second to last date, as the last one is the commit date` \
> git tag tag1 tag1^{} -a -f                                         # finally, update the tag message, but save the date of the old one
>
> git rev-list --objects -g --no-walk --all
6bdcc347fca041a5138f89fdf5276b3ebf9095d5
e18c178f2a548b37799b100ab90ca785af1fede0 tag1
f22d6308c3cd330a3b0d86b9bf05562faf6b6f17
> git show tag1
tag tag1
Tagger: [tagger]
Date:   [date of original tag]
[Updated description]

[tagged commit details]

Người giới thiệu:

4. Tự làm

Ngoài ra, để cập nhật các thẻ, bạn chỉ cần xóa chúng và tạo lại chúng. Vì hóa ra việc cập nhật chỉ cần thêm một thẻ mới và làm cho nó trỏ đến thẻ cũ, hoặc thay vào đó, chỉ cần xóa hoàn toàn thẻ cũ và tạo một thẻ mới để trỏ đến cùng một cam kết.

Bạn có thể đạt được điều này bằng cách phát hành:

> git tag -d <tag-name>
> [GIT_COMMITTER_DATE=<original-commit-date>] \
> [GIT_AUTHOR_NAME=<original-author-name>] \
> git tag <tag-name> [commit]

Đây [optional]là một lĩnh vực tùy chọn; <required>là một lĩnh vực bắt buộc. Tất nhiên, bạn có thể thêm bất kỳ cờ nào sau git taglệnh mà bạn thường làm.


3
Cảm ơn bạn đã chỉ ra rằng "Câu trả lời của họ sẽ tạo ra một đối tượng thẻ mới"!
cwhsu

Trích dẫn Andreas Schwab : The tagger is controlled by the committer info. (...) GIT_COMMITTER_{NAME,EMAIL}. A tagger isn't really an author.
Ivan Vučica

11

Giải pháp của @Andy

git tag <tag-name> <tag-name> -f -a

sai . Sau đó, với

git show

lệnh, chúng ta sẽ thấy các thẻ stack có cùng tên.

Nó thêm một thẻ mới với cùng tên thẻ và thông báo mới tại cam kết <tag-name>. Nhưng nó không xóa thẻ cũ. Đây là trường hợp đặc biệt của lệnh này:

git tag [<commit> | <old-tag>] <tag-name>

Nhưng chỉ <old-tag>là giống với <tag-name>.


Giải pháp đúng là đơn giản, chỉ cần cập nhật thẻ là OK.

git tag <tag-name> -f -a

Hãy nhớ rằng, chỉ có một ở đây.

Nếu chúng ta muốn thay đổi thẻ, không phải HEAD, chúng ta cần thêm một <commit>đối số.

git tag <commit> <tag-name> -f -a

ĐÚNG! Bạn đúng. Cảm ơn đã chỉ ra rằng. Sau khi viết lại thẻ được chú thích một vài lần, tôi đã kiểm tra thẻ của mình git show <tag>và tôi thấy tất cả các phiên bản trước đó.
Manoel Vilela

Vấn đề là: nếu tôi cần cập nhật một số thẻ không HEAD, vượt qua phần bổ sung <commit>, thẻ đã mở sẽ trống. Tôi mong đợi thẻ cũ chỉ cần chỉnh sửa. Có cách nào không?
Manoel Vilela

Xin lưu ý rằng giải pháp của Andy đã được cập nhật kể từ khi bạn trả lời. Có lẽ sẽ rất tốt để bắt đầu câu trả lời của bạn với một thông báo nói rằng nó đã được sửa? Cũng có thể là lệnh của bạn git tag <commit> <tag-name> -f -acó <commit> và <tag-name> bị đảo ngược? Nó trông giống như vậy khi so sánh với các câu trả lời khác và các tài liệu, nhưng tôi không phải là chuyên gia.
Jacob Akkerboom

7

chúng tôi muốn làm cho các tin nhắn v1.x trông giống như tin nhắn v2.0

Với Git 2.17 (quý 2 năm 2018), sẽ có một cách khác để tạo thẻ mới với git tag <tag name> <tag name> -f -m "<new message>", vì tùy chọn " git tag" đã học rõ ràng " --edit" cho phép thông báo được cung cấp qua " -m" và " -F" được chỉnh sửa thêm.

Xem cam kết 9eed6e4 (06 tháng 2 năm 2018) của Nicolas Morey-Chaisemartin ( nmorey) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 05d290e , ngày 06 tháng 3 năm 2018)

tag: thêm --edittùy chọn

Thêm một --edittùy chọn cho phép sửa đổi các tin nhắn được cung cấp bởi -mhoặc -F, theo cách tương tự git commit --edit.


4
Bạn có thể vui lòng cung cấp một ví dụ mạch lạc bằng cách sử dụng --editđịa chỉ OP không?
Josh Habdas

@JoshHabdas thực sự, bạn cần thêm tùy chọn -f: --edit chỉ cho phép tin nhắn được chỉnh sửa thêm.
VonC

Cảm ơn. Vì vậy, nếu -fcờ cũng được thêm vào thì --editsẽ chỉnh sửa thông báo và sửa đổi dấu thời gian, phải không?
Josh Habdas

@JoshHabdas Đó là ý tưởng, vâng.
VonC

4

Bạn sẽ phải gắn thẻ một lần nữa, sử dụng -fcờ lực.

git tag v1.0 -f -m "actual message"

3
Giải pháp này cho rằng đầu git hiện tại ở phiên bản 1.0. Điều này có thể làm mọi thứ rối tung lên nếu không, vì nó thay đổi bản sửa đổi liên quan đến phiên bản 1.0. Giải pháp của Andy tránh được cạm bẫy này.
Eric O Lebigot

4

Sử dụng các câu trả lời ở trên, đây là bí danh của tôi .gitconfig. Thay thế thẻ hiện có và giữ nguyên ngày cam kết.

[alias]
    tm = "!sh -c 'f() { export GIT_COMMITTER_DATE=$(git log -1 --format=%ci $0); git tag -f -a $0 $0^{}; }; f '"

Cải tiến?


1
Cũng giữ tác giả: tag-amend = "!sh -c 'f() { name=$(git log -1 --format=%an $0); email=$(git log -1 --format=%ae $0); date=$(git log -1 --format=%ci $0); GIT_AUTHOR_NAME=\"${name}\" GIT_COMMITTER _NAME=\"${name}\" GIT_AUTHOR_EMAIL=\"${email}\" GIT_COMMITTER_EMAIL=\"${email}\" GIT_AUTHOR_DATE=\"${date}\" GIT_COMMITTER_DATE=\"${date}\" git tag -f -a $0 $0^{}; }; f '"
minterior

1
Chỉ cần thử điều này. Thay vì đưa thẻ thay thế cho tác giả và thông tin ngày từ chính thẻ, nó sử dụng thông tin từ cam kết mà thẻ trỏ tới. Điều này không nhất thiết giống nhau và trên thực tế, không giống nhau đối với trường hợp của chúng ta hầu hết thời gian. Chúng tôi có cơ sở hạ tầng nhiều repo và sử dụng các thẻ chú thích trong repo 'lõi' để ghi lại thông tin về các lần đẩy kéo dài nhiều repos. Vì vậy, về cốt lõi, cam kết được chỉ ra thậm chí có thể không phải là một phần của sự thúc đẩy thực sự. Thông tin trong thẻ chú thích sẽ phản ánh những cú đẩy thực sự trong các repos khác.
tanager

0

Nếu bạn đang sử dụng GUI như smartgit, hãy

  1. tạo lại cùng một thẻ ở cùng một vị trí với thông báo mới
  2. chọn "ghi đè thẻ hiện có"
  3. buộc đẩy thẻ vào kho lưu trữ ngược dòng
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.