/*
 * Copyright (C) 2010, 2013 Chris Aniszczyk <caniszczyk@gmail.com>
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
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; } }