Git dalındaki bir etiketi farklı bir işleme nasıl taşıyabilirim?


858

Ana dalda şöyle adlandırılan bir etiket oluşturdum v0.1:

git tag -a v0.1

Ama sonra 0.1 sürümü için master'a birleştirmem gereken bazı değişiklikler olduğunu fark ettim, bu yüzden yaptım. Ama şimdi benim v0.1etiketim (post-it not benzetmesini çağırmak için) yanlış taahhütte kaldı. Onun en son ustalık taahhüdüne takılı kalmasını istiyorum, ama bunun yerine en son ikinci ustalık taahhüdüne yapıştı.

Bunu en son ustalık taahhüdüne nasıl taşıyabilirim?

Yanıtlar:


1199

Şu -fseçeneği kullanın git tag:

-f
--force

    Replace an existing tag with the given name (instead of failing)

Büyük olasılıkla , açıklamalı olmayan bir etiket yerine açıklamalı bir etiket oluşturmak için -fbirlikte kullanmak istersiniz -a.

Misal

  1. Basmadan önce herhangi bir uzaktan kumandadaki etiketi silin

    git push origin :refs/tags/<tagname>
    
  2. En son işleme başvurmak için etiketi değiştirin

    git tag -fa <tagname>
    
  3. Etiketi uzaktaki kaynağa itme

    git push origin master --tags
    

90
Bunu yapmadan önce herhangi bir uzaktan kumandadaki etiketi silmek iyi bir fikir olabilir: git push origin :refs/tag/<tagname>ve sonra yapın git tag -fa <tagname>ve sonra git push origin master --tags. Aksi takdirde, uzaktan kumandadaki refs listesinde ^ ve {} karakterlerin eklenmesiyle garip şeyler elde edebilirsiniz. Bunu işaret ettiği için codebasehq.com'daki Dan'a teşekkürler.
eedeep

47
@eedeep: Küçük düzeltme - bunun yerine :refs/tag/<tagname>olmalıdır :refs/tags/<tagname>.
Ben Hocking

8
Bu yalnızca kodu makinenizden çıkarmadıysanız çalışır. Eğer varsa, en iyi cevap, muhtemelen uğraşmaya değmeyeceği için 'dünyada çok sayıda sayı var'.
Chris Huang-Leaver

33
Etiketinizi daha önce itmiş olsanız bile, uzak etiketi zorunlu bir itme ile güncelleyebilirsinizgit push -f origin <tagname>
rc_luke

11
Burada ve dokümanlarda bahsedilmeyen şey, yeni bir mesaj verilmezse bunun gerçekten etiket mesajını taşımasıdır.
Twonky

259

Daha doğrusu, etiketin eklenmesini zorlamanız, ardından --tags ve -f seçeneğiyle itmeniz gerekir:

git tag -f -a <tagname>
git push -f --tags

171

Uzaktan kumandanızın originaranıp aranmadığını ve masterşube üzerinde çalışıp çalışmadığınızı özetlemek için :

git tag -d <tagname>
git push origin :refs/tags/<tagname>
git tag <tagname> <commitId>
git push origin <tagname>
  • Satır 1 yerel env'de etiketi kaldırır.
  • Satır 2, uzak ortamdaki etiketi kaldırır.
  • Satır 3, etiketi farklı işlemlere ekler
  • Satır 4, değişikliği uzaktan kumandaya iter

Ayrıca, satır 4'ü git push origin --tagsyerel değişikliklerinizdeki etiketlerle tüm değişiklikleri itmek için değiştirebilirsiniz.

@ Stuart-golodetz, @ greg-hewgill, @eedeep, @ ben-hocking cevapları, cevaplarının altındaki yorumlar ve cevabımın altındaki NateS yorumlarına dayanarak.


87

git tag -d <tagname>İle silin ve sonra doğru taahhütte yeniden oluşturun.


3
@eedeep: Bence Greg'in yanıtı aslında adil olmak için daha iyi.
Stuart Golodetz

Basit tutun. Silin, daha önce yaptığınızı tekrar yapın.
ooolala

1
Sadeliği için kabul edilen cevap bu olmalıdır. Ayrıca aşırı kuvvet kullanmaz.
chinnychinchin

48

Git'i kullanırken birkaç şeyden kaçınmaya çalışıyorum.

  1. Dahili bilgilerin bilgisini kullanma, örneğin refs / tags. Yalnızca belgelenmiş Git komutlarını kullanmaya çalışıyorum ve .git dizininin iç içeriği hakkında bilgi gerektiren şeyleri kullanmaktan kaçınıyorum. (Yani Git'i Git geliştiricisi olarak değil Git kullanıcısı olarak görüyorum.)

  2. Gerekli olmadığında güç kullanımı.

  3. Aşırı şeyler. (İstediğim yere bir etiket almak için bir dalı ve / veya çok sayıda etiketi itmek.)

İşte Git etiketini bilmeden hem yerel hem de uzaktan bir etiketi değiştirmek için şiddet içermeyen çözümüm.

Bir yazılım düzeltmesinin nihayetinde bir sorunu olduğunda ve güncellenmesi / yeniden yayınlanması gerektiğinde kullanıyorum.

git tag -d fix123                # delete the old local tag
git push github :fix123          # delete the old remote tag (use for each affected remote)
git tag fix123 790a621265        # create a new local tag
git push github fix123           # push new tag to remote    (use for each affected remote)

githubörnek bir uzak ad, fix123bir örnek etiket adı ve 790a621265bir örnek taahhüttür.


26

Burada bu komutun ihtiyaçlarıma uygun başka bir formunu bırakacağım. Taşımak istediğim
bir etiket v0.0.1.2vardı.

$ git tag -f v0.0.1.2 63eff6a

Updated tag 'v0.0.1.2' (was 8078562)

Ve sonra:

$ git push --tags --force

iyi, teşekkürler, 2 sade ve basit komut
Sérgio

10

Başka bir yol:

Etiketi uzak depoda taşıyın. (Gerekirse HEAD'ı başka bir tanesiyle değiştirin.)

$ git push --force origin HEAD:refs/tags/v0.0.1.2

Değişiklikleri geri al.

$ git fetch --tags

Bu diğer cevaplardan daha "işlemsel".
Justin M. Keyes

9

Takma ad bir etiketi farklı bir işleme taşımak için kullanılır.

Senin örneğinde, olaya karma e2ea1639 ile taahhüt yapın: git tagm v0.1 e2ea1639.

Aktarılan etiketler için kullanın git tagmp v0.1 e2ea1639.

Her iki takma ad da orijinal tarih ve mesajı tutar. Eğer kullanırsanız git tag -dorijinal mesajınızı kaybettiniz.

Bunları .gitconfigdosyanıza kaydedin

# Return date of tag. (To use in another alias)
tag-date = "!git show $1 | awk '{ if ($1 == \"Date:\") { print substr($0, index($0,$3)) }}' | tail -2 | head -1 #"

# Show tag message
tag-message = "!git show $1 | awk -v capture=0 '{ if(capture) message=message\"\\n\"$0}; BEGIN {message=\"\"}; { if ($1 == \"Date:\" && length(message)==0 ) {capture=1}; if ($1 == \"commit\" ) {capture=0}  }; END { print message }' | sed '$ d' | cat -s #"

### Move tag. Use: git tagm <tagname> <newcommit> 
tagm = "!GIT_TAG_MESSAGE=$(git tag-message $1) && GIT_COMMITTER_DATE=$(git tag-date $1) && git tag-message $1 && git tag -d $1 && git tag -a $1 $2 -m \"$GIT_TAG_MESSAGE\" #"

### Move pushed tag. Use: git tagmp <tagname> <newcommit> 
tagmp = "!git tagm $1 $2 && git push --delete origin $1 && git push origin $1 #"

1

Açıklamalı bir etiketi taşımak istiyorsanız, yalnızca hedeflenen taahhüdü değiştirmek, ancak ek açıklama mesajını ve diğer meta veri kullanımını korumak için:

moveTag() {
  local tagName=$1
  # Support passing branch/tag names (not just full commit hashes)
  local newTarget=$(git rev-parse $2^{commit})

  git cat-file -p refs/tags/$tagName | 
    sed "1 s/^object .*$/object $newTarget/g" | 
    git hash-object -w --stdin -t tag | 
    xargs -I {} git update-ref refs/tags/$tagName {}
}

use: moveTag <tag-to-move> <target>

Yukarıdaki fonksiyon teerapap / git-move-annotated-tag.sh referans alınarak geliştirilmiştir .


1
Artık buna gerek yok gibi görünüyor: git tag -f -a my_tagzaten önceki bir mesajın mesajını koruyor (git sürüm 2.11.0 ile).
Matthijs Kooijman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.