Fix broken TagCommand API

Tags can be un-annotated whereby there is no RevTag object, only
a ref pointing to the tagged object.

Bug: 360650
Change-Id: I06309c45c0a896fe2a0a874700febf78c9fb87e8
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java
index 4bfc56c..1489e47 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java
@@ -54,7 +54,8 @@
 import org.eclipse.jgit.api.ListTagCommand;
 import org.eclipse.jgit.api.TagCommand;
 import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.revwalk.RevTag;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevWalk;
 import org.kohsuke.args4j.Argument;
 import org.kohsuke.args4j.Option;
@@ -88,9 +89,9 @@ protected void run() throws Exception {
 			command.call();
 		} else {
 			ListTagCommand command = git.tagList();
-			List<RevTag> list = command.call();
-			for (RevTag revTag : list) {
-				out.println(revTag.getTagName());
+			List<Ref> list = command.call();
+			for (Ref ref : list) {
+				out.println(Repository.shortenRefName(ref.getName()));
 			}
 		}
 	}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BranchCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BranchCommandTest.java
index 7760ec0..32d2e01 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BranchCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BranchCommandTest.java
@@ -67,7 +67,6 @@
 import org.eclipse.jgit.lib.RepositoryTestCase;
 import org.eclipse.jgit.lib.StoredConfig;
 import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevTag;
 import org.eclipse.jgit.transport.FetchResult;
 import org.eclipse.jgit.transport.RefSpec;
 import org.eclipse.jgit.transport.RemoteConfig;
@@ -264,10 +263,10 @@ public void testCreateFromLightweightTag() throws Exception {
 
 	@Test
 	public void testCreateFromAnnotatetdTag() throws Exception {
-		RevTag tag = git.tag().setName("V10").setObjectId(secondCommit).call();
+		Ref tagRef = git.tag().setName("V10").setObjectId(secondCommit).call();
 		Ref branch = git.branchCreate().setName("FromAnnotatedTag")
 				.setStartPoint("refs/tags/V10").call();
-		assertFalse(tag.getId().equals(branch.getObjectId()));
+		assertFalse(tagRef.getObjectId().equals(branch.getObjectId()));
 		assertEquals(secondCommit.getId(), branch.getObjectId());
 	}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
index 756802a..6545c37 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
@@ -49,11 +49,11 @@
 
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.lib.RepositoryTestCase;
 import org.eclipse.jgit.lib.StoredConfig;
 import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevTag;
 import org.eclipse.jgit.transport.RefSpec;
 import org.eclipse.jgit.transport.RemoteConfig;
 import org.eclipse.jgit.transport.URIish;
@@ -79,7 +79,7 @@ public void testFetch() throws JGitInternalException, IOException,
 
 		// create some refs via commits and tag
 		RevCommit commit = git2.commit().setMessage("initial commit").call();
-		RevTag tag = git2.tag().setName("tag").call();
+		Ref tagRef = git2.tag().setName("tag").call();
 
 		Git git1 = new Git(db);
 
@@ -89,7 +89,8 @@ public void testFetch() throws JGitInternalException, IOException,
 
 		assertEquals(commit.getId(),
 				db.resolve(commit.getId().getName() + "^{commit}"));
-		assertEquals(tag.getId(), db.resolve(tag.getId().getName()));
+		assertEquals(tagRef.getObjectId(),
+				db.resolve(tagRef.getObjectId().getName()));
 
 	}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java
index d5ae0c9..d6d1427 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java
@@ -52,12 +52,12 @@
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.api.errors.JGitInternalException;
 import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.RefUpdate;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.lib.RepositoryTestCase;
 import org.eclipse.jgit.lib.StoredConfig;
 import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevTag;
 import org.eclipse.jgit.transport.PushResult;
 import org.eclipse.jgit.transport.RefSpec;
 import org.eclipse.jgit.transport.RemoteConfig;
@@ -85,7 +85,7 @@ public void testPush() throws JGitInternalException, IOException,
 		Git git1 = new Git(db);
 		// create some refs via commits and tag
 		RevCommit commit = git1.commit().setMessage("initial commit").call();
-		RevTag tag = git1.tag().setName("tag").call();
+		Ref tagRef = git1.tag().setName("tag").call();
 
 		try {
 			db2.resolve(commit.getId().getName() + "^{commit}");
@@ -100,7 +100,8 @@ public void testPush() throws JGitInternalException, IOException,
 
 		assertEquals(commit.getId(),
 				db2.resolve(commit.getId().getName() + "^{commit}"));
-		assertEquals(tag.getId(), db2.resolve(tag.getId().getName()));
+		assertEquals(tagRef.getObjectId(),
+				db2.resolve(tagRef.getObjectId().getName()));
 	}
 
 	@Test
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 1e8f7fd..7f381e3 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
@@ -45,6 +45,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
+import java.io.IOException;
 import java.util.List;
 
 import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
@@ -53,25 +54,29 @@
 import org.eclipse.jgit.api.errors.NoHeadException;
 import org.eclipse.jgit.api.errors.NoMessageException;
 import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.errors.UnmergedPathException;
-import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.lib.RepositoryTestCase;
 import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevTag;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.junit.Test;
 
 public class TagCommandTest extends RepositoryTestCase {
 
 	@Test
 	public void testTaggingOnHead() throws NoHeadException, NoMessageException,
-			UnmergedPathException, ConcurrentRefUpdateException,
-			JGitInternalException, WrongRepositoryStateException,
-			InvalidTagNameException {
+			ConcurrentRefUpdateException, JGitInternalException,
+			WrongRepositoryStateException, InvalidTagNameException,
+			MissingObjectException, IncorrectObjectTypeException, IOException {
 		Git git = new Git(db);
 		RevCommit commit = git.commit().setMessage("initial commit").call();
-		RevTag tag = git.tag().setName("tag").call();
-		assertEquals(commit.getId(), tag.getObject().getId());
+		Ref tagRef = git.tag().setName("tag").call();
+		assertEquals(commit.getId(), db.peel(tagRef).getPeeledObjectId());
+		RevWalk walk = new RevWalk(db);
+		assertEquals("tag", walk.parseTag(tagRef.getObjectId()).getTagName());
 	}
 
 	@Test
@@ -83,8 +88,8 @@ public void testTagging() throws NoHeadException, NoMessageException,
 		git.commit().setMessage("initial commit").call();
 		RevCommit commit = git.commit().setMessage("second commit").call();
 		git.commit().setMessage("third commit").call();
-		RevTag tag = git.tag().setObjectId(commit).setName("tag").call();
-		assertEquals(commit.getId(), tag.getObject().getId());
+		Ref tagRef = git.tag().setObjectId(commit).setName("tag").call();
+		assertEquals(commit.getId(), db.peel(tagRef).getPeeledObjectId());
 	}
 
 	@Test
@@ -136,21 +141,20 @@ public void testFailureOnSignedTags() throws NoHeadException,
 	public void testDelete() throws Exception {
 		Git git = new Git(db);
 		git.commit().setMessage("initial commit").call();
-		RevTag tag = git.tag().setName("tag").call();
+		Ref tagRef = git.tag().setName("tag").call();
 		assertEquals(1, db.getTags().size());
 
-		List<String> deleted = git.tagDelete().setTags(tag.getTagName())
+		List<String> deleted = git.tagDelete().setTags(tagRef.getName())
 				.call();
 		assertEquals(1, deleted.size());
-		assertEquals(tag.getTagName(),
-				Repository.shortenRefName(deleted.get(0)));
+		assertEquals(tagRef.getName(), deleted.get(0));
 		assertEquals(0, db.getTags().size());
 
-		RevTag tag1 = git.tag().setName("tag1").call();
-		RevTag tag2 = git.tag().setName("tag2").call();
+		Ref tagRef1 = git.tag().setName("tag1").call();
+		Ref tagRef2 = git.tag().setName("tag2").call();
 		assertEquals(2, db.getTags().size());
-		deleted = git.tagDelete()
-				.setTags(tag1.getTagName(), tag2.getTagName()).call();
+		deleted = git.tagDelete().setTags(tagRef1.getName(), tagRef2.getName())
+				.call();
 		assertEquals(2, deleted.size());
 		assertEquals(0, db.getTags().size());
 	}
@@ -159,13 +163,13 @@ public void testDelete() throws Exception {
 	public void testDeleteFullName() throws Exception {
 		Git git = new Git(db);
 		git.commit().setMessage("initial commit").call();
-		RevTag tag = git.tag().setName("tag").call();
+		Ref tagRef = git.tag().setName("tag").call();
 		assertEquals(1, db.getTags().size());
 
 		List<String> deleted = git.tagDelete()
-				.setTags(Constants.R_TAGS + tag.getTagName()).call();
+				.setTags(Repository.shortenRefName(tagRef.getName())).call();
 		assertEquals(1, deleted.size());
-		assertEquals(Constants.R_TAGS + tag.getTagName(), deleted.get(0));
+		assertEquals(tagRef.getName(), deleted.get(0));
 		assertEquals(0, db.getTags().size());
 	}
 
@@ -203,7 +207,7 @@ public void testShouldNotBlowUpIfThereAreNoTagsInRepository()
 		Git git = new Git(db);
 		git.add().addFilepattern("*").call();
 		git.commit().setMessage("initial commit").call();
-		List<RevTag> list = git.tagList().call();
+		List<Ref> list = git.tagList().call();
 		assertEquals(0, list.size());
 	}
 
@@ -211,7 +215,7 @@ public void testShouldNotBlowUpIfThereAreNoTagsInRepository()
 	public void testShouldNotBlowUpIfThereAreNoCommitsInRepository()
 			throws Exception {
 		Git git = new Git(db);
-		List<RevTag> list = git.tagList().call();
+		List<Ref> list = git.tagList().call();
 		assertEquals(0, list.size());
 	}
 
@@ -225,12 +229,12 @@ public void testListAllTagsInRepositoryInOrder() throws Exception {
 		git.tag().setName("v2").call();
 		git.tag().setName("v10").call();
 
-		List<RevTag> list = git.tagList().call();
+		List<Ref> list = git.tagList().call();
 
 		assertEquals(3, list.size());
-		assertEquals("v10", list.get(0).getTagName());
-		assertEquals("v2", list.get(1).getTagName());
-		assertEquals("v3", list.get(2).getTagName());
+		assertEquals("refs/tags/v10", list.get(0).getName());
+		assertEquals("refs/tags/v2", list.get(1).getName());
+		assertEquals("refs/tags/v3", list.get(2).getName());
 	}
 
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java
index ec199c3..c1ae887 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java
@@ -53,7 +53,6 @@
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevTag;
 import org.eclipse.jgit.revwalk.RevWalk;
 
 /**
@@ -62,7 +61,7 @@
  * @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-tag.html"
  *      >Git documentation about Tag</a>
  */
-public class ListTagCommand extends GitCommand<List<RevTag>> {
+public class ListTagCommand extends GitCommand<List<Ref>> {
 
 	/**
 	 * @param repo
@@ -76,25 +75,24 @@ protected ListTagCommand(Repository repo) {
 	 *             upon internal failure
 	 * @return the tags available
 	 */
-	public List<RevTag> call() throws JGitInternalException {
+	public List<Ref> call() throws JGitInternalException {
 		checkCallable();
 		Map<String, Ref> refList;
-		List<RevTag> tags = new ArrayList<RevTag>();
+		List<Ref> tags = new ArrayList<Ref>();
 		RevWalk revWalk = new RevWalk(repo);
 		try {
 			refList = repo.getRefDatabase().getRefs(Constants.R_TAGS);
 			for (Ref ref : refList.values()) {
-				RevTag tag = revWalk.parseTag(ref.getObjectId());
-				tags.add(tag);
+				tags.add(ref);
 			}
 		} catch (IOException e) {
 			throw new JGitInternalException(e.getMessage(), e);
 		} finally {
 			revWalk.release();
 		}
-		Collections.sort(tags, new Comparator<RevTag>() {
-			public int compare(RevTag o1, RevTag o2) {
-				return o1.getTagName().compareTo(o2.getTagName());
+		Collections.sort(tags, new Comparator<Ref>() {
+			public int compare(Ref o1, Ref o2) {
+				return o1.getName().compareTo(o2.getName());
 			}
 		});
 		setCallable(false);
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 d5196a3..30d548c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java
@@ -54,13 +54,13 @@
 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.RevTag;
 import org.eclipse.jgit.revwalk.RevWalk;
 
 /**
@@ -71,7 +71,7 @@
  * @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<RevTag> {
+public class TagCommand extends GitCommand<Ref> {
 	private RevObject id;
 
 	private String name;
@@ -97,7 +97,7 @@ protected TagCommand(Repository repo) {
 	 * class should only be used for one invocation of the command (means: one
 	 * call to {@link #call()})
 	 *
-	 * @return a {@link RevTag} object representing the successful tag
+	 * @return a {@link Ref} a ref pointing to a tag
 	 * @throws NoHeadException
 	 *             when called on a git repo without a HEAD reference
 	 * @throws JGitInternalException
@@ -106,7 +106,7 @@ protected TagCommand(Repository repo) {
 	 *             {@link Exception#getCause()}. Expect only
 	 *             {@code IOException's} to be wrapped.
 	 */
-	public RevTag call() throws JGitInternalException,
+	public Ref call() throws JGitInternalException,
 			ConcurrentRefUpdateException, InvalidTagNameException, NoHeadException {
 		checkCallable();
 
@@ -140,7 +140,6 @@ public RevTag call() throws JGitInternalException,
 
 				RevWalk revWalk = new RevWalk(repo);
 				try {
-					RevTag revTag = revWalk.parseTag(tagId);
 					String refName = Constants.R_TAGS + newTag.getTag();
 					RefUpdate tagRef = repo.updateRef(refName);
 					tagRef.setNewObjectId(tagId);
@@ -150,7 +149,7 @@ public RevTag call() throws JGitInternalException,
 					switch (updateResult) {
 					case NEW:
 					case FORCED:
-						return revTag;
+						return repo.getRef(refName);
 					case LOCK_FAILURE:
 						throw new ConcurrentRefUpdateException(
 								JGitText.get().couldNotLockHEAD,