From 707912b35d3375ea70808e176e028aa086d01451 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Fri, 20 Aug 2010 15:18:25 -0700 Subject: [PATCH] Make Tag class only for writing The Tag class now only supports the creation of an annotated tag object. To read an annotated tag, applictions should use RevTag. This permits us to have exactly one implementation, and RevTag's is faster and more bug-free. Change-Id: Ib573f7e15f36855112815269385c21dea532e2cf Signed-off-by: Shawn O. Pearce --- .../eclipse/jgit/junit/TestRepository.java | 5 +- .../org/eclipse/jgit/pgm/CLIText.properties | 1 + .../src/org/eclipse/jgit/pgm/CLIText.java | 1 + .../src/org/eclipse/jgit/pgm/Tag.java | 44 ++- .../jgit/storage/file/T0003_Basic.java | 133 +++----- .../org/eclipse/jgit/JGitText.properties | 1 - .../src/org/eclipse/jgit/JGitText.java | 1 - .../org/eclipse/jgit/lib/ObjectInserter.java | 4 +- .../src/org/eclipse/jgit/lib/Repository.java | 36 --- .../src/org/eclipse/jgit/lib/Tag.java | 285 ++++++------------ .../src/org/eclipse/jgit/revwalk/RevTag.java | 12 - 11 files changed, 185 insertions(+), 338 deletions(-) diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java index 2737b64834..9df4072b0c 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java @@ -397,9 +397,8 @@ public class TestRepository { * @throws Exception */ public RevTag tag(final String name, final RevObject dst) throws Exception { - final Tag t = new Tag(db); - t.setType(Constants.typeString(dst.getType())); - t.setObjId(dst.toObjectId()); + final Tag t = new Tag(); + t.setObjectId(dst); t.setTag(name); t.setTagger(new PersonIdent(committer, new Date(now))); t.setMessage(""); diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties index 2fff6d4630..dc738d3856 100644 --- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties +++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties @@ -44,6 +44,7 @@ expectedNumberOfbytes=Expected {0} bytes. exporting=Exporting {0} failedToCommitIndex=failed to commit index failedToLockIndex=failed to lock index +failedToLockTag=Failed to lock tag {0}: {1} fatalError=fatal: {0} fatalErrorTagExists=fatal: tag '{0}' exists fatalThisProgramWillDestroyTheRepository=fatal: This program will destroy the repository\nfatal:\nfatal:\nfatal: {0}\nfatal:\nfatal: To continue, add {1} to the command line\nfatal: diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java index 14dcb1f50d..dd0f6dbea6 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java @@ -97,6 +97,7 @@ public class CLIText extends TranslationBundle { /***/ public String exporting; /***/ public String failedToCommitIndex; /***/ public String failedToLockIndex; + /***/ public String failedToLockTag; /***/ public String fatalError; /***/ public String fatalErrorTagExists; /***/ public String fatalThisProgramWillDestroyTheRepository; 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 c798950a2e..df986a88bc 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 @@ -51,8 +51,10 @@ import java.text.MessageFormat; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.ObjectLoader; import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.RefUpdate; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; @@ -80,19 +82,45 @@ class Tag extends TextBuiltin { if (!tagName.startsWith(Constants.R_TAGS)) tagName = Constants.R_TAGS + tagName; + + String shortName = tagName.substring(Constants.R_TAGS.length()); if (!force && db.resolve(tagName) != null) { throw die(MessageFormat.format(CLIText.get().fatalErrorTagExists - , tagName.substring(Constants.R_TAGS.length()))); + , shortName)); } final ObjectLoader ldr = db.open(object); + final ObjectInserter inserter = db.newObjectInserter(); + final ObjectId id; + try { + org.eclipse.jgit.lib.Tag tag = new org.eclipse.jgit.lib.Tag(); + tag.setObjectId(object, ldr.getType()); + tag.setTagger(new PersonIdent(db)); + tag.setMessage(message.replaceAll("\r", "")); + tag.setTag(shortName); + id = inserter.insert(Constants.OBJ_TAG, inserter.format(tag)); + inserter.flush(); + } finally { + inserter.release(); + } + + RefUpdate ru = db.updateRef(tagName); + ru.setForceUpdate(force); + ru.setNewObjectId(id); + ru.setRefLogMessage("tagged " + shortName, false); + switch (ru.update()) { + case NEW: + case FAST_FORWARD: + case FORCED: + break; - org.eclipse.jgit.lib.Tag tag = new org.eclipse.jgit.lib.Tag(db); - tag.setObjId(object); - tag.setType(Constants.typeString(ldr.getType())); - tag.setTagger(new PersonIdent(db)); - tag.setMessage(message.replaceAll("\r", "")); - tag.setTag(tagName.substring(Constants.R_TAGS.length())); - tag.tag(); + case REJECTED: + throw die(MessageFormat.format(CLIText.get().fatalErrorTagExists, + shortName)); + + default: + throw die(MessageFormat.format(CLIText.get().failedToLockTag, + shortName, ru.getResult())); + } } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/T0003_Basic.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/T0003_Basic.java index 0c170a6b3d..1c7d3b681e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/T0003_Basic.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/T0003_Basic.java @@ -77,6 +77,7 @@ import org.eclipse.jgit.lib.Tree; import org.eclipse.jgit.lib.TreeEntry; import org.eclipse.jgit.lib.WriteTree; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevWalk; public class T0003_Basic extends SampleDataRepositoryTestCase { @@ -439,33 +440,19 @@ public class T0003_Basic extends SampleDataRepositoryTestCase { public void test020_createBlobTag() throws IOException { final ObjectId emptyId = new ObjectWriter(db).writeBlob(new byte[0]); - final Tag t = new Tag(db); - t.setObjId(emptyId); - t.setType("blob"); + final Tag t = new Tag(); + t.setObjectId(emptyId, Constants.OBJ_BLOB); t.setTag("test020"); t.setTagger(new PersonIdent(author, 1154236443000L, -4 * 60)); t.setMessage("test020 tagged\n"); - t.tag(); + insertTag(t); assertEquals("6759556b09fbb4fd8ae5e315134481cc25d46954", t.getTagId().name()); - Tag mapTag = db.mapTag("test020"); - assertEquals("blob", mapTag.getType()); - assertEquals("test020 tagged\n", mapTag.getMessage()); - assertEquals(new PersonIdent(author, 1154236443000L, -4 * 60), mapTag.getTagger()); - assertEquals("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", mapTag.getObjId().name()); - } - - public void test020b_createBlobPlainTag() throws IOException { - test020_createBlobTag(); - Tag t = new Tag(db); - t.setTag("test020b"); - t.setObjId(ObjectId.fromString("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391")); - t.tag(); - - Tag mapTag = db.mapTag("test020b"); - assertEquals("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", mapTag.getObjId().name()); - - // We do not repeat the plain tag test for other object types + RevTag mapTag = parseTag(t.getTagId()); + assertEquals(Constants.OBJ_BLOB, mapTag.getObject().getType()); + assertEquals("test020 tagged\n", mapTag.getFullMessage()); + assertEquals(new PersonIdent(author, 1154236443000L, -4 * 60), mapTag.getTaggerIdent()); + assertEquals("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", mapTag.getObject().getId().name()); } public void test021_createTreeTag() throws IOException { @@ -473,20 +460,19 @@ public class T0003_Basic extends SampleDataRepositoryTestCase { final Tree almostEmptyTree = new Tree(db); almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId, "empty".getBytes(), false)); final ObjectId almostEmptyTreeId = new ObjectWriter(db).writeTree(almostEmptyTree); - final Tag t = new Tag(db); - t.setObjId(almostEmptyTreeId); - t.setType("tree"); + final Tag t = new Tag(); + t.setObjectId(almostEmptyTreeId, Constants.OBJ_TREE); t.setTag("test021"); t.setTagger(new PersonIdent(author, 1154236443000L, -4 * 60)); t.setMessage("test021 tagged\n"); - t.tag(); + insertTag(t); assertEquals("b0517bc8dbe2096b419d42424cd7030733f4abe5", t.getTagId().name()); - Tag mapTag = db.mapTag("test021"); - assertEquals("tree", mapTag.getType()); - assertEquals("test021 tagged\n", mapTag.getMessage()); - assertEquals(new PersonIdent(author, 1154236443000L, -4 * 60), mapTag.getTagger()); - assertEquals("417c01c8795a35b8e835113a85a5c0c1c77f67fb", mapTag.getObjId().name()); + RevTag mapTag = parseTag(t.getTagId()); + assertEquals(Constants.OBJ_TREE, mapTag.getObject().getType()); + assertEquals("test021 tagged\n", mapTag.getFullMessage()); + assertEquals(new PersonIdent(author, 1154236443000L, -4 * 60), mapTag.getTaggerIdent()); + assertEquals("417c01c8795a35b8e835113a85a5c0c1c77f67fb", mapTag.getObject().getId().name()); } public void test022_createCommitTag() throws IOException { @@ -500,20 +486,19 @@ public class T0003_Basic extends SampleDataRepositoryTestCase { almostEmptyCommit.setMessage("test022\n"); almostEmptyCommit.setTreeId(almostEmptyTreeId); ObjectId almostEmptyCommitId = insertCommit(almostEmptyCommit); - final Tag t = new Tag(db); - t.setObjId(almostEmptyCommitId); - t.setType("commit"); + final Tag t = new Tag(); + t.setObjectId(almostEmptyCommitId,Constants.OBJ_COMMIT); t.setTag("test022"); t.setTagger(new PersonIdent(author, 1154236443000L, -4 * 60)); t.setMessage("test022 tagged\n"); - t.tag(); + insertTag(t); assertEquals("0ce2ebdb36076ef0b38adbe077a07d43b43e3807", t.getTagId().name()); - Tag mapTag = db.mapTag("test022"); - assertEquals("commit", mapTag.getType()); - assertEquals("test022 tagged\n", mapTag.getMessage()); - assertEquals(new PersonIdent(author, 1154236443000L, -4 * 60), mapTag.getTagger()); - assertEquals("b5d3b45a96b340441f5abb9080411705c51cc86c", mapTag.getObjId().name()); + RevTag mapTag = parseTag(t.getTagId()); + assertEquals(Constants.OBJ_COMMIT, mapTag.getObject().getType()); + assertEquals("test022 tagged\n", mapTag.getFullMessage()); + assertEquals(new PersonIdent(author, 1154236443000L, -4 * 60), mapTag.getTaggerIdent()); + assertEquals("b5d3b45a96b340441f5abb9080411705c51cc86c", mapTag.getObject().getId().name()); } public void test023_createCommitNonAnullii() throws IOException { @@ -549,51 +534,6 @@ public class T0003_Basic extends SampleDataRepositoryTestCase { assertEquals("2979b39d385014b33287054b87f77bcb3ecb5ebf", cid.name()); } - public void test025_packedRefs() throws IOException { - test020_createBlobTag(); - test021_createTreeTag(); - test022_createCommitTag(); - - if (!new File(db.getDirectory(),"refs/tags/test020").delete()) throw new Error("Cannot delete unpacked tag"); - if (!new File(db.getDirectory(),"refs/tags/test021").delete()) throw new Error("Cannot delete unpacked tag"); - if (!new File(db.getDirectory(),"refs/tags/test022").delete()) throw new Error("Cannot delete unpacked tag"); - - // We cannot resolve it now, since we have no ref - Tag mapTag20missing = db.mapTag("test020"); - assertNull(mapTag20missing); - - // Construct packed refs file - PrintWriter w = new PrintWriter(new FileWriter(new File(db.getDirectory(), "packed-refs"))); - w.println("# packed-refs with: peeled"); - w.println("6759556b09fbb4fd8ae5e315134481cc25d46954 refs/tags/test020"); - w.println("^e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"); - w.println("b0517bc8dbe2096b419d42424cd7030733f4abe5 refs/tags/test021"); - w.println("^417c01c8795a35b8e835113a85a5c0c1c77f67fb"); - w.println("0ce2ebdb36076ef0b38adbe077a07d43b43e3807 refs/tags/test022"); - w.println("^b5d3b45a96b340441f5abb9080411705c51cc86c"); - w.close(); - ((RefDirectory)db.getRefDatabase()).rescan(); - - Tag mapTag20 = db.mapTag("test020"); - assertNotNull("have tag test020", mapTag20); - assertEquals("blob", mapTag20.getType()); - assertEquals("test020 tagged\n", mapTag20.getMessage()); - assertEquals(new PersonIdent(author, 1154236443000L, -4 * 60), mapTag20.getTagger()); - assertEquals("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", mapTag20.getObjId().name()); - - Tag mapTag21 = db.mapTag("test021"); - assertEquals("tree", mapTag21.getType()); - assertEquals("test021 tagged\n", mapTag21.getMessage()); - assertEquals(new PersonIdent(author, 1154236443000L, -4 * 60), mapTag21.getTagger()); - assertEquals("417c01c8795a35b8e835113a85a5c0c1c77f67fb", mapTag21.getObjId().name()); - - Tag mapTag22 = db.mapTag("test022"); - assertEquals("commit", mapTag22.getType()); - assertEquals("test022 tagged\n", mapTag22.getMessage()); - assertEquals(new PersonIdent(author, 1154236443000L, -4 * 60), mapTag22.getTagger()); - assertEquals("b5d3b45a96b340441f5abb9080411705c51cc86c", mapTag22.getObjId().name()); - } - public void test025_computeSha1NoStore() throws IOException { byte[] data = "test025 some data, more than 16 bytes to get good coverage" .getBytes("ISO-8859-1"); @@ -777,6 +717,29 @@ public class T0003_Basic extends SampleDataRepositoryTestCase { } } + private ObjectId insertTag(final Tag tag) throws IOException, + UnsupportedEncodingException { + ObjectInserter oi = db.newObjectInserter(); + try { + ObjectId id = oi.insert(Constants.OBJ_TAG, oi.format(tag)); + oi.flush(); + tag.setTagId(id); + return id; + } finally { + oi.release(); + } + } + + private RevTag parseTag(AnyObjectId id) throws MissingObjectException, + IncorrectObjectTypeException, IOException { + RevWalk rw = new RevWalk(db); + try { + return rw.parseTag(id); + } finally { + rw.release(); + } + } + /** * Kick the timestamp of a local file. *

diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties index faeb1d53f9..6744f548d3 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties @@ -352,7 +352,6 @@ truncatedHunkLinesMissingForAncestor=Truncated hunk, at least {0} lines missing truncatedHunkNewLinesMissing=Truncated hunk, at least {0} new lines is missing truncatedHunkOldLinesMissing=Truncated hunk, at least {0} old lines is missing unableToCheckConnectivity=Unable to check connectivity. -unableToLockTag=Unable to lock tag {0} unableToStore=Unable to store {0}. unableToWrite=Unable to write {0} unencodeableFile=Unencodeable file: {0} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java index 461242cb27..ece1c29e1d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java @@ -411,7 +411,6 @@ public class JGitText extends TranslationBundle { /***/ public String truncatedHunkNewLinesMissing; /***/ public String truncatedHunkOldLinesMissing; /***/ public String unableToCheckConnectivity; - /***/ public String unableToLockTag; /***/ public String unableToStore; /***/ public String unableToWrite; /***/ public String unencodeableFile; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java index 349b8197db..369dd6e4c2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java @@ -367,11 +367,11 @@ public abstract class ObjectInserter { OutputStreamWriter w = new OutputStreamWriter(os, Constants.CHARSET); try { w.write("object "); - tag.getObjId().copyTo(w); + tag.getObjectId().copyTo(w); w.write('\n'); w.write("type "); - w.write(tag.getType()); + w.write(Constants.typeString(tag.getObjectType())); w.write("\n"); w.write("tag "); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java index 6059efde91..2742cd4e50 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -317,42 +317,6 @@ public abstract class Repository { } } - /** - * Access a tag by symbolic name. - * - * @param revstr - * @return a Tag or null - * @throws IOException on I/O error or unexpected type - * @deprecated Use {@link #resolve(String)} and feed its return value to - * {@link org.eclipse.jgit.revwalk.RevWalk#parseTag(AnyObjectId)}. - */ - @Deprecated - public Tag mapTag(String revstr) throws IOException { - final ObjectId id = resolve(revstr); - return id != null ? mapTag(revstr, id) : null; - } - - /** - * Access a Tag by SHA'1 id - * @param refName - * @param id - * @return Commit or null - * @throws IOException for I/O error or unexpected object type. - * @deprecated Use {@link org.eclipse.jgit.revwalk.RevWalk#parseTag(AnyObjectId)}. - */ - @Deprecated - public Tag mapTag(final String refName, final ObjectId id) throws IOException { - final ObjectLoader or; - try { - or = open(id); - } catch (MissingObjectException notFound) { - return null; - } - if (or.getType() == Constants.OBJ_TAG) - return new Tag(this, id, refName, or.getCachedBytes()); - return new Tag(this, id, refName, null); - } - /** * Create a command to update, create or delete a ref in this repository. * diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Tag.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Tag.java index 4559c1eef1..fbd22c36be 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Tag.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Tag.java @@ -45,250 +45,155 @@ package org.eclipse.jgit.lib; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.text.MessageFormat; - -import org.eclipse.jgit.JGitText; -import org.eclipse.jgit.errors.CorruptObjectException; -import org.eclipse.jgit.errors.ObjectWritingException; +import org.eclipse.jgit.revwalk.RevObject; /** - * Represents a named reference to another Git object of any type. + * Mutable builder to construct an annotated tag recording a project state. + * + * Applications should use this object when they need to manually construct a + * tag and want precise control over its fields. */ public class Tag { - private final Repository objdb; - private ObjectId tagId; - private PersonIdent tagger; + private ObjectId object; - private String message; - - private byte[] raw; - - private String type; + private int type = Constants.OBJ_BAD; private String tag; - private ObjectId objId; + private PersonIdent tagger; - /** - * Construct a new, yet unnamed Tag. - * - * @param db - */ - public Tag(final Repository db) { - objdb = db; + private String message; + + /** @return this tag's object id. */ + public ObjectId getTagId() { + return tagId; } /** - * Construct a Tag representing an existing with a known name referencing an known object. - * This could be either a simple or annotated tag. + * Set the id of this tag object. * - * @param db {@link Repository} - * @param id target id. - * @param refName tag name or null - * @param raw data of an annotated tag. + * @param id + * the id that we calculated for this object. */ - public Tag(final Repository db, final ObjectId id, String refName, final byte[] raw) { - objdb = db; - if (raw != null) { - tagId = id; - objId = ObjectId.fromString(raw, 7); - } else - objId = id; - if (refName != null && refName.startsWith("refs/tags/")) - refName = refName.substring(10); - tag = refName; - this.raw = raw; + public void setTagId(ObjectId id) { + tagId = id; } - /** - * @return comment of an annotated tag, or null - */ - public String getMessage() { - decode(); - return message; + /** @return the type of object this tag refers to. */ + public int getObjectType() { + return type; } - private void decode() { - // FIXME: handle I/O errors - if (raw != null) { - try { - BufferedReader br = new BufferedReader(new InputStreamReader( - new ByteArrayInputStream(raw))); - String n = br.readLine(); - if (n == null || !n.startsWith("object ")) { - throw new CorruptObjectException(tagId, JGitText.get().corruptObjectNoObject); - } - objId = ObjectId.fromString(n.substring(7)); - n = br.readLine(); - if (n == null || !n.startsWith("type ")) { - throw new CorruptObjectException(tagId, JGitText.get().corruptObjectNoType); - } - type = n.substring("type ".length()); - n = br.readLine(); - - if (n == null || !n.startsWith("tag ")) { - throw new CorruptObjectException(tagId, JGitText.get().corruptObjectNoTagName); - } - tag = n.substring("tag ".length()); - n = br.readLine(); - - // We should see a "tagger" header here, but some repos have tags - // without it. - if (n == null) - throw new CorruptObjectException(tagId, JGitText.get().corruptObjectNoTaggerHeader); - - if (n.length()>0) - if (n.startsWith("tagger ")) - tagger = new PersonIdent(n.substring("tagger ".length())); - else - throw new CorruptObjectException(tagId, JGitText.get().corruptObjectNoTaggerBadHeader); - - // Message should start with an empty line, but - StringBuilder tempMessage = new StringBuilder(); - char[] readBuf = new char[2048]; - int readLen; - while ((readLen = br.read(readBuf)) > 0) { - tempMessage.append(readBuf, 0, readLen); - } - message = tempMessage.toString(); - if (message.startsWith("\n")) - message = message.substring(1); - } catch (IOException e) { - e.printStackTrace(); - } finally { - raw = null; - } - } + /** @return the object this tag refers to. */ + public ObjectId getObjectId() { + return object; } /** - * Set the message of an annotated tag - * @param m + * Set the object this tag refers to, and its type. + * + * @param obj + * the object. + * @param objType + * the type of {@code obj}. Must be a valid type code. */ - public void setMessage(final String m) { - message = m; + public void setObjectId(AnyObjectId obj, int objType) { + object = obj.copy(); + type = objType; + tagId = null; } /** - * Store a tag. - * If author, message or type is set make the tag an annotated tag. + * Set the object this tag refers to, and infer its type. * - * @throws IOException + * @param obj + * the object the tag will refer to. */ - public void tag() throws IOException { - if (getTagId() != null) - throw new IllegalStateException(MessageFormat.format(JGitText.get().illegalStateExists, getTagId())); - final ObjectId id; - final RefUpdate ru; - - if (tagger!=null || message!=null || type!=null) { - ObjectInserter odi = objdb.newObjectInserter(); - try { - id = odi.insert(Constants.OBJ_TAG, odi.format(this)); - odi.flush(); - setTagId(id); - } finally { - odi.release(); - } - } else { - id = objId; - } - - ru = objdb.updateRef(Constants.R_TAGS + getTag()); - ru.setNewObjectId(id); - ru.setRefLogMessage("tagged " + getTag(), false); - if (ru.forceUpdate() == RefUpdate.Result.LOCK_FAILURE) - throw new ObjectWritingException(MessageFormat.format(JGitText.get().unableToLockTag, getTag())); + public void setObjectId(RevObject obj) { + setObjectId(obj, obj.getType()); } - public String toString() { - return "tag[" + getTag() + getType() + getObjId() + " " + getTagger() + "]"; - } - - /** - * @return SHA-1 of this tag (if annotated and stored). - */ - public ObjectId getTagId() { - return tagId; + /** @return short name of the tag (no {@code refs/tags/} prefix). */ + public String getTag() { + return tag; } /** - * Set SHA-1 of this tag. Used by writer. + * Set the name of this tag. * - * @param tagId + * @param shortName + * new short name of the tag. This short name should not start + * with {@code refs/} as typically a tag is stored under the + * reference derived from {@code "refs/tags/" + getTag()}. */ - public void setTagId(ObjectId tagId) { - this.tagId = tagId; + public void setTag(String shortName) { + this.tag = shortName; + tagId = null; } - /** - * @return creator of this tag. - */ + /** @return creator of this tag. May be null. */ public PersonIdent getTagger() { - decode(); return tagger; } /** - * Set the creator of this tag + * Set the creator of this tag. * - * @param tagger - */ - public void setTagger(PersonIdent tagger) { - this.tagger = tagger; - } - - /** - * @return tag target type - */ - public String getType() { - decode(); - return type; - } - - /** - * Set tag target type - * @param type + * @param taggerIdent + * the creator. May be null. */ - public void setType(String type) { - this.type = type; + public void setTagger(PersonIdent taggerIdent) { + tagger = taggerIdent; + tagId = null; } - /** - * @return name of the tag. - */ - public String getTag() { - return tag; + /** @return the complete commit message. */ + public String getMessage() { + return message; } /** - * Set the name of this tag. + * Set the tag's message. * - * @param tag + * @param newMessage + * the tag's message. */ - public void setTag(String tag) { - this.tag = tag; + public void setMessage(final String newMessage) { + message = newMessage; + tagId = null; } - /** - * @return the SHA'1 of the object this tag refers to. - */ - public ObjectId getObjId() { - return objId; - } + @Override + public String toString() { + StringBuilder r = new StringBuilder(); + r.append("Tag"); + if (tagId != null) + r.append("[" + tagId.name() + "]"); + r.append("={\n"); + + r.append("object "); + r.append(object != null ? object.name() : "NOT_SET"); + r.append("\n"); + + r.append("type "); + r.append(object != null ? Constants.typeString(type) : "NOT_SET"); + r.append("\n"); + + r.append("tag "); + r.append(tag != null ? tag : "NOT_SET"); + r.append("\n"); + + if (tagger != null) { + r.append("tagger "); + r.append(tagger); + r.append("\n"); + } - /** - * Set the id of the object this tag refers to. - * - * @param objId - */ - public void setObjId(ObjectId objId) { - this.objId = objId; + r.append("\n"); + r.append(message != null ? message : ""); + r.append("}"); + return r.toString(); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java index a04ea7154e..dadebe9cb5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java @@ -54,7 +54,6 @@ import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.PersonIdent; -import org.eclipse.jgit.lib.Tag; import org.eclipse.jgit.util.MutableInteger; import org.eclipse.jgit.util.RawParseUtils; @@ -186,17 +185,6 @@ public class RevTag extends RevObject { return str; } - /** - * Parse this tag buffer for display. - * - * @param walk - * revision walker owning this reference. - * @return parsed tag. - */ - public Tag asTag(final RevWalk walk) { - return new Tag(walk.repository, this, tagName, buffer); - } - /** * Get a reference to the object this tag was placed on. * -- 2.39.5