TagCommand should be able to create unannotated tags too

Using the low level API's is just too cumbersome.

Change-Id: Id5b9f560ee095d6db0b2ea5b26aef3e53021626e
Signed-off-by: Robin Stocker <robin@nibor.org>
This commit is contained in:
Robin Rosenberg 2013-05-02 23:07:04 +02:00 committed by Robin Stocker
parent e8f720335f
commit b8e763fc19
4 changed files with 95 additions and 45 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
* 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
@ -80,6 +80,18 @@ public void testTagging() throws GitAPIException, JGitInternalException {
assertEquals(commit.getId(), db.peel(tagRef).getPeeledObjectId());
}
@Test
public void testUnannotatedTagging() throws GitAPIException,
JGitInternalException {
Git git = new Git(db);
git.commit().setMessage("initial commit").call();
RevCommit commit = git.commit().setMessage("second commit").call();
git.commit().setMessage("third commit").call();
Ref tagRef = git.tag().setObjectId(commit).setName("tag")
.setAnnotated(false).call();
assertEquals(commit.getId(), tagRef.getObjectId());
}
@Test
public void testEmptyTagName() throws GitAPIException {
Git git = new Git(db);

View File

@ -295,6 +295,7 @@ mergeStrategyDoesNotSupportHeads=merge strategy {0} does not support {1} heads t
mergeUsingStrategyResultedInDescription=Merge of revisions {0} with base {1} using strategy {2} resulted in: {3}. {4}
mergeRecursiveReturnedNoCommit=Merge returned no commit:\n Depth {0}\n Head one {1}\n Head two {2}
mergeRecursiveTooManyMergeBasesFor = "More than {0} merge bases for:\n a {1}\n b {2} found:\n count {3}"
messageAndTaggerNotAllowedInUnannotatedTags = Unannotated tags cannot have a message or tagger
minutesAgo={0} minutes ago
missingAccesskey=Missing accesskey.
missingConfigurationForKey=No value for key {0} found in configuration

View File

@ -66,18 +66,24 @@
import org.eclipse.jgit.revwalk.RevWalk;
/**
* Create/update an annotated tag object.
* Create/update an annotated tag object or a simple unannotated tag
* <p>
* Examples (<code>git</code> is a {@link Git} instance):
* <p>
* Create a new annotated tag for the current commit:
* 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>
* Use {@link Repository#updateRef(String)} to create a lightweight tag (just a
* named reference to a commit).
*
* <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>
@ -95,6 +101,8 @@ public class TagCommand extends GitCommand<Ref> {
private boolean forceUpdate;
private boolean annotated = true;
/**
* @param repo
*/
@ -120,13 +128,8 @@ public Ref call() throws GitAPIException, ConcurrentRefUpdateException,
RepositoryState state = repo.getRepositoryState();
processOptions(state);
RevWalk revWalk = new RevWalk(repo);
try {
// create the tag object
TagBuilder newTag = new TagBuilder();
newTag.setTag(name);
newTag.setMessage(message);
newTag.setTagger(tagger);
// if no id is set, we should attempt to use HEAD
if (id == null) {
ObjectId objectId = repo.resolve(Constants.HEAD + "^{commit}"); //$NON-NLS-1$
@ -134,47 +137,33 @@ public Ref call() throws GitAPIException, ConcurrentRefUpdateException,
throw new NoHeadException(
JGitText.get().tagOnRepoWithoutHEADCurrentlyNotSupported);
newTag.setObjectId(objectId, Constants.OBJ_COMMIT);
} else {
newTag.setObjectId(id);
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
ObjectInserter inserter = repo.newObjectInserter();
try {
ObjectId tagId = inserter.insert(newTag);
inserter.flush();
RevWalk revWalk = new RevWalk(repo);
try {
String refName = Constants.R_TAGS + newTag.getTag();
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.getRef(refName);
case LOCK_FAILURE:
throw new ConcurrentRefUpdateException(
JGitText.get().couldNotLockHEAD,
tagRef.getRef(), updateResult);
case REJECTED:
throw new RefAlreadyExistsException(
MessageFormat.format(
JGitText.get().tagAlreadyExists,
newTag.toString()));
default:
throw new JGitInternalException(MessageFormat.format(
JGitText.get().updatingRefFailed, refName,
newTag.toString(), updateResult));
}
} finally {
revWalk.release();
}
String tag = newTag.getTag();
return updateTagRef(tagId, revWalk, tag, newTag.toString());
} finally {
inserter.release();
@ -184,6 +173,35 @@ public Ref call() throws GitAPIException, ConcurrentRefUpdateException,
throw new JGitInternalException(
JGitText.get().exceptionCaughtDuringExecutionOfTagCommand,
e);
} finally {
revWalk.release();
}
}
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.getRef(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));
}
}
@ -201,7 +219,7 @@ public Ref call() throws GitAPIException, ConcurrentRefUpdateException,
*/
private void processOptions(RepositoryState state)
throws InvalidTagNameException {
if (tagger == null)
if (tagger == null && annotated)
tagger = new PersonIdent(repo);
if (name == null || !Repository.isValidRefName(Constants.R_TAGS + name))
throw new InvalidTagNameException(MessageFormat.format(JGitText
@ -323,4 +341,22 @@ public TagCommand setForceUpdate(boolean forceUpdate) {
return this;
}
/**
* @param annotated
* @return {@code this}
* @since 3.0
*/
public TagCommand setAnnotated(boolean annotated) {
this.annotated = annotated;
return this;
}
/**
* @return true if this command will create an annotated tag (default is
* true)
* @since 3.0
*/
public boolean isAnnotated() {
return annotated;
}
}

View File

@ -357,6 +357,7 @@ public static JGitText get() {
/***/ public String mergeUsingStrategyResultedInDescription;
/***/ public String mergeRecursiveReturnedNoCommit;
/***/ public String mergeRecursiveTooManyMergeBasesFor;
/***/ public String messageAndTaggerNotAllowedInUnannotatedTags;
/***/ public String minutesAgo;
/***/ public String missingAccesskey;
/***/ public String missingConfigurationForKey;