Làm thế nào để bạn đổi tên một thẻ Git?


1219

Hôm nay tôi đã xem qua nhật ký của một dự án và nhận ra rằng tôi đã lấy một thẻ tên một thời gian trước đây. Có cách nào để đổi tên thẻ không? Google đã không bật lên bất cứ điều gì hữu ích.

Tôi nhận ra rằng tôi có thể kiểm tra phiên bản được gắn thẻ và tạo một thẻ mới, tôi thậm chí đã thử nó. Nhưng điều đó dường như tạo ra một đối tượng thẻ không hoàn toàn đúng. Cho một,

git tag -l

liệt kê nó ra khỏi trật tự liên quan đến tất cả các thẻ khác. Tôi không biết điều đó có ý nghĩa gì không, nhưng nó khiến tôi tin rằng đối tượng thẻ mới không hoàn toàn như tôi muốn. Tôi có thể sống với điều đó, bởi vì tôi thực sự chỉ quan tâm rằng tên thẻ phù hợp với tài liệu, nhưng tôi muốn làm điều đó "đúng", giả sử có một cách đúng đắn để làm điều này.


Bạn đã sử dụng cùng một lời gọi, tức là nếu thẻ cũ được chú thích / thẻ đã ký, thì thẻ mới cũng thuộc loại này hay là thẻ nhẹ?
Jakub Narębski

1
Cả thẻ cũ không chính xác và thẻ mới mong muốn, nên được chú thích và không dấu. Thẻ cũ đã được tạo bằng 'thẻ git -a bad_tag_name', vì vậy tôi muốn làm gì đó dọc theo dòng 'thẻ git -a good_tag_name'.
Brandon Fosdick

Tôi nên chỉ ra rằng tôi cũng muốn quá trình đổi tên thẻ ma thuật này để duy trì chú thích khỏi thẻ được đổi tên. Trên thực tế, tôi thực sự muốn thay đổi chỉ tên và không có gì khác.
Brandon Fosdick

7
git log --oneline --decorate --graphlà hữu ích khi làm sạch thẻ.
Joel Purra

Bạn có thể đổi tên một thẻ trong một dòng: xem câu trả lời của tôi bên dưới
VonC

Câu trả lời:


2039

Đây là cách tôi đổi tên một thẻ oldthành new:

git tag new old
git tag -d old
git push origin :refs/tags/old
git push --tags

Dấu hai chấm trong lệnh đẩy sẽ xóa thẻ khỏi kho lưu trữ từ xa. Nếu bạn không làm điều này, Git sẽ tạo thẻ cũ trên máy của bạn khi bạn kéo.

Cuối cùng, hãy chắc chắn rằng những người dùng khác xóa thẻ đã xóa. Hãy nói với họ (đồng nghiệp) để chạy lệnh sau:

git pull --prune --tags

Lưu ý rằng nếu bạn đang thay đổi thẻ chú thích , bạn cần đảm bảo rằng tên thẻ mới đang tham chiếu cam kết cơ bản chứ không phải đối tượng thẻ chú thích cũ mà bạn sắp xóa. Do đó, sử dụng git tag -a new old^{}thay vì git tag new old(điều này là do các thẻ chú thích là các đối tượng trong khi các thẻ nhẹ thì không, thông tin thêm trong câu trả lời này ).


19
nếu thẻ được chú thích thì thẻ mới sẽ không có thông báo của thẻ cũ, nhưng đó là một thông tin hữu ích
NickSoft

25
@NickSoft, tôi chỉ làm như trên với các thẻ chú thích. Các tin nhắn đã được sao chép từ cũ sang mới chỉ tốt. Có lẽ tôi có một phiên bản mới hơn của git?
katyhuff

25
git push origin :refs/tags/oldTôi có thể đơn giản hóa git push origin :old.
Jesse Glick

25
Tôi sẽ đề nghị thay đổi "git đẩy --tags" để rõ ràng hơn với thẻ này "git đẩy nguồn gốc refs / tags / new". Bạn không muốn vô tình đẩy các thẻ khác.
chrish

11
Cảnh báo : Sử dụng git tag new oldsẽ tạo thẻ chỉ vào thẻ cũ, không phải cam kết của thẻ cũ. (Xem Tại sao tôi không thể kiểm tra thẻ của mình từ GUI Git? )
Stevoisiak

297

Câu hỏi ban đầu là làm thế nào để đổi tên thẻ, rất dễ: đầu tiên tạo MỚI dưới dạng bí danh của OLD: git tag NEW OLDsau đó xóa OLD : git tag -d OLD.

Câu trích dẫn liên quan đến "cách Git" và (trong) sự tỉnh táo là không có cơ sở, bởi vì nó nói về việc giữ nguyên tên thẻ, nhưng làm cho nó đề cập đến một trạng thái kho lưu trữ khác.


3
Trả lời ở trên là hơi thích hợp hơn vì nó bao gồm các git push origindoanh nghiệp.
Roly

Cách dễ nhất, làm việc tuyệt vời để đổi tên thẻ phát hành trước đó được tạo bằng Gitflow
RousseauAlexandre

5
Cảnh báo : Sử dụng git tag new oldsẽ tạo thẻ chỉ vào thẻ cũ, không phải cam kết của thẻ cũ. (Xem Tại sao tôi không thể kiểm tra thẻ của mình từ GUI Git? )
Stevoisiak

118

Ngoài các câu trả lời khác:

Trước tiên, bạn cần xây dựng một bí danh của tên thẻ , chỉ vào cam kết ban đầu:

git tag new old^{}

Sau đó, bạn cần xóa cái cũ cục bộ :

git tag -d old

Sau đó xóa thẻ trên (các) vị trí từ xa của bạn:

# Check your remote sources:
git remote -v
# The argument (3rd) is your remote location,
# the one you can see with `git remote`. In this example: `origin`
git push origin :refs/tags/old

Cuối cùng, bạn cần thêm thẻ mới của bạn vào vị trí từ xa. Cho đến khi bạn thực hiện điều này, (các) thẻ mới sẽ không được thêm vào:

git push origin --tags

Lặp lại điều này cho mọi địa điểm từ xa.

Xin lưu ý, về những tác động của việc thay đổi Thẻ Git đối với người tiêu dùng gói!


Cảnh báo : Sử dụng git tag new oldsẽ tạo thẻ chỉ vào thẻ cũ, không phải cam kết của thẻ cũ. (Xem Tại sao tôi không thể kiểm tra thẻ của mình từ GUI Git? )
Stevoisiak

1
@StevenVascellaro Cảm ơn đã liên kết. Lần sau, vui lòng gửi chỉnh sửa - trả lời cũng là một nỗ lực của cộng đồng. Cảm ơn.
kaiser

Tôi đã không thực hiện chỉnh sửa vì tôi chưa tự kiểm tra mã. (Lưu ý ngày gửi về câu hỏi được liên kết)
Stevoisiak

Khi chúng tôi làm git tag new old^{}, sau đó chúng tôi không cần git tag new_tag_name old_tag_name(bước đầu tiên).
Số945

28

Nếu nó được xuất bản, bạn không thể xóa nó (mà không có nguy cơ bị dính nhựa đường và có lông, đó là). 'Cách Git' là để làm:

Điều lành mạnh. Chỉ cần thừa nhận bạn đã làm hỏng, và sử dụng một tên khác. Những người khác đã nhìn thấy một tên thẻ và nếu bạn giữ cùng một tên, bạn có thể gặp tình huống hai người có "phiên bản X", nhưng họ thực sự có chữ "X" khác nhau. Vì vậy, chỉ cần gọi nó là "X.1" và được thực hiện với nó.

Ngoài ra,

Điều điên rồ. Bạn thực sự muốn gọi phiên bản mới là "X", mặc dù những người khác đã nhìn thấy phiên bản cũ. Vì vậy, chỉ cần sử dụng lại git-tag -f, như thể bạn đã không xuất bản cái cũ.

Thật điên rồ vì:

Git không (và không nên) thay đổi thẻ phía sau người dùng. Vì vậy, nếu ai đó đã có thẻ cũ, thực hiện thao tác git-pull trên cây của bạn không nên làm cho chúng ghi đè lên thẻ cũ.

Nếu ai đó có thẻ phát hành từ bạn, bạn không thể thay đổi thẻ cho họ bằng cách cập nhật thẻ của riêng bạn. Đây là một vấn đề bảo mật lớn, trong đó mọi người PHẢI có thể tin tưởng vào tên thẻ của họ. Nếu bạn thực sự muốn làm điều điên rồ, bạn cần phải tin vào nó, và nói với mọi người rằng bạn đã làm hỏng.

Tất cả lịch sự của các trang người đàn ông .


6
Hoặc bạn có thể gắn thẻ (với tên chính xác) thẻ được đặt tên không chính xác này.
Jakub Narębski

6
Cảm ơn, tôi đã qua trang người đàn ông đó một triệu lần rồi. May mắn là thẻ xấu đã không được công bố ở bất cứ đâu. Ngay cả nếu đó là, đây là một dự án nội bộ và tôi là nhà phát triển duy nhất (hiện tại). Tôi nghĩ rằng tôi khá an toàn từ cả tarring và Feathering, nhưng chỉ khi tôi có thể có được repo để phù hợp với các tài liệu.
Brandon Fosdick

Đôi khi tôi sử dụng thẻ cho tài liệu tham khảo cá nhân của riêng tôi. Ví dụ. nó có thể là thẻ 'ok_jb'. Tôi sử dụng điều này, bởi vì một số người tôi làm việc không thể xây dựng cho nền tảng của tôi, vì vậy đôi khi sẽ có lỗi xây dựng. Sau đó tôi có thể nhanh chóng có được một phiên bản xây dựng, bằng cách kiểm tra thẻ đó. Khi các nguồn mới xây dựng, tôi chỉ cần di chuyển thẻ hoặc đổi tên nó thành các bản dựng ##, trong đó ## là một số (tùy thuộc vào dự án). Tôi cũng có thể nhấn mạnh khi một tính năng đặc biệt được giới thiệu, bằng cách thêm một thẻ.

7
Câu trả lời kém. "Đừng làm điều đó" không bao giờ là câu trả lời chính xác cho "Làm thế nào tôi có thể làm điều đó?". Người dùng không hỏi liệu bạn có nghĩ rằng đó là một ý tưởng tốt để làm điều đó hoặc nếu mọi người sẽ thích điều đó. Nếu ai đó hỏi "Làm thế nào tôi có thể cắt tay tôi", hãy nói cho anh ấy biết làm thế nào hoặc để anh ấy một mình nhưng anh ấy sẽ không cần ai đó nói với anh ấy rằng cắt tay có thể không phải là một ý tưởng tuyệt vời. Và bạn có thể làm điều đó. Bạn có thể thêm một thẻ mới và xóa thẻ cũ, về mặt kỹ thuật là có thể, ngay cả trong một kho lưu trữ từ xa.
Mecki

5
Điều này dường như trả lời câu hỏi "Làm thế nào để tôi tạo một điểm thẻ hiện có cho một phiên bản khác?" thay vì câu hỏi của OP, "Làm cách nào để đổi tên thẻ?" Cũng không rõ làm thế nào để nói với những người mà bạn nhắn tin sẽ giải quyết vấn đề (mặc dù nói chung đó là một ý tưởng tốt).
LarsH

25

Trang wiki này có một lớp lót thú vị này, nhắc nhở chúng ta rằng chúng ta có thể đẩy một số ref :

git push origin <refs/tags/old-tag>:<refs/tags/new-tag> :<refs/tags/old-tag> && git tag -d <old-tag>

và yêu cầu các nhân bản khác làm git pull --prune --tags

Vì vậy, ý tưởng là để thúc đẩy:

  • <new-tag>cho mọi cam kết được tham chiếu bởi <old-tag> : <refs/tags/old-tag>:<refs/tags/new-tag>,
  • xóa <old-tag> ::<refs/tags/old-tag>

Xem ví dụ " Thay đổi quy ước đặt tên của các thẻ trong kho git? ".


Điều này có bảo tồn các chú thích?
Brandon Fosdick

1
Coi chừng việc này để lại tên thẻ gốc trong chú thích cho các thẻ chú thích !! Tôi không chắc nếu điều đó thực sự ngụ ý bất cứ điều gì, ít nhất là trong các phiên bản hiện tại.
gbr

@gbr Bạn có thể chỉnh sửa câu trả lời bằng một ví dụ cho thấy "tên thẻ gốc" còn lại trong chú thích không?
VonC

1
@VonC Tôi không chắc là tôi hiểu những gì bạn đang hỏi; có thể tôi không rõ: các đối tượng chú thích chứa trường thẻ được đặt thành tên của thẻ, bạn có thể thấy nó với git cat-file -p <tag>; với phương thức của bạn trên hệ thống của tôi, tôi nhận được thẻ 'đổi tên' ref ( <new-tag>), nhưng trường thẻ của nó vẫn còn <old-tag>.
gbr

3
@gbr Không phải là những gì OP muốn? Ông đã đề cập "Tôi nên chỉ ra rằng tôi cũng muốn quá trình đổi tên thẻ ma thuật này để duy trì chú thích khỏi thẻ được đổi tên. Thực ra, tôi thực sự muốn thay đổi tên và không có gì khác" ( stackoverflow.com/questions/1028649/ how-do-you-rename-a-git-tag /
Mạnh

25

Để thêm vào các câu trả lời khác, tôi đã thêm một bí danh để thực hiện tất cả trong một bước, với cảm giác lệnh di chuyển * nix quen thuộc hơn. Đối số 1 là tên thẻ cũ, đối số 2 là tên thẻ mới.

[alias]
    renameTag = "!sh -c 'set -e;git tag $2 $1; git tag -d $1;git push origin :refs/tags/$1;git push --tags' -"

Sử dụng:

git renametag old new

Điều này không hiệu quả với tôi, vì nó thất bại tại !sh(câu hỏi liên quan đến Windows Git), tuy nhiên, sau khi cập nhật định dạng thành sau, nó đã hoạt động : renametag = "!f() { git tag $2 $1; git tag -d $1; git push origin :refs/tags/$1; git push --tags; }; f".
Nắng Patel

10

Thực hiện theo cách tiếp cận 3 bước cho một hoặc một vài thẻ.

Bước 1: Xác định ID cam kết / đối tượng của thẻ cam kết mà thẻ hiện tại đang trỏ đến

     command: git rev-parse <tag name>
     example: git rev-parse v0.1.0-Demo
     example output: db57b63b77a6bae3e725cbb9025d65fa1eabcde

Bước 2: Xóa thẻ khỏi kho lưu trữ

     command: git tag -d <tag name>
     example: git tag -d v0.1.0-Demo
     example output: Deleted tag 'v0.1.0-Demo' (was abcde)

Bước 3: Tạo thẻ mới trỏ đến cùng id id như thẻ cũ đã trỏ đến

     command: git tag -a <tag name>  -m "appropriate message" <commit id>
     example: git tag -a v0.1.0-full  -m "renamed from v0.1.0-Demo" db57b63b77a6bae3e725cbb9025d65fa1eabcde
     example output: Nothing or basically <No error>

Khi git cục bộ đã sẵn sàng với thay đổi tên thẻ, những thay đổi này có thể được đẩy trở lại nguồn gốc để người khác thực hiện.


Đó là thiếu các bước để đẩy lùi thẻ đã xóa: git push origin :refs/tags/v0.1.0-Demovà để đẩy lùi các thẻ (với những thứ đang chờ xử lý khác)git push --tags
Star Wolf

6

Đối với những người thích phiêu lưu, nó có thể được thực hiện trong một lệnh:

mv .git/refs/tags/OLD .git/refs/tags/NEW

7
Điều này sẽ không hoạt động nếu ref của bạn được đóng gói, tức là nếu bạn chạy git gcgần đây
trước

2
Điều này cũng sẽ chỉ ảnh hưởng đến repo địa phương. Nếu bạn có một cấu hình từ xa, tôi không chắc những tác động tiêu cực này có thể gây ra. Tôi không khuyên bạn nên tiếp cận phương pháp này.
Therealklanni

1
Cũng lưu ý rằng đối với các thẻ chú thích, điều này có thể sẽ còn rắc rối hơn, vì các đốm 'chú thích' trong số những thứ khác chứa tên gốc của thẻ. Trên thực tế tôi không chắc chắn nếu điều đó được sử dụng bởi bất cứ điều gì (hy vọng ít nhất là bằng thẻ xác minh), nhưng tôi sẽ không có cơ hội.
gbr

1
@gbr Điều này hoạt động tốt. (Tất nhiên, lưu ý của @forivall là phải được tính đến.) Thủ thuật này đã được sử dụng ồ ạt cho các lứa tuổi trong hệ thống xây dựng ALT Sisyphus. Xem cách các nguồn cho một gói được lưu trữ, ví dụ: git.altlinux.org/gears/g/gear.git . Các thẻ có thể đọc được như 2.0.7-alt1 là các thẻ đã ký được các nhà bảo trì gửi đến hệ thống xây dựng. Các thẻ mật mã gb-sisyphus-task164472.200 được hệ thống xây dựng đặt ở đó để theo dõi ID nhiệm vụ đã xây dựng và xuất bản pkg từ nguồn này. Chúng là những bản sao câm ( cp), với thông điệp của người bảo trì chưa được xử lý.
imz - Ivan Zakharyaschev

@ imz - IvanZakharyaschev Rất tốt để biết, tôi sẽ không đặt quá nhiều niềm tin mặc dù điều đó sẽ không làm phát sinh vấn đề trong tương lai, với một số sản phẩm; không có đặc điểm kỹ thuật thực sự của định dạng kho git và tương tác dự kiến, vì vậy khi khả thi tôi sẽ cố gắng làm mọi thứ sạch sẽ theo cách ít gây ngạc nhiên nhất
gbr

3

Bất kể các vấn đề liên quan đến việc đẩy thẻ và đổi tên thẻ đã được đẩy, trong trường hợp thẻ để đổi tên là chú thích , trước tiên bạn có thể sao chép nó nhờ vào dòng lệnh đơn dòng sau:

git tag -a -m "`git cat-file -p old_tag | tail -n +6`" new_tag old_tag^{}

Sau đó, bạn chỉ cần xóa thẻ cũ:

git tag -d old_tag

Tôi tìm thấy dòng lệnh này nhờ hai câu trả lời sau:

Chỉnh sửa:
Gặp phải sự cố khi sử dụng đồng bộ hóa cài đặt thẻ tự động fetch.pruneTags=true(như được mô tả trong https://stackoverflow.com/a/49215190/7009806 ), cá nhân tôi đề nghị trước tiên sao chép thẻ mới trên máy chủ và sau đó xóa thẻ cũ. Bằng cách đó, thẻ mới sẽ không bị xóa ngẫu nhiên khi xóa thẻ cũ và đồng bộ hóa các thẻ muốn xóa thẻ mới chưa có trên máy chủ . Vì vậy, ví dụ, tất cả chúng ta cùng nhau nhận được:

git tag -a -m "`git cat-file -p old_tag | tail -n +6`" new_tag old_tag^{}
git push --tags
git tag -d old_tag
git push origin :refs/tags/old_tag

3

Bạn cũng có thể đổi tên các thẻ từ xa mà không cần kiểm tra chúng, bằng cách sao chép thẻ / nhánh cũ thành một tên mới và xóa tên cũ, trong một git pushlệnh duy nhất .

Đổi tên thẻ từ xa / Chi nhánh từ xa → chuyển đổi thẻ: (Lưu ý :refs/tags/:)

git push <remote_name> <old_branch_or_tag>:refs/tags/<new_tag> :<old_branch_or_tag>

Đổi tên chi nhánh từ xa / Thẻ từ xa → chuyển đổi chi nhánh: (Lưu ý :refs/heads/:)

git push <remote_name> <old_branch_or_tag>:refs/heads/<new_branch> :<old_branch_or_tag>

Đầu ra đổi tên một thẻ từ xa:

D:\git.repo>git push gitlab App%2012.1%20v12.1.0.23:refs/tags/App_12.1_v12.1.0.23 :App%2012.1%20v12.1.0.23

Total 0 (delta 0), reused 0 (delta 0)
To https://gitlab.server/project/repository.git
 - [deleted]               App%2012.1%20v12.1.0.23
 * [new tag]               App%2012.1%20v12.1.0.23 -> App_12.1_v12.1.0.23
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.