ฉันจะแก้ไขข้อความแท็กที่มีอยู่ในคอมไพล์ได้อย่างไร


225

เรามีแท็กหมายเหตุประกอบหลายแท็กในที่เก็บ git ของเรา แท็กที่เก่ากว่ามีข้อความปลอมที่เราต้องการอัปเดตให้อยู่ในรูปแบบใหม่ของเรา

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

ในตัวอย่างนี้เราต้องการทำให้ข้อความ v1.x ดูเหมือนข้อความ v2.0 ใครรู้ว่าเราจะทำเช่นนี้?


2
หมายเหตุ: ด้วย Git 2.17 (Q2 2018) ความเรียบง่ายgit tag -m "A message" --edit v1.0ก็เพียงพอแล้ว ดูคำตอบของฉันด้านล่าง
VonC


@VonC พยายามมันและได้รับใช้fatal: tag 'v6.6.2' already exists 2.17.0
Josh Habdas

1
คุณสามารถลบแท็กก่อนหน้าและทำมันได้อีกครั้ง
RoadRunner

คำตอบ:


264

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

สิ่งนี้จะสร้างแท็กใหม่ด้วยชื่อเดียวกัน (โดยการเขียนทับต้นฉบับ)


7
สิ่งนี้จะรักษาวันที่ของแท็กเดิมหรือไม่
James M. Greene

16
คำตอบสำหรับคำถามความคิดเห็นของตัวเอง: ใช่มันไม่เปลี่ยนวันที่ :(
James M. Greene

10
ดูส่วน "backdating แท็ก" git tag --helpใน
dahlbyk

6
ควรสังเกตว่าคุณสามารถต่อท้ายข้อความหลายข้อความ (พวกเขาถูกคั่นด้วยบรรทัดใหม่ - บน GitHub)git tag <tag name> <tag name> -f -m "<new message>" -m "<new message>" -m "<new message>"
Blair McMillan

5
@ChrisMorley ดูที่คำตอบของฉันด้านล่างstackoverflow.com/a/23532519/603949 - ในระยะสั้นใช้<tag name>^{}เมื่อคุณต้องการแทนที่old tag
Sungam

87

หากต้องการอัปเดตข้อความที่ซับซ้อนเพียงระบุตัวเลือกแท็กหมายเหตุประกอบกับ-aหรือตัวเลือกแท็กที่เซ็นชื่อด้วย-s:

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

นี้จะเปิดตัวแก้ไขด้วยเนื้อหาของข้อความแท็กเก่าของคุณ


39

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

นี่คือการปรับปรุง: หากไม่มี^{}มันจะสร้างวัตถุแท็กใหม่ที่อ้างอิงถึงวัตถุแท็กเก่าโดยที่ทั้งคู่จะมีชื่อแท็กเดียวกัน

<tag name>^{} จะแก้ไขแท็ก / การอ้างอิงจนกว่าจะพบแฮชการส่งครั้งแรก


4
@BrentFoust ที่ใช้งานได้เฉพาะเมื่อหัวของคุณอยู่ที่การติดแท็ก usage: git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]
Sungam

33

TL; DR

คุณสามารถทำได้โดยลบแท็กและสร้างใหม่ในขณะที่ปลอมแปลงวันที่และผู้แต่ง:

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

เรื่องราวทั้งหมด:

การสร้างคำตอบของSungram (แต่เดิมเสนอเป็นการแก้ไข):

1. คำตอบที่ยอมรับ

นี่เป็นการปรับปรุงคำตอบของAndyและEric Hu คำตอบของพวกเขาจะสร้างวัตถุแท็กใหม่ที่อ้างอิงถึงวัตถุแท็กเก่าและทั้งสองจะมีชื่อเดียวกัน

เพื่อแสดงสิ่งนี้ให้พิจารณาสิ่งต่อไปนี้:

> 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. การปรับปรุงของ Sungram

การใช้<tag name>^{}เป็นอาร์กิวเมนต์ที่สองของgit tagจะแทนที่แท็กก่อนหน้าทั้งหมดด้วยชื่อเดียวกัน

พิจารณาความต่อเนื่องของเซสชันเทอร์มินัลก่อนหน้า:

> 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. บันทึกวันที่

สุดท้ายหากคุณต้องการเก็บวันที่ของแท็กเดิมเป็นวันที่ของแท็กที่อัปเดตให้ใช้เวทย์ awk (หรือคล้ายกัน) หรือวางวันที่ที่คุณต้องการแทน ต่อไปนี้เป็นสิ่งทดแทนสำหรับตัวอย่างที่สอง (มิฉะนั้นวันที่ดั้งเดิมจะหายไปเนื่องจากการแทนที่):

> 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]

อ้างอิง:

4. DIY

หรืออีกวิธีหนึ่งในการอัปเดตแท็กคุณสามารถลบและสร้างใหม่ได้อีกครั้ง เนื่องจากปรากฎว่าการอัปเดตเพิ่งเพิ่มแท็กใหม่และทำให้มันชี้ไปที่แท็กเก่าหรือมิฉะนั้นเพียงแค่ลบแท็กเก่าโดยปริยายและสร้างแท็กใหม่เพื่อชี้ไปที่การกระทำเดียวกัน

คุณสามารถทำได้โดยการออก:

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

นี่[optional]คือฟิลด์ตัวเลือก; <required>เป็นฟิลด์บังคับ แน่นอนคุณสามารถเพิ่มการตั้งค่าสถานะใด ๆ หลังจากgit tagคำสั่งที่คุณปกติจะ


3
ขอบคุณที่ชี้ให้เห็นว่า "คำตอบของพวกเขาจะสร้างแท็กวัตถุใหม่"!
cwhsu

Quoting 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

@ โซลูชั่นของ Andy

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

เป็นที่ไม่ถูกต้อง หลังจากนั้นด้วย

git show

คำสั่งเราจะเห็นสแต็กแท็กที่มีชื่อเดียวกัน

<tag-name>มันเพิ่มแท็กใหม่ที่มีชื่อแท็กเดียวกันและข้อความใหม่ที่มอบความไว้วางใจ แต่จะไม่ลบแท็กเก่าออก มันเป็นกรณีพิเศษของคำสั่งนี้:

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

แต่เป็นเหมือนกันกับ<old-tag><tag-name>


โซลูชันที่ถูกต้องนั้นง่ายเพียงแค่อัปเดตแท็กก็โอเค

git tag <tag-name> -f -a

โปรดจำไว้ว่าเพียงหนึ่ง ที่นี่

หากเราต้องการเปลี่ยนแท็กซึ่งไม่ใช่HEADเราจำเป็นต้องมี<commit>อาร์กิวเมนต์เพิ่มเติม

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

ใช่! คุณถูก. ขอบคุณสำหรับการชี้ว่า หลังจากเขียนแท็กคำอธิบายประกอบอีกสองสามครั้งฉันตรวจสอบแท็กด้วยgit show <tag>และฉันเห็นรุ่นก่อนหน้าทั้งหมด
Manoel Vilela

ปัญหาคือ: ถ้าฉันต้องการอัปเดตแท็กที่ไม่HEADผ่านการเพิ่ม<commit>แท็กที่เปิดอยู่นั้นว่างเปล่า ฉันคาดว่าแท็กเก่าจะเพิ่งแก้ไข มีวิธีหรือไม่
Manoel Vilela

โปรดทราบว่าโซลูชั่นของ Andy ได้รับการปรับปรุงตั้งแต่ที่คุณตอบ อาจเป็นการดีถ้าคุณเริ่มตอบด้วยข้อความที่บอกว่าได้รับการแก้ไขแล้วหรือไม่? เป็นไปได้ไหมว่าคำสั่งของคุณgit tag <commit> <tag-name> -f -aมี <commit> และ <tag-name> กลับด้าน ดูเหมือนว่าเมื่อเปรียบเทียบกับคำตอบและเอกสารอื่น ๆ แต่ฉันไม่เชี่ยวชาญ
Jacob Akkerboom

7

เราต้องการทำให้ข้อความ v1.x ดูเหมือนข้อความ v2.0

ด้วย Git 2.17 (Q2 2018) จะมีทางเลือกอื่นในการสร้างแท็กใหม่ด้วยgit tag <tag name> <tag name> -f -m "<new message>"เนื่องจาก " git tag" เรียนรู้ตัวเลือกที่ชัดเจน " --edit"ที่ช่วยให้ข้อความที่ได้รับผ่าน " -m" และ " -F" ถูกแก้ไขเพิ่มเติม

ดูกระทำ 9eed6e4 (6 กุมภาพันธ์ 2018) โดยนิโคลัส Morey-Chaisemartin (nmorey )
(ผสานโดยJunio ​​C Hamano - gitster-ในการกระทำ 05d290e , 06 Mar 2018)

tag: เพิ่ม--editตัวเลือก

เพิ่ม--editตัวเลือกซึ่งจะช่วยให้การปรับเปลี่ยนข้อความให้โดย-mหรือ-Fวิธีเดียวกันgit commit --editไม่


4
คุณช่วยยกตัวอย่างที่เชื่อมโยงกันโดยใช้--editที่อยู่ OP ได้ไหม
Josh Habdas

@JoshHabdas จริง ๆ แล้วคุณต้องเพิ่มตัวเลือก -f: - แก้ไขเฉพาะช่วยให้ข้อความที่จะแก้ไขเพิ่มเติม
VonC

ขอบคุณ ดังนั้นหาก-fมีการเพิ่มการตั้งค่าสถานะจากนั้น--editจะแก้ไขข้อความและแก้ไขการประทับเวลาใช่ไหม
Josh Habdas

@JoshHabdas นั่นคือความคิดใช่
VonC

4

คุณจะต้องติดแท็กอีกครั้งโดยใช้-fธงบังคับ

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

3
วิธีแก้ปัญหานี้สมมติว่าส่วนหัว git ปัจจุบันเป็นเวอร์ชัน 1.0 สิ่งนี้อาจทำให้เกิดความยุ่งยากหากไม่เป็นเช่นนั้นเพราะจะเปลี่ยนแปลงการแก้ไขที่เกี่ยวข้องกับรุ่น 1.0 ทางออกของ Andy หลีกเลี่ยงหลุมพรางนี้
Eric O Lebigot

4

.gitconfigการใช้คำตอบดังกล่าวข้างต้นนี้เป็นนามแฝงหนึ่งซับของฉัน แทนที่แท็กที่มีอยู่และเก็บรักษาวันที่ส่งมอบ

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

ปรับปรุง?


1
นอกจากนี้ยังช่วยให้ผู้เขียน: 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
เพิ่งลองสิ่งนี้ แทนที่จะให้แท็กการแทนที่ผู้เขียนและข้อมูลวันที่จากแท็กตัวเองมันจะใช้ข้อมูลจากการกระทำแท็กชี้ไปที่ สิ่งนี้ไม่จำเป็นต้องเหมือนกันและในความเป็นจริงนั้นไม่เหมือนกันสำหรับกรณีของเราส่วนใหญ่ เรามีโครงสร้างพื้นฐานแบบหลาย repo และใช้แท็กที่มีคำอธิบายประกอบใน repo 'core' เพื่อบันทึกข้อมูลเกี่ยวกับการพุชที่ครอบคลุมหลาย repos ดังนั้นในแกนกลางการกระทำที่ชี้ไปที่อาจไม่ได้เป็นส่วนหนึ่งของการผลักดันที่แท้จริง ข้อมูลในแท็กที่มีคำอธิบายประกอบควรสะท้อนถึงการผลักดันที่แท้จริงใน repos อื่น ๆ
ฟอกหนัง

0

หากคุณใช้ GUI เช่นsmartgitเพียงแค่

  1. สร้างแท็กเดียวกันอีกครั้งที่ตำแหน่งเดียวกันด้วยข้อความใหม่
  2. เลือก "เขียนทับแท็กที่มีอยู่"
  3. บังคับให้กดแท็กไปยังที่เก็บข้อมูลต้นน้ำ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.