web-dev-qa-db-fra.com

Comment puis-je déplacer un tag d’une branche git vers un autre commit?

J'ai créé une étiquette sur la branche principale appelée v0.1 comme ceci:

git tag -a v0.1

Mais ensuite, j'ai réalisé qu'il me restait quelques changements à fusionner avec Master pour la version 0.1, alors je l'ai fait. Mais maintenant, ma balise v0.1 est bloquée (pour invoquer l'analogie post-it note) avec la validation incorrecte. Je veux que ce soit collé sur le plus récent commit sur master, mais plutôt sur le deuxième commit le plus récent sur master.

Comment puis-je le déplacer vers le plus récent commit sur master?

677
eedeep

Utilisez l'option -f pour git tag :

-f
--force

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

Vous voudrez probablement utiliser -f avec -a pour forcer la création d'une balise annotée au lieu d'une balise non annotée.

Exemple

  1. Supprimer la balise sur n'importe quelle télécommande avant d'appuyer

    git Push Origin :refs/tags/<tagname>
    
  2. Remplace la balise pour faire référence au commit le plus récent

    git tag -fa <tagname>
    
  3. Poussez l'étiquette vers la télécommande d'origine

    git Push Origin master --tags
    
957
Greg Hewgill

Plus précisément, vous devez forcer l'ajout du tag, puis Push avec l'option --tags et -f:

git tag -f -a <tagname>
git Push -f --tags
225
Daniel

En résumé, si votre télécommande s'appelle Origin et que vous travaillez sur la branche master:

git tag -d <tagname>
git Push Origin :refs/tags/<tagname>
git tag <tagname> <commitId>
git Push Origin <tagname>
  • La ligne 1 supprime la balise dans env local.
  • La ligne 2 supprime la balise dans env. À distance.
  • La ligne 3 ajoute le tag à différents commit
  • La ligne 4 envoie le changement à la télécommande

Vous pouvez également échanger la ligne 4 en git Push Origin --tags pour transmettre toutes les modifications avec les balises de vos modifications locales.

En vous basant sur @ stuart-golodetz, @ greg-hewgill, @eedeep, @ ben-hocking, vos réponses, vos commentaires sous ceux-ci et les commentaires de NateS sous ma réponse.

113
Vive

Supprimez-le avec git tag -d <tagname>, puis recréez-le sur le bon commit.

82
Stuart Golodetz

Je laisserai ici juste une autre forme de cette commande qui répondait à mes besoins.
Il y avait une balise v0.0.1.2 que je voulais déplacer.

$ git tag -f v0.0.1.2 63eff6a

Updated tag 'v0.0.1.2' (was 8078562)

Et alors: 

$ git Push --tags --force
8
Nakilon

Alias ​​pour déplacer une balise vers un autre commit.

Dans votre exemple, pour déplacer une validation avec le hachage e2ea1639, procédez comme suit: git tagm v0.1 e2ea1639.

Pour les tags poussés, utilisez git tagmp v0.1 e2ea1639.

Les deux alias vous permettent de conserver la date et le message d'origine. Si vous utilisez git tag -d, vous avez perdu votre message d'origine.

Enregistrez-les sur votre fichier .gitconfig

# 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 #"
6

J'essaie d'éviter deux choses lorsque j'utilise Git.

  1. Utilisation de la connaissance des composants internes, par exemple refs/tags. J'essaie d'utiliser uniquement les commandes Git documentées et d'éviter d'utiliser des éléments nécessitant une connaissance du contenu interne du répertoire .git. (C’est-à-dire que je traite Git en tant qu’utilisateur Git et non en tant que développeur Git.)

  2. Évitez le recours à la force lorsqu'il n'est pas nécessaire.

Voici donc ma solution non violente pour changer une étiquette, à la fois localement et à distance, sans connaître les éléments internes de Git.

Je l'utilise lorsqu'un correctif logiciel pose finalement un problème et doit être mis à jour/réédité. 

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

github est un exemple de nom de télécommande, fix123 est un exemple de nom de balise et 790a621265 un exemple de validation.

5
user3070485

Une autre façon:

Déplacer la balise dans le dépôt distant (remplacez HEAD par une autre si nécessaire.)

$ git Push --force Origin HEAD:refs/tags/v0.0.1.2

Récupère les changements.

$ git fetch --tags

Si vous souhaitez déplacer une balise annotée, modifiez uniquement la validation ciblée tout en préservant le message d'annotation et les autres métadonnées utilisées:

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 {}
}

utilisation: moveTag <tag-to-move> <cible>

La fonction ci-dessus a été développée en référençant teerapap/git-move-annotated-tag.sh .

0
vossad01