/*
 * Copyright (C) 2010, 2013 Chris Aniszczyk <caniszczyk@gmail.com> and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package org.eclipse.jgit.api;

import java.io.IOException;
import java.text.MessageFormat;

import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidTagNameException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.api.errors.NoHeadException;
import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryState;
import org.eclipse.jgit.lib.TagBuilder;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevWalk;

Create/update an annotated tag object or a simple unannotated tag

Examples (git is a Git instance):

Create a new tag for the current commit:

git.tag().setName("v1.0").setMessage("First stable release").call();

Create a new unannotated tag for the current commit:

git.tag().setName("v1.0").setAnnotated(false).call();

See Also:
/** * Create/update an annotated tag object or a simple unannotated tag * <p> * Examples (<code>git</code> is a {@link org.eclipse.jgit.api.Git} instance): * <p> * Create a new tag for the current commit: * * <pre> * git.tag().setName(&quot;v1.0&quot;).setMessage(&quot;First stable release&quot;).call(); * </pre> * <p> * * <p> * Create a new unannotated tag for the current commit: * * <pre> * git.tag().setName(&quot;v1.0&quot;).setAnnotated(false).call(); * </pre> * <p> * * @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-tag.html" * >Git documentation about Tag</a> */
public class TagCommand extends GitCommand<Ref> { private RevObject id; private String name; private String message; private PersonIdent tagger; private boolean signed; private boolean forceUpdate; private boolean annotated = true;

Constructor for TagCommand.

Params:
/** * <p>Constructor for TagCommand.</p> * * @param repo a {@link org.eclipse.jgit.lib.Repository} object. */
protected TagCommand(Repository repo) { super(repo); }
{@inheritDoc}

Executes the tag command with all the options and parameters collected by the setter methods of this class. Each instance of this class should only be used for one invocation of the command (means: one call to call())

Since:2.0
/** * {@inheritDoc} * <p> * Executes the {@code tag} command with all the options and parameters * collected by the setter methods of this class. Each instance of this * class should only be used for one invocation of the command (means: one * call to {@link #call()}) * * @since 2.0 */
@Override public Ref call() throws GitAPIException, ConcurrentRefUpdateException, InvalidTagNameException, NoHeadException { checkCallable(); RepositoryState state = repo.getRepositoryState(); processOptions(state); try (RevWalk revWalk = new RevWalk(repo)) { // if no id is set, we should attempt to use HEAD if (id == null) { ObjectId objectId = repo.resolve(Constants.HEAD + "^{commit}"); //$NON-NLS-1$ if (objectId == null) throw new NoHeadException( JGitText.get().tagOnRepoWithoutHEADCurrentlyNotSupported); id = revWalk.parseCommit(objectId); } if (!annotated) { if (message != null || tagger != null) throw new JGitInternalException( JGitText.get().messageAndTaggerNotAllowedInUnannotatedTags); return updateTagRef(id, revWalk, name, "SimpleTag[" + name + " : " + id //$NON-NLS-1$ //$NON-NLS-2$ + "]"); //$NON-NLS-1$ } // create the tag object TagBuilder newTag = new TagBuilder(); newTag.setTag(name); newTag.setMessage(message); newTag.setTagger(tagger); newTag.setObjectId(id); // write the tag object try (ObjectInserter inserter = repo.newObjectInserter()) { ObjectId tagId = inserter.insert(newTag); inserter.flush(); String tag = newTag.getTag(); return updateTagRef(tagId, revWalk, tag, newTag.toString()); } } catch (IOException e) { throw new JGitInternalException( JGitText.get().exceptionCaughtDuringExecutionOfTagCommand, e); } } private Ref updateTagRef(ObjectId tagId, RevWalk revWalk, String tagName, String newTagToString) throws IOException, ConcurrentRefUpdateException, RefAlreadyExistsException { String refName = Constants.R_TAGS + tagName; RefUpdate tagRef = repo.updateRef(refName); tagRef.setNewObjectId(tagId); tagRef.setForceUpdate(forceUpdate); tagRef.setRefLogMessage("tagged " + name, false); //$NON-NLS-1$ Result updateResult = tagRef.update(revWalk); switch (updateResult) { case NEW: case FORCED: return repo.exactRef(refName); case LOCK_FAILURE: throw new ConcurrentRefUpdateException( JGitText.get().couldNotLockHEAD, tagRef.getRef(), updateResult); case REJECTED: throw new RefAlreadyExistsException(MessageFormat.format( JGitText.get().tagAlreadyExists, newTagToString)); default: throw new JGitInternalException(MessageFormat.format( JGitText.get().updatingRefFailed, refName, newTagToString, updateResult)); } }
Sets default values for not explicitly specified options. Then validates that all required data has been provided.
Params:
  • state – the state of the repository we are working on
Throws:
/** * Sets default values for not explicitly specified options. Then validates * that all required data has been provided. * * @param state * the state of the repository we are working on * * @throws InvalidTagNameException * if the tag name is null or invalid * @throws UnsupportedOperationException * if the tag is signed (not supported yet) */
private void processOptions(RepositoryState state) throws InvalidTagNameException { if (tagger == null && annotated) tagger = new PersonIdent(repo); if (name == null || !Repository.isValidRefName(Constants.R_TAGS + name)) throw new InvalidTagNameException( MessageFormat.format(JGitText.get().tagNameInvalid, name == null ? "<null>" : name)); //$NON-NLS-1$ if (signed) throw new UnsupportedOperationException( JGitText.get().signingNotSupportedOnTag); }
Set the tag name.
Params:
  • name – the tag name used for the tag
Returns:this
/** * Set the tag <code>name</code>. * * @param name * the tag name used for the {@code tag} * @return {@code this} */
public TagCommand setName(String name) { checkCallable(); this.name = name; return this; }
Get the tag name.
Returns:the tag name used for the tag
/** * Get the tag <code>name</code>. * * @return the tag name used for the <code>tag</code> */
public String getName() { return name; }
Get the tag message.
Returns:the tag message used for the tag
/** * Get the tag <code>message</code>. * * @return the tag message used for the <code>tag</code> */
public String getMessage() { return message; }
Set the tag message.
Params:
  • message – the tag message used for the tag
Returns:this
/** * Set the tag <code>message</code>. * * @param message * the tag message used for the {@code tag} * @return {@code this} */
public TagCommand setMessage(String message) { checkCallable(); this.message = message; return this; }
Whether this tag is signed
Returns:whether the tag is signed
/** * Whether this tag is signed * * @return whether the tag is signed */
public boolean isSigned() { return signed; }
If set to true the Tag command creates a signed tag object. This corresponds to the parameter -s on the command line.
Params:
  • signed – a boolean.
Returns:this
/** * If set to true the Tag command creates a signed tag object. This * corresponds to the parameter -s on the command line. * * @param signed * a boolean. * @return {@code this} */
public TagCommand setSigned(boolean signed) { this.signed = signed; return this; }
Sets the tagger of the tag. If the tagger is null, a PersonIdent will be created from the info in the repository.
Params:
Returns:this
/** * Sets the tagger of the tag. If the tagger is null, a PersonIdent will be * created from the info in the repository. * * @param tagger * a {@link org.eclipse.jgit.lib.PersonIdent} object. * @return {@code this} */
public TagCommand setTagger(PersonIdent tagger) { this.tagger = tagger; return this; }
Get the tagger who created the tag.
Returns:the tagger of the tag
/** * Get the <code>tagger</code> who created the tag. * * @return the tagger of the tag */
public PersonIdent getTagger() { return tagger; }
Get the tag's object id
Returns:the object id of the tag
/** * Get the tag's object id * * @return the object id of the tag */
public RevObject getObjectId() { return id; }
Sets the object id of the tag. If the object id is null, the commit pointed to from HEAD will be used.
Params:
Returns:this
/** * Sets the object id of the tag. If the object id is null, the commit * pointed to from HEAD will be used. * * @param id * a {@link org.eclipse.jgit.revwalk.RevObject} object. * @return {@code this} */
public TagCommand setObjectId(RevObject id) { this.id = id; return this; }
Whether this is a forced update
Returns:is this a force update
/** * Whether this is a forced update * * @return is this a force update */
public boolean isForceUpdate() { return forceUpdate; }
If set to true the Tag command may replace an existing tag object. This corresponds to the parameter -f on the command line.
Params:
  • forceUpdate – whether this is a forced update
Returns:this
/** * If set to true the Tag command may replace an existing tag object. This * corresponds to the parameter -f on the command line. * * @param forceUpdate * whether this is a forced update * @return {@code this} */
public TagCommand setForceUpdate(boolean forceUpdate) { this.forceUpdate = forceUpdate; return this; }
Configure this tag to be created as an annotated tag
Params:
  • annotated – whether this shall be an annotated tag
Returns:this
Since:3.0
/** * Configure this tag to be created as an annotated tag * * @param annotated * whether this shall be an annotated tag * @return {@code this} * @since 3.0 */
public TagCommand setAnnotated(boolean annotated) { this.annotated = annotated; return this; }
Whether this will create an annotated command
Returns:true if this command will create an annotated tag (default is true)
Since:3.0
/** * Whether this will create an annotated command * * @return true if this command will create an annotated tag (default is * true) * @since 3.0 */
public boolean isAnnotated() { return annotated; } }