{"thread":{"id":"7025","subject":"[EGIT PATCH 9/9] Performance test for jgit.","startedAt":"2007-02-28T22:26:04Z","lastAt":"2007-03-01T08:22:17Z","messageCount":12,"participants":["Robin Rosenberg","Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":9},"messages":[{"id":"35895","messageId":"20070228222355.12021.13029.stgit@lathund.dewire.com","threadId":"7025","inReplyTo":null,"subject":"[EGIT PATCH 0/9] Misc minor fixes","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg.lists@dewire.com","sentAt":"2007-02-28T22:26:04Z","receivedAt":"2007-02-28T22:26:04Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"This is a set of smaller fixes necessary to implement larger\nfeatures ( to be submitted later on ).\n\n-- robin\n"},{"id":"35894","messageId":"20070228222610.12021.1782.stgit@lathund.dewire.com","threadId":"7025","inReplyTo":"20070228222355.12021.13029.stgit@lathund.dewire.com","subject":"[EGIT PATCH 1/9] Minor fix.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2007-02-28T22:26:10Z","receivedAt":"2007-02-28T22:26:10Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"Eclipse's strict checking thinks there is an error.\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n---\n\n .../src/org/spearce/jgit/lib/WindowedFile.java     |    3 ++-\n 1 files changed, 2 insertions(+), 1 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/WindowedFile.java b/org.spearce.jgit/src/org/spearce/jgit/lib/WindowedFile.java\nindex 28b495f..827cc22 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/WindowedFile.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/WindowedFile.java\n@@ -21,6 +21,7 @@ import java.io.File;\n import java.io.IOException;\n import java.io.RandomAccessFile;\n import java.nio.MappedByteBuffer;\n+import java.nio.channels.FileChannel;\n import java.nio.channels.FileChannel.MapMode;\n import java.util.zip.DataFormatException;\n import java.util.zip.Inflater;\n@@ -85,7 +86,7 @@ public class WindowedFile {\n \t *            use the same window cache.\n \t * @param file\n \t *            the file to open. The file will be opened for reading only,\n-\t *            unless {@link MapMode#READ_WRITE} or {@link MapMode#PRIVATE}\n+\t *            unless {@link FileChannel.MapMode#READ_WRITE} or {@link FileChannel.MapMode#PRIVATE}\n \t *            is given.\n \t * @param windowSz\n \t *            number of bytes within a window. This value must be a power of\n"},{"id":"35898","messageId":"20070228222615.12021.4058.stgit@lathund.dewire.com","threadId":"7025","inReplyTo":"20070228222355.12021.13029.stgit@lathund.dewire.com","subject":"[EGIT PATCH 2/9] Catch mmap errors and retry.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2007-02-28T22:26:16Z","receivedAt":"2007-02-28T22:26:16Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"At least JDK 1.4 and 1.5 versions can hit an IOException if\nmemory cannot be mapped. A workaround is to catch the exception\nand retry once.\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n---\n\n .../src/org/spearce/jgit/lib/Repository.java       |   19 ++++++++++++++++---\n 1 files changed, 16 insertions(+), 3 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\nindex c9e8a2d..5e0e89a 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n@@ -145,9 +145,22 @@ public class Repository {\n \t\t\t\t\t\treturn ol;\n \t\t\t\t} catch (IOException ioe) {\n \t\t\t\t\t// This shouldn't happen unless the pack was corrupted\n-\t\t\t\t\t// after we opened it. We'll ignore the error as though\n-\t\t\t\t\t// the object does not exist in this pack.\n-\t\t\t\t\t//\n+\t\t\t\t\t// after we opened it or the VM runs out of memory. This is\n+\t\t\t\t\t// a know problem with memory mapped I/O in java and have\n+\t\t\t\t\t// been noticed with JDK < 1.6. Tell the gc that now is a good\n+\t\t\t\t\t// time to collect and try once more.\n+\t\t\t\t\ttry {\n+\t\t\t\t\t\tSystem.gc();\n+\t\t\t\t\t\tfinal ObjectLoader ol = packs[k].get(id, tmp);\n+\t\t\t\t\t\tif (ol != null)\n+\t\t\t\t\t\t\treturn ol;\n+\t\t\t\t\t} catch (IOException ioe2) {\n+\t\t\t\t\t\tioe2.printStackTrace();\n+\t\t\t\t\t\tioe.printStackTrace();\n+\t\t\t\t\t\t// Still fails.. that's BAD, maybe the pack has\n+\t\t\t\t\t\t// been corrupted after all, or the gc didn't manage\n+\t\t\t\t\t\t// to release enough previously mmaped areas.\n+\t\t\t\t\t}\n \t\t\t\t}\n \t\t\t} while (k > 0);\n \t\t}\n"},{"id":"35900","messageId":"20070228222621.12021.65339.stgit@lathund.dewire.com","threadId":"7025","inReplyTo":"20070228222355.12021.13029.stgit@lathund.dewire.com","subject":"[EGIT PATCH 3/9] Use mmap per default.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2007-02-28T22:26:21Z","receivedAt":"2007-02-28T22:26:21Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"A small test of mine show a tenfold speed improvemnt looking for a blob\nwhile scanning the history (11K commit, blob three trees down). This was\non a x86 platform. For other platforms Shawn noted that memory mapping\nwas about 10% slower than normall reading of files.\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n---\n\n .../src/org/spearce/jgit/lib/PackFile.java         |    4 ++--\n 1 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\nindex ee4b8a1..d33aa97 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\n@@ -42,7 +42,7 @@ public class PackFile {\n \t\trepo = parentRepo;\n \t\t// FIXME window size and mmap type should be configurable\n \t\tpack = new WindowedFile(repo.getWindowCache(), packFile,\n-\t\t\t\t64 * 1024 * 1024, false);\n+\t\t\t\t64 * 1024 * 1024, true);\n \t\ttry {\n \t\t\treadPackHeader();\n \n@@ -53,7 +53,7 @@ public class PackFile {\n \t\t\t\t\t+ \".idx\");\n \t\t\t// FIXME window size and mmap type should be configurable\n \t\t\tidx = new WindowedFile(repo.getWindowCache(), idxFile,\n-\t\t\t\t\t64 * 1024 * 1024, false);\n+\t\t\t\t\t64 * 1024 * 1024, true);\n \t\t\ttry {\n \t\t\t\tidxHeader = readIndexHeader();\n \t\t\t} catch (IOException ioe) {\n"},{"id":"35899","messageId":"20070228222626.12021.60482.stgit@lathund.dewire.com","threadId":"7025","inReplyTo":"20070228222355.12021.13029.stgit@lathund.dewire.com","subject":"[EGIT PATCH 4/9] Add .qualifier to the plugin version.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2007-02-28T22:26:26Z","receivedAt":"2007-02-28T22:26:26Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"This makes every exported plugin have a different name. This\nis not the git SHA1, but a timestamp.\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n---\n\n org.spearce.egit.core/META-INF/MANIFEST.MF |    2 +-\n org.spearce.egit.ui/META-INF/MANIFEST.MF   |    2 +-\n org.spearce.jgit/META-INF/MANIFEST.MF      |    2 +-\n 3 files changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/org.spearce.egit.core/META-INF/MANIFEST.MF b/org.spearce.egit.core/META-INF/MANIFEST.MF\nindex f295c3c..a8349a1 100644\n--- a/org.spearce.egit.core/META-INF/MANIFEST.MF\n+++ b/org.spearce.egit.core/META-INF/MANIFEST.MF\n@@ -2,7 +2,7 @@ Manifest-Version: 1.0\n Bundle-ManifestVersion: 2\n Bundle-Name: %plugin_name\n Bundle-SymbolicName: org.spearce.egit.core; singleton:=true\n-Bundle-Version: 0.2\n+Bundle-Version: 0.2.0.qualifier\n Bundle-Activator: org.spearce.egit.core.Activator\n Bundle-Vendor: %provider_name\n Bundle-Localization: plugin\ndiff --git a/org.spearce.egit.ui/META-INF/MANIFEST.MF b/org.spearce.egit.ui/META-INF/MANIFEST.MF\nindex 5c97648..63dcec8 100644\n--- a/org.spearce.egit.ui/META-INF/MANIFEST.MF\n+++ b/org.spearce.egit.ui/META-INF/MANIFEST.MF\n@@ -2,7 +2,7 @@ Manifest-Version: 1.0\n Bundle-ManifestVersion: 2\n Bundle-Name: %plugin_name\n Bundle-SymbolicName: org.spearce.egit.ui; singleton:=true\n-Bundle-Version: 0.2\n+Bundle-Version: 0.2.0.qualifier\n Bundle-Activator: org.spearce.egit.ui.Activator\n Bundle-Vendor: %plugin_provider\n Bundle-Localization: plugin\ndiff --git a/org.spearce.jgit/META-INF/MANIFEST.MF b/org.spearce.jgit/META-INF/MANIFEST.MF\nindex 2f959e1..1485bb9 100644\n--- a/org.spearce.jgit/META-INF/MANIFEST.MF\n+++ b/org.spearce.jgit/META-INF/MANIFEST.MF\n@@ -2,7 +2,7 @@ Manifest-Version: 1.0\n Bundle-ManifestVersion: 2\n Bundle-Name: %plugin_name\n Bundle-SymbolicName: org.spearce.jgit\n-Bundle-Version: 0.2\n+Bundle-Version: 0.2.0.qualifier\n Bundle-Localization: plugin\n Bundle-Vendor: %provider_name\n Export-Package: org.spearce.jgit.errors,\n"},{"id":"35901","messageId":"20070228222631.12021.49294.stgit@lathund.dewire.com","threadId":"7025","inReplyTo":"20070228222355.12021.13029.stgit@lathund.dewire.com","subject":"[EGIT PATCH 5/9] Force full checkpoint for CheckpointOperation.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2007-02-28T22:26:32Z","receivedAt":"2007-02-28T22:26:32Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"Until further notice we need this operation not to cut any\ncorners but to do everything in order to clean up because it is\nstill too easy to mess upp the checkpoint tree completely.\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n---\n\n .../spearce/egit/core/op/CheckpointOperation.java  |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/org.spearce.egit.core/src/org/spearce/egit/core/op/CheckpointOperation.java b/org.spearce.egit.core/src/org/spearce/egit/core/op/CheckpointOperation.java\nindex 9534039..6cf80ca 100644\n--- a/org.spearce.egit.core/src/org/spearce/egit/core/op/CheckpointOperation.java\n+++ b/org.spearce.egit.core/src/org/spearce/egit/core/op/CheckpointOperation.java\n@@ -68,7 +68,7 @@ public class CheckpointOperation implements IWorkspaceRunnable {\n \t\t\tfinal IProject project = (IProject) i.next();\n \t\t\tfinal GitProjectData projectData = GitProjectData.get(project);\n \t\t\tif (projectData != null)\n-\t\t\t\tprojectData.checkpointIfNecessary();\n+\t\t\t\tprojectData.fullUpdate();\n \t\t}\n \t}\n }\n"},{"id":"35896","messageId":"20070228222637.12021.63285.stgit@lathund.dewire.com","threadId":"7025","inReplyTo":"20070228222355.12021.13029.stgit@lathund.dewire.com","subject":"[EGIT PATCH 6/9] Add branch and StGit patch to decorator","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2007-02-28T22:26:37Z","receivedAt":"2007-02-28T22:26:37Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"This makes it easier to see in what context you are working.\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n---\n\n .../internal/decorators/GitResourceDecorator.java  |   20 ++++++++++++++++----\n .../src/org/spearce/jgit/lib/Repository.java       |   22 ++++++++++++++++++++++\n 2 files changed, 38 insertions(+), 4 deletions(-)\n\ndiff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitResourceDecorator.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitResourceDecorator.java\nindex bde6182..da2e256 100644\n--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitResourceDecorator.java\n+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitResourceDecorator.java\n@@ -16,6 +16,8 @@\n  */\n package org.spearce.egit.ui.internal.decorators;\n \n+import java.io.IOException;\n+\n import org.eclipse.core.resources.IResource;\n import org.eclipse.core.runtime.CoreException;\n import org.eclipse.core.runtime.IAdaptable;\n@@ -30,6 +32,7 @@ import org.spearce.egit.core.project.RepositoryMapping;\n import org.spearce.egit.ui.UIIcons;\n import org.spearce.egit.ui.UIText;\n import org.spearce.jgit.lib.MergedTree;\n+import org.spearce.jgit.lib.Repository;\n import org.spearce.jgit.lib.TreeEntry;\n \n /**\n@@ -110,10 +113,19 @@ public class GitResourceDecorator extends LabelProvider implements\n \t\t\tfinal MergedTree diff = mapped.getActiveDiff();\n \t\t\tif (diff != null && diff.isModified())\n \t\t\t\tdecoration.addPrefix(\">\");\n-\t\t\tif (mapped.getRepository().isStGitMode())\n-\t\t\t\tdecoration.addSuffix(\" [StGit]\");\n-\t\t\telse\n-\t\t\t\tdecoration.addSuffix(\" [Git]\");\n+\t\t\tRepository repo = mapped.getRepository();\n+\t\t\ttry {\n+\t\t\t\tString branch = repo.getBranch();\n+\t\t\t\tif (repo.isStGitMode()) {\n+\t\t\t\t\tString patch = repo.getPatch();\n+\t\t\t\t\tdecoration.addSuffix(\" [StGit \" + patch + \"@\" + branch +\"]\");\n+\t\t\t\t} else {\n+\t\t\t\t\tdecoration.addSuffix(\" [Git @ \"+ branch + \"]\");\n+\t\t\t\t}\n+\t\t\t} catch (IOException e) {\n+\t\t\t\te.printStackTrace();\n+\t\t\t\tdecoration.addSuffix(\" [Git ?]\");\n+\t\t\t}\n \t\t\tdecoration.addOverlay(UIIcons.OVR_SHARED);\n \t\t\treturn;\n \t\t}\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\nindex 5e0e89a..d2943c3 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n@@ -342,6 +342,27 @@ public class Repository {\n \t\treturn \"Repository[\" + getDirectory() + \"]\";\n \t}\n \n+\tpublic String getPatch() throws IOException {\n+\t\tfinal File ptr = new File(getDirectory(),\"patches/\"+getBranch()+\"/current\");\n+\t\tfinal BufferedReader br = new BufferedReader(new FileReader(ptr));\n+\t\tfinal String line = br.readLine();\n+\t\treturn line;\n+\t}\n+\tpublic String getBranch() throws IOException {\n+\t\tfinal File ptr = new File(getDirectory(),\"HEAD\");\n+\t\tfinal BufferedReader br = new BufferedReader(new FileReader(ptr));\n+\t\tfinal String line = br.readLine();\n+\t\t\n+\t\tString ref;\n+\t\tif (line.startsWith(\"ref: \"))\n+\t\t\tref = line.substring(5);\n+\t\telse\n+\t\t\tref = line; \n+\t\tif (ref.startsWith(\"refs/heads/\"))\n+\t\t\tref = ref.substring(11);\n+\t\treturn ref;\n+\t}\n+\n \tpublic Collection getBranches() {\n \t\treturn listFilesRecursively(new File(refsDir, \"heads\"), null);\n \t}\n@@ -391,4 +412,5 @@ public class Repository {\n \t\t}\n \t\treturn ret;\n \t}\n+\n }\n"},{"id":"35897","messageId":"20070228222642.12021.43184.stgit@lathund.dewire.com","threadId":"7025","inReplyTo":"20070228222355.12021.13029.stgit@lathund.dewire.com","subject":"[EGIT PATCH 7/9] Support tag objects","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2007-02-28T22:26:42Z","receivedAt":"2007-02-28T22:26:42Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"A tag refers to another object and can carry information about\nwho created the tag and when.\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n---\n\n .../src/org/spearce/jgit/lib/Commit.java           |    2 \n .../src/org/spearce/jgit/lib/ObjectWriter.java     |   37 +++++\n .../src/org/spearce/jgit/lib/Repository.java       |   15 ++\n org.spearce.jgit/src/org/spearce/jgit/lib/Tag.java |  172 ++++++++++++++++++++\n .../tst/org/spearce/jgit/lib/T0003_Basic.java      |   66 +++++++++\n 5 files changed, 291 insertions(+), 1 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Commit.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Commit.java\nindex 498f983..d1ef5de 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Commit.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Commit.java\n@@ -79,7 +79,7 @@ public class Commit implements Treeish {\n \t}\n \n \tpublic void setTreeId(final ObjectId id) {\n-\t\tif (!treeId.equals(id)) {\n+\t\tif (treeId==null || !treeId.equals(id)) {\n \t\t\ttreeObj = null;\n \t\t}\n \t\ttreeId = id;\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectWriter.java b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectWriter.java\nindex 620f1cd..0ff092c 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectWriter.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectWriter.java\n@@ -137,6 +137,38 @@ public class ObjectWriter {\n \t\treturn writeCommit(os.toByteArray());\n \t}\n \n+\tpublic ObjectId writeTag(final byte[] b) throws IOException {\n+\t\treturn writeTag(b.length, new ByteArrayInputStream(b));\n+\t}\n+\n+\tpublic ObjectId writeTag(final Tag c) throws IOException {\n+\t\tfinal ByteArrayOutputStream os = new ByteArrayOutputStream();\n+\t\tfinal OutputStreamWriter w = new OutputStreamWriter(os,\n+\t\t\t\tConstants.CHARACTER_ENCODING);\n+\n+\t\tw.write(\"object \");\n+\t\tc.getObjId().copyTo(w);\n+\t\tw.write('\\n');\n+\n+\t\tw.write(\"type \");\n+\t\tw.write(c.getType());\n+\t\tw.write(\"\\n\");\n+\t\t\n+\t\tw.write(\"tag \");\n+\t\tw.write(c.getTag());\n+\t\tw.write(\"\\n\");\n+\t\t\n+\t\tw.write(\"tagger \");\n+\t\tw.write(c.getAuthor().toExternalString());\n+\t\tw.write('\\n');\n+\n+\t\tw.write('\\n');\n+\t\tw.write(c.getMessage());\n+\t\tw.close();\n+\n+\t\treturn writeTag(os.toByteArray());\n+\t}\n+\t\n \tpublic ObjectId writeCommit(final byte[] b) throws IOException {\n \t\treturn writeCommit(b.length, new ByteArrayInputStream(b));\n \t}\n@@ -146,6 +178,11 @@ public class ObjectWriter {\n \t\treturn writeObject(Constants.OBJ_COMMIT, Constants.TYPE_COMMIT, len, is);\n \t}\n \n+\tpublic ObjectId writeTag(final long len, final InputStream is)\n+\t\tthrows IOException {\n+\t\treturn writeObject(Constants.OBJ_TAG, Constants.TYPE_TAG, len, is);\n+\t}\n+\t\n \tpublic ObjectId writeObject(final int typeCode, final String type,\n \t\t\tlong len, final InputStream is) throws IOException {\n \t\tfinal File t;\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\nindex d2943c3..069c650 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n@@ -211,6 +211,21 @@ public class Repository {\n \t\tthrow new IncorrectObjectTypeException(id, Constants.TYPE_TREE);\n \t}\n \n+\tpublic Tag mapTag(String revstr) throws IOException {\n+\t\tfinal ObjectId id = resolve(revstr);\n+\t\treturn id != null ? mapTag(id) : null;\n+\t}\n+\t\n+\tpublic Tag mapTag(final ObjectId id) throws IOException {\n+\t\tfinal ObjectLoader or = openObject(id);\n+\t\tif (or == null)\n+\t\t\treturn null;\n+\t\tfinal byte[] raw = or.getBytes();\n+\t\tif (Constants.TYPE_TAG.equals(or.getType()))\n+\t\t\treturn new Tag(this, id, raw);\n+\t\tthrow new IncorrectObjectTypeException(id, Constants.TYPE_TAG);\n+\t}\n+\n \tpublic RefLock lockRef(final String ref) throws IOException {\n \t\tfinal RefLock l = new RefLock(readRef(ref, true));\n \t\treturn l.lock() ? l : null;\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Tag.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Tag.java\nnew file mode 100644\nindex 0000000..d9e6990\n--- /dev/null\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Tag.java\n@@ -0,0 +1,172 @@\n+/*\n+ *  Copyright (C) 20067  Robin Rosenberg <robin.rosenberg@dewire.com>\n+ *\n+ *  This library is free software; you can redistribute it and/or\n+ *  modify it under the terms of the GNU General Public\n+ *  License, version 2, as published by the Free Software Foundation.\n+ *\n+ *  This library is distributed in the hope that it will be useful,\n+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+ *  General Public License for more details.\n+ *\n+ *  You should have received a copy of the GNU General Public\n+ *  License along with this library; if not, write to the Free Software\n+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301\n+ */\n+package org.spearce.jgit.lib;\n+\n+import java.io.BufferedReader;\n+import java.io.ByteArrayInputStream;\n+import java.io.IOException;\n+import java.io.InputStreamReader;\n+\n+import org.spearce.jgit.errors.CorruptObjectException;\n+\n+public class Tag {\n+\tprivate final Repository objdb;\n+\n+\tprivate ObjectId tagId;\n+\n+\tprivate PersonIdent tagger;\n+\n+\tprivate String message;\n+\n+\tprivate byte[] raw;\n+\n+\tprivate String type;\n+\n+\tprivate String tag;\n+\n+\tprivate ObjectId objId;\n+\n+\tpublic Tag(final Repository db) {\n+\t\tobjdb = db;\n+\t}\n+\n+\tpublic Tag(final Repository db, final ObjectId id, final byte[] raw) {\n+\t\tobjdb = db;\n+\t\ttagId = id;\n+\t\tobjId = ObjectId.fromString(raw, 7);\n+\t\tthis.raw = raw;\n+\t}\n+\n+\tpublic PersonIdent getAuthor() {\n+\t\tdecode();\n+\t\treturn tagger;\n+\t}\n+\n+\tpublic void setAuthor(final PersonIdent a) {\n+\t\ttagger = a;\n+\t}\n+\n+\tpublic String getMessage() {\n+\t\tdecode();\n+\t\treturn message;\n+\t}\n+\n+\tprivate void decode() {\n+\t\t// FIXME: handle I/O errors\n+\t\tif (raw != null) {\n+\t\t\ttry {\n+\t\t\t\tBufferedReader br = new BufferedReader(new InputStreamReader(\n+\t\t\t\t\t\tnew ByteArrayInputStream(raw)));\n+\t\t\t\tString n = br.readLine();\n+\t\t\t\tif (n == null || !n.startsWith(\"object \")) {\n+\t\t\t\t\tthrow new CorruptObjectException(tagId, \"no object\");\n+\t\t\t\t}\n+\t\t\t\tobjId = new ObjectId(n.substring(7));\n+\t\t\t\tn = br.readLine();\n+\t\t\t\tif (n == null || !n.startsWith(\"type \")) {\n+\t\t\t\t\tthrow new CorruptObjectException(tagId, \"no type\");\n+\t\t\t\t}\n+\t\t\t\ttype = n.substring(\"type \".length());\n+\t\t\t\tn = br.readLine();\n+\n+\t\t\t\tif (n == null || !n.startsWith(\"tag \")) {\n+\t\t\t\t\tthrow new CorruptObjectException(tagId, \"no tag name\");\n+\t\t\t\t}\n+\t\t\t\ttag = n.substring(\"tag \".length());\n+\t\t\t\tn = br.readLine();\n+\n+\t\t\t\tif (n == null || !n.startsWith(\"tagger \")) {\n+\t\t\t\t\tthrow new CorruptObjectException(tagId, \"no tagger\");\n+\t\t\t\t}\n+\t\t\t\ttagger = new PersonIdent(n.substring(\"tagger \".length()));\n+\n+\t\t\t\tn = br.readLine();\n+\t\t\t\tif (n == null || !n.equals(\"\")) {\n+\t\t\t\t\tthrow new CorruptObjectException(tagId,\n+\t\t\t\t\t\t\t\"malformed header\");\n+\t\t\t\t}\n+\t\t\t\tStringBuffer tempMessage = new StringBuffer();\n+\t\t\t\tchar[] readBuf = new char[2048];\n+\t\t\t\tint readLen;\n+\t\t\t\twhile ((readLen = br.read(readBuf)) > 0) {\n+\t\t\t\t\ttempMessage.append(readBuf, 0, readLen);\n+\t\t\t\t}\n+\t\t\t\tmessage = tempMessage.toString();\n+\t\t\t} catch (IOException e) {\n+\t\t\t\te.printStackTrace();\n+\t\t\t} finally {\n+\t\t\t\traw = null;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tpublic void setMessage(final String m) {\n+\t\tmessage = m;\n+\t}\n+\n+\tpublic void tag() throws IOException {\n+\t\tif (getTagId() != null)\n+\t\t\tthrow new IllegalStateException(\"exists \" + getTagId());\n+\t\tsetTagId(new ObjectWriter(objdb).writeTag(this));\n+\t}\n+\n+\tpublic String toString() {\n+\t\treturn \"tag[\" + getTag() + getType() + getObjId() + \" \" + getAuthor() + \"]\";\n+\t}\n+\n+\tpublic ObjectId getTagId() {\n+\t\treturn tagId;\n+\t}\n+\n+\tpublic void setTagId(ObjectId tagId) {\n+\t\tthis.tagId = tagId;\n+\t}\n+\n+\tpublic PersonIdent getTagger() {\n+\t\tdecode();\n+\t\treturn tagger;\n+\t}\n+\n+\tpublic void setTagger(PersonIdent tagger) {\n+\t\tthis.tagger = tagger;\n+\t}\n+\n+\tpublic String getType() {\n+\t\tdecode();\n+\t\treturn type;\n+\t}\n+\n+\tpublic void setType(String type) {\n+\t\tthis.type = type;\n+\t}\n+\t\n+\tpublic String getTag() {\n+\t\treturn tag;\n+\t}\n+\n+\tpublic void setTag(String tag) {\n+\t\tthis.tag = tag;\n+\t}\n+\n+\tpublic ObjectId getObjId() {\n+\t\treturn objId;\n+\t}\n+\n+\tpublic void setObjId(ObjectId objId) {\n+\t\tthis.objId = objId;\n+\t}\n+}\ndiff --git a/org.spearce.jgit/tst/org/spearce/jgit/lib/T0003_Basic.java b/org.spearce.jgit/tst/org/spearce/jgit/lib/T0003_Basic.java\nindex a1bf803..0b135b1 100644\n--- a/org.spearce.jgit/tst/org/spearce/jgit/lib/T0003_Basic.java\n+++ b/org.spearce.jgit/tst/org/spearce/jgit/lib/T0003_Basic.java\n@@ -319,4 +319,70 @@ public class T0003_Basic extends RepositoryTestCase {\n \t\tassertEquals(new ObjectId(\"b47a8f0a4190f7572e11212769090523e23eb1ea\"),\n \t\t\t\tt.getId());\n \t}\n+\t\n+\tpublic void test020_createBlobTag() throws IOException {\n+\t\tfinal ObjectId emptyId = new ObjectWriter(db).writeBlob(new byte[0]);\n+\t\tfinal Tag t = new Tag(db);\n+\t\tt.setObjId(emptyId);\n+\t\tt.setType(\"blob\");\n+\t\tt.setTag(\"test020\");\n+\t\tt.setAuthor(new PersonIdent(jauthor, 1154236443000L, -4 * 60));\n+\t\tt.setMessage(\"test020 tagged\\n\");\n+\t\tt.tag();\n+\t\tassertEquals(\"6759556b09fbb4fd8ae5e315134481cc25d46954\", t.getTagId().toString());\n+\n+\t\tTag mapTag = db.mapTag(\"6759556b09fbb4fd8ae5e315134481cc25d46954\");\n+\t\tassertEquals(\"blob\", mapTag.getType());\n+\t\tassertEquals(\"test020 tagged\\n\", mapTag.getMessage());\n+\t\tassertEquals(new PersonIdent(jauthor, 1154236443000L, -4 * 60), mapTag.getAuthor());\n+\t\tassertEquals(\"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\", mapTag.getObjId().toString());\n+\t}\n+\n+\tpublic void test021_createTreeTag() throws IOException {\n+\t\tfinal ObjectId emptyId = new ObjectWriter(db).writeBlob(new byte[0]);\n+\t\tfinal Tree almostEmptyTree = new Tree(db);\n+\t\talmostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId, \"empty\".getBytes(), false));\n+\t\tfinal ObjectId almostEmptyTreeId = new ObjectWriter(db).writeTree(almostEmptyTree);\n+\t\tfinal Tag t = new Tag(db);\n+\t\tt.setObjId(almostEmptyTreeId);\n+\t\tt.setType(\"tree\");\n+\t\tt.setTag(\"test021\");\n+\t\tt.setAuthor(new PersonIdent(jauthor, 1154236443000L, -4 * 60));\n+\t\tt.setMessage(\"test021 tagged\\n\");\n+\t\tt.tag();\n+\t\tassertEquals(\"b0517bc8dbe2096b419d42424cd7030733f4abe5\", t.getTagId().toString());\n+\n+\t\tTag mapTag = db.mapTag(\"b0517bc8dbe2096b419d42424cd7030733f4abe5\");\n+\t\tassertEquals(\"tree\", mapTag.getType());\n+\t\tassertEquals(\"test021 tagged\\n\", mapTag.getMessage());\n+\t\tassertEquals(new PersonIdent(jauthor, 1154236443000L, -4 * 60), mapTag.getAuthor());\n+\t\tassertEquals(\"417c01c8795a35b8e835113a85a5c0c1c77f67fb\", mapTag.getObjId().toString());\n+\t}\n+\n+\tpublic void test022_createCommitTag() throws IOException {\n+\t\tfinal ObjectId emptyId = new ObjectWriter(db).writeBlob(new byte[0]);\n+\t\tfinal Tree almostEmptyTree = new Tree(db);\n+\t\talmostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId, \"empty\".getBytes(), false));\n+\t\tfinal ObjectId almostEmptyTreeId = new ObjectWriter(db).writeTree(almostEmptyTree);\n+\t\tfinal Commit almostEmptyCommit = new Commit(db);\n+\t\talmostEmptyCommit.setAuthor(new PersonIdent(jauthor, 1154236443000L, -2 * 60)); // not exactly the same\n+\t\talmostEmptyCommit.setCommitter(new PersonIdent(jauthor, 1154236443000L, -2 * 60));\n+\t\talmostEmptyCommit.setMessage(\"test022\\n\");\n+\t\talmostEmptyCommit.setTreeId(almostEmptyTreeId);\n+\t\tObjectId almostEmptyCommitId = new ObjectWriter(db).writeCommit(almostEmptyCommit);\n+\t\tfinal Tag t = new Tag(db);\n+\t\tt.setObjId(almostEmptyCommitId);\n+\t\tt.setType(\"commit\");\n+\t\tt.setTag(\"test022\");\n+\t\tt.setAuthor(new PersonIdent(jauthor, 1154236443000L, -4 * 60));\n+\t\tt.setMessage(\"test022 tagged\\n\");\n+\t\tt.tag();\n+\t\tassertEquals(\"0ce2ebdb36076ef0b38adbe077a07d43b43e3807\", t.getTagId().toString());\n+\n+\t\tTag mapTag = db.mapTag(\"0ce2ebdb36076ef0b38adbe077a07d43b43e3807\");\n+\t\tassertEquals(\"commit\", mapTag.getType());\n+\t\tassertEquals(\"test022 tagged\\n\", mapTag.getMessage());\n+\t\tassertEquals(new PersonIdent(jauthor, 1154236443000L, -4 * 60), mapTag.getAuthor());\n+\t\tassertEquals(\"b5d3b45a96b340441f5abb9080411705c51cc86c\", mapTag.getObjId().toString());\n+\t}\n }\n"},{"id":"35893","messageId":"20070228222647.12021.99818.stgit@lathund.dewire.com","threadId":"7025","inReplyTo":"20070228222355.12021.13029.stgit@lathund.dewire.com","subject":"[EGIT PATCH 8/9] Handle odd tag formats created by tools such as cvsimport.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2007-02-28T22:26:47Z","receivedAt":"2007-02-28T22:26:47Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"These lack a date and have a message without a newline\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n---\n\n .../src/org/spearce/jgit/lib/PersonIdent.java      |   68 +++++++++++++----------\n org.spearce.jgit/src/org/spearce/jgit/lib/Tag.java |    8 +-\n 2 files changed, 40 insertions(+), 36 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/PersonIdent.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PersonIdent.java\nindex bfcb34d..50a6a3b 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/PersonIdent.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PersonIdent.java\n@@ -24,7 +24,7 @@ public class PersonIdent {\n \n \tprivate final String emailAddress;\n \n-\tprivate final long when;\n+\tprivate final Long when;\n \n \tprivate final int tzOffset;\n \n@@ -43,7 +43,7 @@ public class PersonIdent {\n \tpublic PersonIdent(final PersonIdent pi, final Date aWhen) {\n \t\tname = pi.getName();\n \t\temailAddress = pi.getEmailAddress();\n-\t\twhen = aWhen.getTime();\n+\t\twhen = new Long(aWhen.getTime());\n \t\ttzOffset = pi.tzOffset;\n \t}\n \n@@ -51,22 +51,22 @@ public class PersonIdent {\n \t\t\tfinal Date aWhen, final TimeZone aTZ) {\n \t\tname = aName;\n \t\temailAddress = aEmailAddress;\n-\t\twhen = aWhen.getTime();\n-\t\ttzOffset = aTZ.getOffset(when) / (60 * 1000);\n+\t\twhen = new Long(aWhen.getTime());\n+\t\ttzOffset = aTZ.getOffset(when.longValue()) / (60 * 1000);\n \t}\n \n \tpublic PersonIdent(final String aName, final String aEmailAddress,\n \t\t\tfinal long aWhen, final int aTZ) {\n \t\tname = aName;\n \t\temailAddress = aEmailAddress;\n-\t\twhen = aWhen;\n+\t\twhen = new Long(aWhen);\n \t\ttzOffset = aTZ;\n \t}\n \n \tpublic PersonIdent(final PersonIdent pi, final long aWhen, final int aTZ) {\n \t\tname = pi.getName();\n \t\temailAddress = pi.getEmailAddress();\n-\t\twhen = aWhen;\n+\t\twhen = new Long(aWhen);\n \t\ttzOffset = aTZ;\n \t}\n \n@@ -83,22 +83,23 @@ public class PersonIdent {\n \t\t}\n \t\tfinal int sp = in.indexOf(' ', gt + 2);\n \t\tif (sp == -1) {\n-\t\t\tthrow new IllegalArgumentException(\"Malformed PersonIdent string\"\n-\t\t\t\t\t+ \" (no time zone found): \" + in);\n-\t\t}\n-\t\tfinal String tzHoursStr = in.substring(sp + 1, sp + 4).trim();\n-\t\tfinal int tzHours;\n-\t\tif (tzHoursStr.charAt(0) == '+') {\n-\t\t\ttzHours = Integer.parseInt(tzHoursStr.substring(1));\n+\t\t\twhen = null;\n+\t\t\ttzOffset = -1;\n \t\t} else {\n-\t\t\ttzHours = Integer.parseInt(tzHoursStr);\n+\t\t\tfinal String tzHoursStr = in.substring(sp + 1, sp + 4).trim();\n+\t\t\tfinal int tzHours;\n+\t\t\tif (tzHoursStr.charAt(0) == '+') {\n+\t\t\t\ttzHours = Integer.parseInt(tzHoursStr.substring(1));\n+\t\t\t} else {\n+\t\t\t\ttzHours = Integer.parseInt(tzHoursStr);\n+\t\t\t}\n+\t\t\tfinal int tzMins = Integer.parseInt(in.substring(sp + 4).trim());\n+\t\t\twhen = new Long(Long.parseLong(in.substring(gt + 1, sp).trim()) * 1000);\n+\t\t\ttzOffset = tzHours * 60 + tzMins;\n \t\t}\n-\t\tfinal int tzMins = Integer.parseInt(in.substring(sp + 4).trim());\n \n \t\tname = in.substring(0, lt).trim();\n \t\temailAddress = in.substring(lt + 1, gt).trim();\n-\t\twhen = Long.parseLong(in.substring(gt + 1, sp).trim()) * 1000;\n-\t\ttzOffset = tzHours * 60 + tzMins;\n \t}\n \n \tpublic String getName() {\n@@ -110,11 +111,13 @@ public class PersonIdent {\n \t}\n \n \tpublic Date getWhen() {\n-\t\treturn new Date(when);\n+\t\tif (when != null)\n+\t\t\treturn new Date(when.longValue());\n+\t\treturn null;\n \t}\n \n \tpublic int hashCode() {\n-\t\treturn getEmailAddress().hashCode() ^ ((int) when);\n+\t\treturn getEmailAddress().hashCode() ^ (when.intValue());\n \t}\n \n \tpublic boolean equals(final Object o) {\n@@ -148,18 +151,19 @@ public class PersonIdent {\n \t\tr.append(\" <\");\n \t\tr.append(getEmailAddress());\n \t\tr.append(\"> \");\n-\t\tr.append(when / 1000);\n-\t\tr.append(' ');\n-\t\tr.append(sign);\n-\t\tif (offsetHours < 10) {\n-\t\t\tr.append('0');\n-\t\t}\n-\t\tr.append(offsetHours);\n-\t\tif (offsetMins < 10) {\n-\t\t\tr.append('0');\n+\t\tif (when != null) {\n+\t\t\tr.append(when.longValue() / 1000);\n+\t\t\tr.append(' ');\n+\t\t\tr.append(sign);\n+\t\t\tif (offsetHours < 10) {\n+\t\t\t\tr.append('0');\n+\t\t\t}\n+\t\t\tr.append(offsetHours);\n+\t\t\tif (offsetMins < 10) {\n+\t\t\t\tr.append('0');\n+\t\t\t}\n+\t\t\tr.append(offsetMins);\n \t\t}\n-\t\tr.append(offsetMins);\n-\n \t\treturn r.toString();\n \t}\n \n@@ -176,7 +180,9 @@ public class PersonIdent {\n \t\tr.append(\", \");\n \t\tr.append(getEmailAddress());\n \t\tr.append(\", \");\n-\t\tr.append(new Date(when + minutes * 60));\n+\t\tif (when != null) {\n+\t\t\tr.append(new Date(when.longValue() + minutes * 60));\n+\t\t}\n \t\tr.append(\"]\");\n \n \t\treturn r.toString();\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Tag.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Tag.java\nindex d9e6990..cd59ee9 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Tag.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Tag.java\n@@ -94,11 +94,7 @@ public class Tag {\n \t\t\t\t}\n \t\t\t\ttagger = new PersonIdent(n.substring(\"tagger \".length()));\n \n-\t\t\t\tn = br.readLine();\n-\t\t\t\tif (n == null || !n.equals(\"\")) {\n-\t\t\t\t\tthrow new CorruptObjectException(tagId,\n-\t\t\t\t\t\t\t\"malformed header\");\n-\t\t\t\t}\n+\t\t\t\t// Message should start with an empty line, but\n \t\t\t\tStringBuffer tempMessage = new StringBuffer();\n \t\t\t\tchar[] readBuf = new char[2048];\n \t\t\t\tint readLen;\n@@ -106,6 +102,8 @@ public class Tag {\n \t\t\t\t\ttempMessage.append(readBuf, 0, readLen);\n \t\t\t\t}\n \t\t\t\tmessage = tempMessage.toString();\n+\t\t\t\tif (message.startsWith(\"\\n\"))\n+\t\t\t\t\tmessage = message.substring(1);\n \t\t\t} catch (IOException e) {\n \t\t\t\te.printStackTrace();\n \t\t\t} finally {\n"},{"id":"35892","messageId":"20070228222653.12021.55186.stgit@lathund.dewire.com","threadId":"7025","inReplyTo":"20070228222355.12021.13029.stgit@lathund.dewire.com","subject":"[EGIT PATCH 9/9] Performance test for jgit.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2007-02-28T22:26:53Z","receivedAt":"2007-02-28T22:26:53Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"Having these things is a test suite is dubious, but useful\nanyway.\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n---\n\n .../tst/org/spearce/jgit/lib/SpeedTestBase.java    |   48 ++++++++++++++++\n .../spearce/jgit/lib/T0005_ShallowSpeedTest.java   |   67 ++++++++++++++++++++++\n .../org/spearce/jgit/lib/T0006_DeepSpeedTest.java  |   70 +++++++++++++++++++++++\n 3 files changed, 185 insertions(+), 0 deletions(-)\n\ndiff --git a/org.spearce.jgit/tst/org/spearce/jgit/lib/SpeedTestBase.java b/org.spearce.jgit/tst/org/spearce/jgit/lib/SpeedTestBase.java\nnew file mode 100644\nindex 0000000..6601407\n--- /dev/null\n+++ b/org.spearce.jgit/tst/org/spearce/jgit/lib/SpeedTestBase.java\n@@ -0,0 +1,48 @@\n+package org.spearce.jgit.lib;\n+\n+import java.io.BufferedReader;\n+import java.io.File;\n+import java.io.FileReader;\n+import java.io.IOException;\n+import java.io.InputStream;\n+\n+import junit.framework.TestCase;\n+\n+public abstract class SpeedTestBase extends TestCase {\n+\tprotected long nativeTime;\n+\tprotected String kernelrepo;\n+\n+\tprotected void prepare(String[] refcmd) throws Exception {\n+\t\ttry {\n+\t\t\tBufferedReader bufferedReader = new BufferedReader(new FileReader(\"kernel.ref\"));\n+\t\t\tkernelrepo = bufferedReader.readLine();\n+\t\t\tbufferedReader.close();\n+\t\t\ttimeNativeGit(kernelrepo, refcmd);\n+\t\t\tnativeTime = timeNativeGit(kernelrepo, refcmd);\n+\t\t} catch (Exception e) {\n+\t\t\tSystem.out.println(\"Create a file named kernel.ref and put the path to the Linux kernels repository there\");\n+\t\t\tthrow e;\n+\t\t}\n+\t}\n+\n+\tprivate static long timeNativeGit(String kernelrepo, String[] refcmd) throws IOException,\n+\t\t\tInterruptedException, Exception {\n+\t\tlong start = System.currentTimeMillis();\n+\t\tProcess p = Runtime.getRuntime().exec(refcmd, null, new File(kernelrepo,\"..\"));\n+\t\tInputStream inputStream = p.getInputStream();\n+\t\tInputStream errorStream = p.getErrorStream();\n+\t\tbyte[] buf=new byte[1024*1024];\n+\t\twhile (inputStream.read(buf)>=0)\n+\t\t\t; // empty\n+\t\tif (p.waitFor()!=0) {\n+\t\t\tint c;\n+\t\t\twhile ((c=errorStream.read())!=-1)\n+\t\t\t\tSystem.err.print((char)c);\n+\t\t\tthrow new Exception(\"git log failed\");\n+\t\t}\n+\t\tinputStream.close();\n+\t\terrorStream.close();\n+\t\tlong stop = System.currentTimeMillis();\n+\t\treturn stop - start;\n+\t}\n+}\ndiff --git a/org.spearce.jgit/tst/org/spearce/jgit/lib/T0005_ShallowSpeedTest.java b/org.spearce.jgit/tst/org/spearce/jgit/lib/T0005_ShallowSpeedTest.java\nnew file mode 100644\nindex 0000000..7187e9a\n--- /dev/null\n+++ b/org.spearce.jgit/tst/org/spearce/jgit/lib/T0005_ShallowSpeedTest.java\n@@ -0,0 +1,67 @@\n+/*\n+ *  Copyright (C) 2006  Robin Rosenberg <robin.rosenberg@dewire.com>\n+ *\n+ *  This library is free software; you can redistribute it and/or\n+ *  modify it under the terms of the GNU Lesser General Public\n+ *  License, version 2.1, as published by the Free Software Foundation.\n+ *\n+ *  This library is distributed in the hope that it will be useful,\n+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+ *  Lesser General Public License for more details.\n+ *\n+ *  You should have received a copy of the GNU Lesser General Public\n+ *  License along with this library; if not, write to the Free Software\n+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301\n+ */\n+package org.spearce.jgit.lib;\n+\n+import java.io.File;\n+import java.io.IOException;\n+import java.util.List;\n+\n+import junit.textui.TestRunner;\n+\n+public class T0005_ShallowSpeedTest extends SpeedTestBase {\n+\n+\tprotected void setUp() throws Exception {\n+\t\tprepare(new String[] { \"git\", \"rev-list\", \"365bbe0d0caaf2ba74d56556827babf0bc66965d\" });\n+\t}\n+\n+\tpublic void testShallowHistoryScan() throws IOException {\n+\t\tlong start = System.currentTimeMillis();\n+\t\tRepository db = new Repository(new File(kernelrepo));\n+\t\tCommit commit = db.mapCommit(\"365bbe0d0caaf2ba74d56556827babf0bc66965d\");\n+\t\tint n = 1;\n+\t\tdo {\n+\t\t\t// System.out.println(\"commit=\"+commit.getCommitId());\n+\t\t\tList parent = commit.getParentIds();\n+\t\t\tif (parent.size() > 0) {\n+\t\t\t\tObjectId parentId = (ObjectId) parent.get(0);\n+\t\t\t\tcommit = db.mapCommit(parentId);\n+\t\t\t\tcommit.getCommitId().toString();\n+\t\t\t\t++n;\n+\t\t\t} else {\n+\t\t\t\tcommit = null;\n+\t\t\t}\n+\t\t} while (commit != null);\n+\t\tassertEquals(12275, n);\n+\t\tlong stop = System.currentTimeMillis();\n+\t\tlong time = stop - start;\n+\t\tSystem.out.println(\"native=\"+nativeTime);\n+\t\tSystem.out.println(\"jgit=\"+time);\n+\t\t// ~0.750s (hot cache), ok\n+\t\t/*\n+native=1748\n+jgit=774\n+\t\t */\n+\t\t// native git seems to run SLOWER than jgit here, at roughly half the speed\n+\t\t// creating the git process is not the issue here, btw. \n+\t\tlong factor10 = (nativeTime*110/time+50)/100;\n+\t\tassertEquals(2, factor10);\n+\t}\n+\n+\tpublic static void main(String[] args) {\n+\t\tTestRunner.run(T0005_ShallowSpeedTest.class);\n+\t}\n+}\ndiff --git a/org.spearce.jgit/tst/org/spearce/jgit/lib/T0006_DeepSpeedTest.java b/org.spearce.jgit/tst/org/spearce/jgit/lib/T0006_DeepSpeedTest.java\nnew file mode 100644\nindex 0000000..5bd480c\n--- /dev/null\n+++ b/org.spearce.jgit/tst/org/spearce/jgit/lib/T0006_DeepSpeedTest.java\n@@ -0,0 +1,70 @@\n+/*\n+ *  Copyright (C) 2006  Shawn Pearce <spearce@spearce.org>\n+ *\n+ *  This library is free software; you can redistribute it and/or\n+ *  modify it under the terms of the GNU Lesser General Public\n+ *  License, version 2.1, as published by the Free Software Foundation.\n+ *\n+ *  This library is distributed in the hope that it will be useful,\n+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+ *  Lesser General Public License for more details.\n+ *\n+ *  You should have received a copy of the GNU Lesser General Public\n+ *  License along with this library; if not, write to the Free Software\n+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301\n+ */\n+package org.spearce.jgit.lib;\n+\n+import java.io.File;\n+import java.io.IOException;\n+import java.util.List;\n+\n+import junit.textui.TestRunner;\n+\n+public class T0006_DeepSpeedTest extends SpeedTestBase {\n+\n+\tprotected void setUp() throws Exception {\n+\t\tprepare(new String[] { \"git\", \"rev-list\", \"365bbe0d0caaf2ba74d56556827babf0bc66965d\",\"--\",\"net/netfilter/nf_queue.c\" });\n+\t}\n+\n+\tpublic void testDeepHistoryScan() throws IOException {\t\n+\t\tlong start = System.currentTimeMillis();\n+\t\tRepository db = new Repository(new File(kernelrepo));\n+\t\tCommit commit = db.mapCommit(\"365bbe0d0caaf2ba74d56556827babf0bc66965d\");\n+\t\tint n = 1;\n+\t\tdo {\n+\t\t\t// System.out.println(\"commit=\"+commit.getCommitId());\n+\t\t\tList parent = commit.getParentIds();\n+\t\t\tif (parent.size() > 0) {\n+\t\t\t\tObjectId parentId = (ObjectId) parent.get(0);\n+\t\t\t\tcommit = db.mapCommit(parentId);\n+\t\t\t\tTreeEntry m = commit.getTree().findMember(\"net/netfilter/nf_queue.c\");\n+\t\t\t\tif (m != null)\n+\t\t\t\t\tcommit.getCommitId().toString();\n+\t\t\t\t++n;\n+\t\t\t} else {\n+\t\t\t\tcommit = null;\n+\t\t\t}\n+\t\t} while (commit != null);\n+\t\t// \n+\t\tassertEquals(12275, n);\n+\t\tlong stop = System.currentTimeMillis();\n+\t\tlong time = stop - start;\n+\t\tSystem.out.println(\"native=\"+nativeTime);\n+\t\tSystem.out.println(\"jgit=\"+time);\n+\t\t/*\n+\t\tnative=1355\n+\t\tjgit=5449\n+\t\t */\n+\t\t// This is not an exact factor, but we'd expect native git to perform this \n+\t\t// about 4 times quicker. If for some reason we find jgit to be faster than\n+\t\t// this the cause should be found and secured.\n+\t\tlong factor = (time*110/nativeTime+50)/100;\n+\t\tassertEquals(4, factor);\n+\t}\n+\n+\tpublic static void main(String[] args) {\n+\t\tTestRunner.run(T0006_DeepSpeedTest.class);\n+\t}\n+}\n"},{"id":"35914","messageId":"20070301035909.GA8103@spearce.org","threadId":"7025","inReplyTo":"20070228222637.12021.63285.stgit@lathund.dewire.com","subject":"Re: [EGIT PATCH 6/9] Add branch and StGit patch to decorator","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-03-01T03:59:10Z","receivedAt":"2007-03-01T03:59:10Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Robin Rosenberg <robin.rosenberg@dewire.com> wrote:\n> +\tpublic String getPatch() throws IOException {\n> +\t\tfinal File ptr = new File(getDirectory(),\"patches/\"+getBranch()+\"/current\");\n> +\t\tfinal BufferedReader br = new BufferedReader(new FileReader(ptr));\n> +\t\tfinal String line = br.readLine();\n> +\t\treturn line;\n> +\t}\n\nLast time I checked leaking a file descriptor was a bad idea.\nI fixed it (in both methods) when I applied the patch.\n\nYour whole series is now pushed. Thanks for the cleanups.\n\n-- \nShawn.\n"},{"id":"35930","messageId":"200703010922.18149.robin.rosenberg@dewire.com","threadId":"7025","inReplyTo":"20070301035909.GA8103@spearce.org","subject":"Re: [EGIT PATCH 6/9] Add branch and StGit patch to decorator","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2007-03-01T08:22:17Z","receivedAt":"2007-03-01T08:22:17Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"torsdag 01 mars 2007 04:59 skrev Shawn O. Pearce:\n> Robin Rosenberg <robin.rosenberg@dewire.com> wrote:\n> > +\tpublic String getPatch() throws IOException {\n> > +\t\tfinal File ptr = new File(getDirectory(),\"patches/\"+getBranch()+\"/current\");\n> > +\t\tfinal BufferedReader br = new BufferedReader(new FileReader(ptr));\n> > +\t\tfinal String line = br.readLine();\n> > +\t\treturn line;\n> > +\t}\n> \n> Last time I checked leaking a file descriptor was a bad idea.\nIt's a hallmark of mine. Sooner or later the GC picks them up :), but you're right.\n\n> I fixed it (in both methods) when I applied the patch.\n> \n> Your whole series is now pushed. Thanks for the cleanups.\n> \n\n-- robin\n"}]}