diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/TagCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/TagCommandTest.java index b9838b171..061d29f50 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/TagCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/TagCommandTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, Chris Aniszczyk + * Copyright (C) 2010, 2013 Chris Aniszczyk * 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); diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties index b64617b39..a8e10f36e 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -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 diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java index 3b1fe8840..8570baa74 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java @@ -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 *

* Examples (git is a {@link Git} instance): *

- * Create a new annotated tag for the current commit: + * Create a new tag for the current commit: * *

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

- * Use {@link Repository#updateRef(String)} to create a lightweight tag (just a - * named reference to a commit). + * + *

+ * Create a new unannotated tag for the current commit: + * + *

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

* * @see Git documentation about Tag @@ -95,6 +101,8 @@ public class TagCommand extends GitCommand { 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; + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java index d7eb8af95..bd211e7e9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -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;