Как перенести тег на ветку git на другую фиксацию?

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

git tag -a v0.1

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

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

Ответы

Ответ 1

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

-f
--force

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

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

Пример

  • Удалите тег на любом удаленном устройстве, прежде чем нажимать

    git push origin :refs/tags/<tagname>
    
  • Замените тег на ссылку последнего фиксации

    git tag -fa <tagname>
    
  • Нажмите тег на удаленное начало

    git push origin master --tags
    

Ответ 2

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

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

Ответ 3

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

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

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

Основываясь на @stuart-golodetz, @greg-hewgill, @eedeep, @ben-hocking ответы, комментарии ниже их ответов и комментарии NateS ниже моего ответа.

Ответ 4

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

Ответ 5

Я стараюсь избегать нескольких вещей при использовании 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 - примерный коммит.

Ответ 6

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

$ git tag -f v0.0.1.2 63eff6a

Updated tag 'v0.0.1.2' (was 8078562)

И затем:

$ git push --tags --force

Ответ 7

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

В вашем примере переместить фиксацию с помощью hash e2ea1639 do: 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 #"

Ответ 8

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

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

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

Извлечение меняется обратно.

$ git fetch --tags

Ответ 9

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

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 <tag-to-move> <target>

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