Как я могу переместить тег в ветке git на другой коммит? - PullRequest
727 голосов
/ 08 ноября 2011

Я создал тег в основной ветке с именем v0.1, например:

git tag -a v0.1

Но потом я понял, что все еще есть некоторые изменения, которые мне нужно было объединить с мастером для выпуска 0.1, и я сделал это. Но теперь мой v0.1 тег прикреплен (чтобы вызвать аналогию с записью) неправильный коммит. Я хочу, чтобы он застрял на последнем коммите на мастере, но вместо этого он застрял на втором последнем коммите на мастере.

Как мне переместить его в самый последний коммит на мастере?

Ответы [ 9 ]

1025 голосов
/ 08 ноября 2011

Используйте параметр -f для git tag:

-f
--force

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

Возможно, вы захотите использовать -f в сочетании с -a для принудительного создания аннотированного тегавместо неаннотированного.

Пример

  1. Удалите тег на любом пульте, прежде чем нажать

    git push origin :refs/tags/<tagname>
    
  2. Замените тег для ссылки на самый последний коммит

    git tag -fa <tagname>
    
  3. Нажмите тег для удаленного источника

    git push origin master --tags
    
242 голосов
/ 15 января 2014

Точнее, вы должны принудительно добавить тег, а затем нажать с опциями --tags и -f:

git tag -f -a <tagname>
git push -f --tags
134 голосов
/ 02 февраля 2015

Подводя итог, если ваш пульт называется origin и вы работаете в master ответвлении:

git tag -d <tagname>
git push origin :refs/tags/<tagname>
git tag <tagname> <commitId>
git push origin <tagname>
  • Строка 1 удаляет тег в локальной среде.
  • Строка 2 удаляет тег в удаленном окружении.
  • Строка 3 добавляет тег в другой коммит
  • Строка 4 передает изменение в удаленный

Вы можететакже измените строку 4 на git push origin --tags, чтобы отправить все изменения с тегами из ваших локальных изменений.

На основе ответов @ stuart-golodetz, @ greg-hewgill, @eedeep, @ ben-hocking, комментариев под ихответы и комментарии NateS под моим ответом.

86 голосов
/ 08 ноября 2011

Удалите его с помощью git tag -d <tagname>, а затем заново создайте его при правильном коммите.

22 голосов
/ 28 августа 2018

Я стараюсь избегать нескольких вещей при использовании Git.

  1. Использование знаний внутренних органов, например, ссылок / тегов.Я стараюсь использовать только документированные команды Git и избегать использования вещей, которые требуют знания внутреннего содержимого каталога .git.(То есть я рассматриваю Git как пользователя Git, а не разработчика Git.)

  2. Применение силы, когда не требуется.

  3. переусердствовать.(Нажмите на ветку и / или множество тегов, чтобы получить один тег там, где я этого хочу.)

Итак, вот мое ненасильственное решение для изменения тега как локально, так и удаленно, без знания внутренних компонентов Git.

Я использую его, когда исправление программного обеспечения в конечном итоге имеет проблему и нуждается в обновлении / повторном выпуске.

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 - это пример удаленного имени, fix123 - это пример имени тега, а 790a621265 - пример фиксации.

15 голосов
/ 19 сентября 2017

Я оставлю здесь еще одну форму этой команды, которая соответствует моим потребностям.
Был тег v0.0.1.2, который я хотел переместить.

$ git tag -f v0.0.1.2 63eff6a

Updated tag 'v0.0.1.2' (was 8078562)

А потом:

$ git push --tags --force
8 голосов
/ 21 мая 2015

Псевдоним для перемещения одного тега в другой коммит.

В вашем примере, чтобы переместить коммит с хешем e2ea1639 сделайте: git tagm v0.1 e2ea1639.

Для выдвинутых тегов используйте git tagmp v0.1 e2ea1639.

Оба псевдонима содержат исходную дату и сообщение.Если вы используете git tag -d, вы потеряли исходное сообщение.

Сохраните их в своем .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 #"
7 голосов
/ 15 марта 2018

Еще один способ:

Переместить тег в удаленном репо. (Замените HEAD на любой другой, если необходимо.)

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

Получить изменения обратно.

$ git fetch --tags
1 голос
/ 08 мая 2018

Если вы хотите переместить аннотированный тег, изменив только целевой коммит, но сохранив аннотированное сообщение и другие метаданные, используйте:

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

использование: moveTag

Вышеуказанная функция была разработана с помощью ссылки teerapap / git-move-annotated-tag.sh .

...