{"thread":{"id":"18294","subject":"[JGIT PATCH 1/5] Show critical flags in debug toString() descriptions of rev queues","startedAt":"2009-03-13T02:07:37Z","lastAt":"2009-03-16T14:33:59Z","messageCount":13,"participants":["Shawn O. Pearce","Robin Rosenberg"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"107891","messageId":"1236910062-18476-1-git-send-email-spearce@spearce.org","threadId":"18294","inReplyTo":null,"subject":"[JGIT PATCH 0/5] RevWalk fixes for UNINTERESTING","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-13T02:07:37Z","receivedAt":"2009-03-13T02:07:37Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Today I uncovered some ugly cases with \"jgit rev-list B ^A\", where\nsome commits reachable from A were still being output, even though\nwe asked that they be excluded.\n\nThis series attempts to fix it by forcing date ordering, and delaying\noutput a little to try and work over any clock skew discovered near\nthe end of the traversal, just before we give up.\n\nShawn O. Pearce (5):\n  Show critical flags in debug toString() descriptions of rev queues\n  Make RevObject.getType implementations final\n  Remove the horribly stupid RevSort.START_ORDER\n  Fix RevWalk with Linus Torvald's occasional bad commit date hack\n  Avoid incorrect output of UNINTERESTING commits when clock skew\n    occurs\n\n .../org/spearce/jgit/revwalk/AbstractRevQueue.java |    5 +\n .../src/org/spearce/jgit/revwalk/DateRevQueue.java |   10 +--\n .../org/spearce/jgit/revwalk/DelayRevQueue.java    |   92 ++++++++++++++++++++\n .../src/org/spearce/jgit/revwalk/FIFORevQueue.java |   10 +--\n .../jgit/revwalk/FixUninterestingGenerator.java    |   77 ++++++++++++++++\n .../src/org/spearce/jgit/revwalk/LIFORevQueue.java |   10 +--\n .../org/spearce/jgit/revwalk/PendingGenerator.java |   59 +++++++++++--\n .../src/org/spearce/jgit/revwalk/RevBlob.java      |    2 +-\n .../src/org/spearce/jgit/revwalk/RevCommit.java    |   15 +++-\n .../src/org/spearce/jgit/revwalk/RevObject.java    |   24 +++++\n .../src/org/spearce/jgit/revwalk/RevSort.java      |   11 ---\n .../src/org/spearce/jgit/revwalk/RevTag.java       |    2 +-\n .../src/org/spearce/jgit/revwalk/RevTree.java      |    2 +-\n .../src/org/spearce/jgit/revwalk/RevWalk.java      |    6 +-\n .../org/spearce/jgit/revwalk/StartGenerator.java   |   27 ++++--\n 15 files changed, 296 insertions(+), 56 deletions(-)\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/revwalk/DelayRevQueue.java\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/revwalk/FixUninterestingGenerator.java\n"},{"id":"107890","messageId":"1236910062-18476-2-git-send-email-spearce@spearce.org","threadId":"18294","inReplyTo":"1236910062-18476-1-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 1/5] Show critical flags in debug toString() descriptions of rev queues","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-13T02:07:38Z","receivedAt":"2009-03-13T02:07:38Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"These can help identify the state of each object, especially the\nimportant UNINTERESTING flag being present (or not).\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../org/spearce/jgit/revwalk/AbstractRevQueue.java |    5 ++++\n .../src/org/spearce/jgit/revwalk/DateRevQueue.java |   10 ++------\n .../src/org/spearce/jgit/revwalk/FIFORevQueue.java |   10 ++------\n .../src/org/spearce/jgit/revwalk/LIFORevQueue.java |   10 ++------\n .../src/org/spearce/jgit/revwalk/RevCommit.java    |   12 ++++++++++\n .../src/org/spearce/jgit/revwalk/RevObject.java    |   23 ++++++++++++++++++++\n 6 files changed, 49 insertions(+), 21 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/AbstractRevQueue.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/AbstractRevQueue.java\nindex 4cf7dae..5bb969d 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/AbstractRevQueue.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/AbstractRevQueue.java\n@@ -115,6 +115,11 @@ int outputType() {\n \t\treturn outputType;\n \t}\n \n+\tprotected static void describe(final StringBuilder s, final RevCommit c) {\n+\t\ts.append(c.toString());\n+\t\ts.append('\\n');\n+\t}\n+\n \tprivate static class AlwaysEmptyQueue extends AbstractRevQueue {\n \t\t@Override\n \t\tpublic void add(RevCommit c) {\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/DateRevQueue.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/DateRevQueue.java\nindex f797477..210f985 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/DateRevQueue.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/DateRevQueue.java\n@@ -126,13 +126,9 @@ int outputType() {\n \t}\n \n \tpublic String toString() {\n-\t\tfinal StringBuffer s = new StringBuffer();\n-\t\tfor (Entry q = head; q != null; q = q.next) {\n-\t\t\ts.append(q.commit.name());\n-\t\t\ts.append(' ');\n-\t\t\ts.append(q.commit.commitTime);\n-\t\t\ts.append('\\n');\n-\t\t}\n+\t\tfinal StringBuilder s = new StringBuilder();\n+\t\tfor (Entry q = head; q != null; q = q.next)\n+\t\t\tdescribe(s, q.commit);\n \t\treturn s.toString();\n \t}\n \ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/FIFORevQueue.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/FIFORevQueue.java\nindex 2c4c003..f086928 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/FIFORevQueue.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/FIFORevQueue.java\n@@ -149,14 +149,10 @@ void removeFlag(final int f) {\n \t}\n \n \tpublic String toString() {\n-\t\tfinal StringBuffer s = new StringBuffer();\n+\t\tfinal StringBuilder s = new StringBuilder();\n \t\tfor (Block q = head; q != null; q = q.next) {\n-\t\t\tfor (int i = q.headIndex; i < q.tailIndex; i++) {\n-\t\t\t\ts.append(q.commits[i].name());\n-\t\t\t\ts.append(' ');\n-\t\t\t\ts.append(q.commits[i].commitTime);\n-\t\t\t\ts.append('\\n');\n-\t\t\t}\n+\t\t\tfor (int i = q.headIndex; i < q.tailIndex; i++)\n+\t\t\t\tdescribe(s, q.commits[i]);\n \t\t}\n \t\treturn s.toString();\n \t}\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/LIFORevQueue.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/LIFORevQueue.java\nindex 5e885c0..045f7f1 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/LIFORevQueue.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/LIFORevQueue.java\n@@ -104,14 +104,10 @@ boolean anybodyHasFlag(final int f) {\n \t}\n \n \tpublic String toString() {\n-\t\tfinal StringBuffer s = new StringBuffer();\n+\t\tfinal StringBuilder s = new StringBuilder();\n \t\tfor (Block q = head; q != null; q = q.next) {\n-\t\t\tfor (int i = q.headIndex; i < q.tailIndex; i++) {\n-\t\t\t\ts.append(q.commits[i].name());\n-\t\t\t\ts.append(' ');\n-\t\t\t\ts.append(q.commits[i].commitTime);\n-\t\t\t\ts.append('\\n');\n-\t\t\t}\n+\t\t\tfor (int i = q.headIndex; i < q.tailIndex; i++)\n+\t\t\t\tdescribe(s, q.commits[i]);\n \t\t}\n \t\treturn s.toString();\n \t}\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevCommit.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevCommit.java\nindex de11c39..1b25fce 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevCommit.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevCommit.java\n@@ -388,4 +388,16 @@ public void dispose() {\n \t\tflags &= ~PARSED;\n \t\tbuffer = null;\n \t}\n+\n+\t@Override\n+\tpublic String toString() {\n+\t\tfinal StringBuilder s = new StringBuilder();\n+\t\ts.append(Constants.typeString(getType()));\n+\t\ts.append(name());\n+\t\ts.append(' ');\n+\t\ts.append(commitTime);\n+\t\ts.append(' ');\n+\t\tappendCoreFlags(s);\n+\t\treturn s.toString();\n+\t}\n }\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevObject.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevObject.java\nindex 451205c..7dadb7b 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevObject.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevObject.java\n@@ -167,4 +167,27 @@ public void remove(final RevFlagSet set) {\n \tpublic void dispose() {\n \t\t// Nothing needs to be done for most objects.\n \t}\n+\n+\t@Override\n+\tpublic String toString() {\n+\t\tfinal StringBuilder s = new StringBuilder();\n+\t\ts.append(Constants.typeString(getType()));\n+\t\ts.append(name());\n+\t\ts.append(' ');\n+\t\tappendCoreFlags(s);\n+\t\treturn s.toString();\n+\t}\n+\n+\t/**\n+\t * @param s\n+\t *            buffer to append a debug description of core RevFlags onto.\n+\t */\n+\tprotected void appendCoreFlags(final StringBuilder s) {\n+\t\ts.append((flags & RevWalk.TOPO_DELAY) != 0 ? 'o' : '-');\n+\t\ts.append((flags & RevWalk.TEMP_MARK) != 0 ? 't' : '-');\n+\t\ts.append((flags & RevWalk.REWRITE) != 0 ? 'r' : '-');\n+\t\ts.append((flags & RevWalk.UNINTERESTING) != 0 ? 'u' : '-');\n+\t\ts.append((flags & RevWalk.SEEN) != 0 ? 's' : '-');\n+\t\ts.append((flags & RevWalk.PARSED) != 0 ? 'p' : '-');\n+\t}\n }\n-- \n1.6.2.288.gc3f22\n"},{"id":"107892","messageId":"1236910062-18476-3-git-send-email-spearce@spearce.org","threadId":"18294","inReplyTo":"1236910062-18476-2-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 2/5] Make RevObject.getType implementations final","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-13T02:07:39Z","receivedAt":"2009-03-13T02:07:39Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"These methods should never be overridden once defined by the base\nclass of RevCommit, RevTree, RevBlob or RevTag.  An override is\nonly going to provide confusion to calls who rely upon the return\nvalue to know if a downcast is safe.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../src/org/spearce/jgit/revwalk/RevBlob.java      |    2 +-\n .../src/org/spearce/jgit/revwalk/RevCommit.java    |    3 ++-\n .../src/org/spearce/jgit/revwalk/RevObject.java    |    1 +\n .../src/org/spearce/jgit/revwalk/RevTag.java       |    2 +-\n .../src/org/spearce/jgit/revwalk/RevTree.java      |    2 +-\n 5 files changed, 6 insertions(+), 4 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevBlob.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevBlob.java\nindex 66cdc02..cf241cf 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevBlob.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevBlob.java\n@@ -58,7 +58,7 @@ void parse(final RevWalk walk) {\n \t}\n \t\n \t@Override\n-\tpublic int getType() {\n+\tpublic final int getType() {\n \t\treturn Constants.OBJ_BLOB;\n \t}\n }\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevCommit.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevCommit.java\nindex 1b25fce..2a59ec4 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevCommit.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevCommit.java\n@@ -139,7 +139,7 @@ else if (nParents == 1) {\n \t}\n \t\n \t@Override\n-\tpublic int getType() {\n+\tpublic final int getType() {\n \t\treturn Constants.OBJ_COMMIT;\n \t}\n \n@@ -393,6 +393,7 @@ public void dispose() {\n \tpublic String toString() {\n \t\tfinal StringBuilder s = new StringBuilder();\n \t\ts.append(Constants.typeString(getType()));\n+\t\ts.append(' ');\n \t\ts.append(name());\n \t\ts.append(' ');\n \t\ts.append(commitTime);\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevObject.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevObject.java\nindex 7dadb7b..8c7cc23 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevObject.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevObject.java\n@@ -172,6 +172,7 @@ public void dispose() {\n \tpublic String toString() {\n \t\tfinal StringBuilder s = new StringBuilder();\n \t\ts.append(Constants.typeString(getType()));\n+\t\ts.append(' ');\n \t\ts.append(name());\n \t\ts.append(' ');\n \t\tappendCoreFlags(s);\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevTag.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevTag.java\nindex aba8744..cace82d 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevTag.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevTag.java\n@@ -99,7 +99,7 @@ void parseCanonical(final RevWalk walk, final byte[] rawTag)\n \t}\n \n \t@Override\n-\tpublic int getType() {\n+\tpublic final int getType() {\n \t\treturn Constants.OBJ_TAG;\n \t}\n \ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevTree.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevTree.java\nindex e1cd4b5..4d767e4 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevTree.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevTree.java\n@@ -58,7 +58,7 @@ void parse(final RevWalk walk) {\n \t}\n \t\n \t@Override\n-\tpublic int getType() {\n+\tpublic final int getType() {\n \t\treturn Constants.OBJ_TREE;\n \t}\n }\n-- \n1.6.2.288.gc3f22\n"},{"id":"107894","messageId":"1236910062-18476-4-git-send-email-spearce@spearce.org","threadId":"18294","inReplyTo":"1236910062-18476-3-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 3/5] Remove the horribly stupid RevSort.START_ORDER","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-13T02:07:40Z","receivedAt":"2009-03-13T02:07:40Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"I must have been on crack the day I wrote 3b27268f49 (\"Allow RevWalk\nusers to ask for FIFO style ordering\").  Its a really bad idea.\n\nApplications can get themselves into a situation where they process\none branch long before another, and then abort too early, before all\ncommits have been correctly flagged UNINTERESTING.\n\nFor example, given the graph:\n\n  Z-A------------B\n  |             /\n  |    ---------\n  \\   /\n   Q-R-S-T-U-V\n\nIf B is \"interesting\" and A,V are UNINTERESTING, without forcing the\ncommit timestamp ordering in the pending queue we wind up processing\nall of B-Z, producing R,Q as \"interesting\" output in the process, and\nterminate before S can even be parsed. Consequently we never push the\nUNINTERESTING flag down onto R, and R,Q produced when they shouldn't.\n\nWe now require that the pending queue use a DateRevQueue instead of\nthe FIFORevQueue, so that in the above graph S must be parsed before\nwe can even consider R or A, even though R,A were reached earlier.\nThis of course still assumes there is no clock skew between S and R.\nThe next commit will address some limited clock skew issues.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../org/spearce/jgit/revwalk/PendingGenerator.java |    8 +++-----\n .../src/org/spearce/jgit/revwalk/RevSort.java      |   11 -----------\n .../src/org/spearce/jgit/revwalk/RevWalk.java      |    6 +++---\n .../org/spearce/jgit/revwalk/StartGenerator.java   |    8 ++------\n 4 files changed, 8 insertions(+), 25 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java\nindex 25b2966..144e909 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java\n@@ -62,7 +62,7 @@\n \n \tprivate final RevWalk walker;\n \n-\tprivate final AbstractRevQueue pending;\n+\tprivate final DateRevQueue pending;\n \n \tprivate final RevFilter filter;\n \n@@ -70,7 +70,7 @@\n \n \tboolean canDispose;\n \n-\tPendingGenerator(final RevWalk w, final AbstractRevQueue p,\n+\tPendingGenerator(final RevWalk w, final DateRevQueue p,\n \t\t\tfinal RevFilter f, final int out) {\n \t\twalker = w;\n \t\tpending = p;\n@@ -81,9 +81,7 @@ PendingGenerator(final RevWalk w, final AbstractRevQueue p,\n \n \t@Override\n \tint outputType() {\n-\t\tif (pending instanceof DateRevQueue)\n-\t\t\treturn output | SORT_COMMIT_TIME_DESC;\n-\t\treturn output;\n+\t\treturn output | SORT_COMMIT_TIME_DESC;\n \t}\n \n \t@Override\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevSort.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevSort.java\nindex b0a03ad..8c3eaed 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevSort.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevSort.java\n@@ -49,17 +49,6 @@\n \tNONE,\n \n \t/**\n-\t * Maintain the order commits were marked as starting points.\n-\t * <p>\n-\t * This strategy is largely a FIFO strategy; commits are enumerated in the\n-\t * order they were added to the RevWalk by the application. Parents not yet\n-\t * visited are added behind all commits already enqueued for visiting.\n-\t * <p>\n-\t * This strategy should not be combined with {@link #COMMIT_TIME_DESC}.\n-\t */\n-\tSTART_ORDER,\n-\n-\t/**\n \t * Sort by commit time, descending (newest first, oldest last).\n \t * <p>\n \t * This strategy can be combined with {@link #TOPO}.\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevWalk.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevWalk.java\nindex c8ec458..316f722 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevWalk.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevWalk.java\n@@ -187,7 +187,7 @@ public RevWalk(final Repository repo) {\n \t\tidBuffer = new MutableObjectId();\n \t\tobjects = new ObjectIdSubclassMap<RevObject>();\n \t\troots = new ArrayList<RevCommit>();\n-\t\tqueue = new FIFORevQueue();\n+\t\tqueue = new DateRevQueue();\n \t\tpending = new StartGenerator(this);\n \t\tsorting = EnumSet.of(RevSort.NONE);\n \t\tfilter = RevFilter.ALL;\n@@ -915,7 +915,7 @@ protected void reset(int retainFlags) {\n \n \t\tcurs.release();\n \t\troots.clear();\n-\t\tqueue = new FIFORevQueue();\n+\t\tqueue = new DateRevQueue();\n \t\tpending = new StartGenerator(this);\n \t}\n \n@@ -934,7 +934,7 @@ public void dispose() {\n \t\tobjects.clear();\n \t\tcurs.release();\n \t\troots.clear();\n-\t\tqueue = new FIFORevQueue();\n+\t\tqueue = new DateRevQueue();\n \t\tpending = new StartGenerator(this);\n \t}\n \ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/StartGenerator.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/StartGenerator.java\nindex 1b7947f..bf7067a 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/StartGenerator.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/StartGenerator.java\n@@ -108,11 +108,7 @@ RevCommit next() throws MissingObjectException,\n \t\t}\n \n \t\tint pendingOutputType = 0;\n-\t\tif (walker.hasRevSort(RevSort.START_ORDER)\n-\t\t\t\t&& !(q instanceof FIFORevQueue))\n-\t\t\tq = new FIFORevQueue(q);\n-\t\tif (walker.hasRevSort(RevSort.COMMIT_TIME_DESC)\n-\t\t\t\t&& !(q instanceof DateRevQueue))\n+\t\tif (!(q instanceof DateRevQueue))\n \t\t\tq = new DateRevQueue(q);\n \t\tif (tf != TreeFilter.ALL) {\n \t\t\trf = AndRevFilter.create(rf, new RewriteTreeFilter(w, tf));\n@@ -120,7 +116,7 @@ RevCommit next() throws MissingObjectException,\n \t\t}\n \n \t\twalker.queue = q;\n-\t\tg = new PendingGenerator(w, q, rf, pendingOutputType);\n+\t\tg = new PendingGenerator(w, (DateRevQueue) q, rf, pendingOutputType);\n \n \t\tif (boundary) {\n \t\t\t// Because the boundary generator may produce uninteresting\n-- \n1.6.2.288.gc3f22\n"},{"id":"107893","messageId":"1236910062-18476-5-git-send-email-spearce@spearce.org","threadId":"18294","inReplyTo":"1236910062-18476-4-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 4/5] Fix RevWalk with Linus Torvald's occasional bad commit date hack","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-13T02:07:41Z","receivedAt":"2009-03-13T02:07:41Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"In git-core commit 7d004199d134c9d465e013064f72dbc04507f6c0 Linus\ndescribes a hack he created to improve the handling of cases where\ncommit dates are out of order, such as a child commit having a date\nolder than its parent.  These cases can show up when there is bad\nimported data, or significant clock skew between distributed peers.\n\nThe original git-core bug report identified a failure in:\n\n  git rev-list A..B C\n\nwhere commits contained in both A and B were reported, due to out\nof order commit dates.\n\nWe keep running until the most recent commit in the pending queue\nis more recent than the last commit sent to the caller.  If the\npending queue suddenly goes \"backwards\" due to one of our parent's\nhaving a more recent commit date, this new check ensures we will\nkeep processing the graph until we see a more consistent cut.\n\nWe process an extra OVER_SCAN commits after we decide that all\nremaining commits are UNINTERESTING.  Processing these extra\ncommits ensures flags are carried back further in the graph,\nincreasing the chances that we correctly mark relevant nodes.\n\nAs a result of this hack, we may produce a commit to our caller,\nbut then later mark it UNINTERESTING if we discover date skew.\nTo handle such cases, callers could buffer produced commits and\nfilter out those that are UNINTERESTING, but this somewhat costly\nand may not always be necessary.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../org/spearce/jgit/revwalk/PendingGenerator.java |   51 ++++++++++++++++++--\n 1 files changed, 47 insertions(+), 4 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java\nindex 144e909..cd24e8f 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java\n@@ -42,6 +42,7 @@\n import org.spearce.jgit.errors.IncorrectObjectTypeException;\n import org.spearce.jgit.errors.MissingObjectException;\n import org.spearce.jgit.errors.StopWalkException;\n+import org.spearce.jgit.lib.ObjectId;\n import org.spearce.jgit.revwalk.filter.RevFilter;\n \n /**\n@@ -60,6 +61,24 @@\n \n \tprivate static final int UNINTERESTING = RevWalk.UNINTERESTING;\n \n+\t/**\n+\t * Number of additional commits to scan after we think we are done.\n+\t * <p>\n+\t * This small buffer of commits is scanned to ensure we didn't miss anything\n+\t * as a result of clock skew when the commits were made. We need to set our\n+\t * constant to 1 additional commit due to the use of a pre-increment\n+\t * operator when accessing the value.\n+\t */\n+\tprivate static final int OVER_SCAN = 5 + 1;\n+\n+\t/** A commit near the end of time, to initialize {@link #last} with. */\n+\tprivate static final RevCommit INIT_LAST;\n+\n+\tstatic {\n+\t\tINIT_LAST = new RevCommit(ObjectId.zeroId());\n+\t\tINIT_LAST.commitTime = Integer.MAX_VALUE;\n+\t}\n+\n \tprivate final RevWalk walker;\n \n \tprivate final DateRevQueue pending;\n@@ -68,6 +87,17 @@\n \n \tprivate final int output;\n \n+\t/** Last commit produced to the caller from {@link #next()}. */\n+\tprivate RevCommit last = INIT_LAST;\n+\n+\t/**\n+\t * Number of commits we have remaining in our over-scan allotment.\n+\t * <p>\n+\t * Only relevant if there are {@link #UNINTERESTING} commits in the\n+\t * {@link #pending} queue.\n+\t */\n+\tprivate int overScan = OVER_SCAN;\n+\n \tboolean canDispose;\n \n \tPendingGenerator(final RevWalk w, final DateRevQueue p,\n@@ -112,14 +142,27 @@ RevCommit next() throws MissingObjectException,\n \t\t\t\twalker.carryFlagsImpl(c);\n \n \t\t\t\tif ((c.flags & UNINTERESTING) != 0) {\n-\t\t\t\t\tif (pending.everbodyHasFlag(UNINTERESTING))\n-\t\t\t\t\t\tthrow StopWalkException.INSTANCE;\n-\t\t\t\t\tc.dispose();\n+\t\t\t\t\tif (pending.everbodyHasFlag(UNINTERESTING)) {\n+\t\t\t\t\t\tfinal RevCommit n = pending.peek();\n+\t\t\t\t\t\tif (n != null && n.commitTime <= last.commitTime) {\n+\t\t\t\t\t\t\t// This is too close to call. The next commit we\n+\t\t\t\t\t\t\t// would pop is before the last one we produced.\n+\t\t\t\t\t\t\t// We have to keep going to ensure that we carry\n+\t\t\t\t\t\t\t// flags as much as necessary.\n+\t\t\t\t\t\t\t//\n+\t\t\t\t\t\t\toverScan = OVER_SCAN;\n+\t\t\t\t\t\t} else if (--overScan == 0)\n+\t\t\t\t\t\t\tthrow StopWalkException.INSTANCE;\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\toverScan = OVER_SCAN;\n+\t\t\t\t\t}\n+\t\t\t\t\tif (canDispose)\n+\t\t\t\t\t\tc.dispose();\n \t\t\t\t\tcontinue;\n \t\t\t\t}\n \n \t\t\t\tif (produce)\n-\t\t\t\t\treturn c;\n+\t\t\t\t\treturn last = c;\n \t\t\t\telse if (canDispose)\n \t\t\t\t\tc.dispose();\n \t\t\t}\n-- \n1.6.2.288.gc3f22\n"},{"id":"107895","messageId":"1236910062-18476-6-git-send-email-spearce@spearce.org","threadId":"18294","inReplyTo":"1236910062-18476-5-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 5/5] Avoid incorrect output of UNINTERESTING commits when clock skew occurs","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-13T02:07:42Z","receivedAt":"2009-03-13T02:07:42Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"The prior commit added functionality to scan a few extra commits when\nwe otherwise would have aborted due to everything left being colored\nUNINTERESTING.  When that happens we may wind up coloring a commit\nthat we already produced to the caller, giving the caller an incorrect\nresult set.\n\nIf we insert a fully buffered generator in the pipeline, such as that\nused for RevSort.TOPO or RevSort.REVERSE, we can easily filter these\nlate-colored commits out before we show them to the application.  But\notherwise we delay the output by 6 commits, just long enough to give\nPendingGenerator a reasonable chance at getting the coloring right.\n\nThis is only an approximation.  It is still possible for commits to\nproduce when they should be UNINTERESTING, such as if more than the\nOVER_SCAN limit had clock skew between two branches and the common\nmerge base, even if we are fully buffering our output.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../org/spearce/jgit/revwalk/DelayRevQueue.java    |   92 ++++++++++++++++++++\n .../jgit/revwalk/FixUninterestingGenerator.java    |   77 ++++++++++++++++\n .../org/spearce/jgit/revwalk/PendingGenerator.java |    2 +-\n .../org/spearce/jgit/revwalk/StartGenerator.java   |   23 ++++-\n 4 files changed, 189 insertions(+), 5 deletions(-)\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/revwalk/DelayRevQueue.java\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/revwalk/FixUninterestingGenerator.java\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/DelayRevQueue.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/DelayRevQueue.java\nnew file mode 100644\nindex 0000000..1eb7064\n--- /dev/null\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/DelayRevQueue.java\n@@ -0,0 +1,92 @@\n+/*\n+ * Copyright (C) 2009, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import java.io.IOException;\n+\n+import org.spearce.jgit.errors.IncorrectObjectTypeException;\n+import org.spearce.jgit.errors.MissingObjectException;\n+\n+/**\n+ * Delays commits to be at least {@link PendingGenerator#OVER_SCAN} late.\n+ * <p>\n+ * This helps to \"fix up\" weird corner cases resulting from clock skew, by\n+ * slowing down what we produce to the caller we get a better chance to ensure\n+ * PendingGenerator reached back far enough in the graph to correctly mark\n+ * commits {@link RevWalk#UNINTERESTING} if necessary.\n+ * <p>\n+ * This generator should appear before {@link FixUninterestingGenerator} if the\n+ * lower level {@link #pending} isn't already fully buffered.\n+ */\n+final class DelayRevQueue extends Generator {\n+\tprivate static final int OVER_SCAN = PendingGenerator.OVER_SCAN;\n+\n+\tprivate final Generator pending;\n+\n+\tprivate final FIFORevQueue delay;\n+\n+\tprivate int size;\n+\n+\tDelayRevQueue(final Generator g) {\n+\t\tpending = g;\n+\t\tdelay = new FIFORevQueue();\n+\t}\n+\n+\t@Override\n+\tint outputType() {\n+\t\treturn pending.outputType();\n+\t}\n+\n+\t@Override\n+\tRevCommit next() throws MissingObjectException,\n+\t\t\tIncorrectObjectTypeException, IOException {\n+\t\twhile (size < OVER_SCAN) {\n+\t\t\tfinal RevCommit c = pending.next();\n+\t\t\tif (c == null)\n+\t\t\t\tbreak;\n+\t\t\tdelay.add(c);\n+\t\t\tsize++;\n+\t\t}\n+\n+\t\tfinal RevCommit c = delay.next();\n+\t\tif (c == null)\n+\t\t\treturn null;\n+\t\tsize--;\n+\t\treturn c;\n+\t}\n+}\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/FixUninterestingGenerator.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/FixUninterestingGenerator.java\nnew file mode 100644\nindex 0000000..6a9ba61\n--- /dev/null\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/FixUninterestingGenerator.java\n@@ -0,0 +1,77 @@\n+/*\n+ * Copyright (C) 2009, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import java.io.IOException;\n+\n+import org.spearce.jgit.errors.IncorrectObjectTypeException;\n+import org.spearce.jgit.errors.MissingObjectException;\n+\n+/**\n+ * Filters out commits marked {@link RevWalk#UNINTERESTING}.\n+ * <p>\n+ * This generator is only in front of another generator that has fully buffered\n+ * commits, such that we are called only after the {@link PendingGenerator} has\n+ * exhausted its input queue and given up. It skips over any uninteresting\n+ * commits that may have leaked out of the PendingGenerator due to clock skew\n+ * being detected in the commit objects.\n+ */\n+final class FixUninterestingGenerator extends Generator {\n+\tprivate final Generator pending;\n+\n+\tFixUninterestingGenerator(final Generator g) {\n+\t\tpending = g;\n+\t}\n+\n+\t@Override\n+\tint outputType() {\n+\t\treturn pending.outputType();\n+\t}\n+\n+\t@Override\n+\tRevCommit next() throws MissingObjectException,\n+\t\t\tIncorrectObjectTypeException, IOException {\n+\t\tfor (;;) {\n+\t\t\tfinal RevCommit c = pending.next();\n+\t\t\tif (c == null)\n+\t\t\t\treturn null;\n+\t\t\tif ((c.flags & RevWalk.UNINTERESTING) == 0)\n+\t\t\t\treturn c;\n+\t\t}\n+\t}\n+}\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java\nindex cd24e8f..ebbb39f 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java\n@@ -69,7 +69,7 @@\n \t * constant to 1 additional commit due to the use of a pre-increment\n \t * operator when accessing the value.\n \t */\n-\tprivate static final int OVER_SCAN = 5 + 1;\n+\tstatic final int OVER_SCAN = 5 + 1;\n \n \t/** A commit near the end of time, to initialize {@link #last} with. */\n \tprivate static final RevCommit INIT_LAST;\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/StartGenerator.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/StartGenerator.java\nindex bf7067a..3535250 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/StartGenerator.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/StartGenerator.java\n@@ -90,6 +90,7 @@ RevCommit next() throws MissingObjectException,\n \t\t\treturn mbg.next();\n \t\t}\n \n+\t\tfinal boolean uninteresting = q.anybodyHasFlag(RevWalk.UNINTERESTING);\n \t\tboolean boundary = walker.hasRevSort(RevSort.BOUNDARY);\n \n \t\tif (!boundary && walker instanceof ObjectWalk) {\n@@ -99,7 +100,7 @@ RevCommit next() throws MissingObjectException,\n \t\t\t//\n \t\t\tboundary = true;\n \t\t}\n-\t\tif (boundary && !q.anybodyHasFlag(RevWalk.UNINTERESTING)) {\n+\t\tif (boundary && !uninteresting) {\n \t\t\t// If we were not fed uninteresting commits we will never\n \t\t\t// construct a boundary. There is no reason to include the\n \t\t\t// extra overhead associated with that in our pipeline.\n@@ -107,16 +108,19 @@ RevCommit next() throws MissingObjectException,\n \t\t\tboundary = false;\n \t\t}\n \n+\t\tfinal DateRevQueue pending;\n \t\tint pendingOutputType = 0;\n-\t\tif (!(q instanceof DateRevQueue))\n-\t\t\tq = new DateRevQueue(q);\n+\t\tif (q instanceof DateRevQueue)\n+\t\t\tpending = (DateRevQueue)q;\n+\t\telse\n+\t\t\tpending = new DateRevQueue(q);\n \t\tif (tf != TreeFilter.ALL) {\n \t\t\trf = AndRevFilter.create(rf, new RewriteTreeFilter(w, tf));\n \t\t\tpendingOutputType |= HAS_REWRITE | NEEDS_REWRITE;\n \t\t}\n \n \t\twalker.queue = q;\n-\t\tg = new PendingGenerator(w, (DateRevQueue) q, rf, pendingOutputType);\n+\t\tg = new PendingGenerator(w, pending, rf, pendingOutputType);\n \n \t\tif (boundary) {\n \t\t\t// Because the boundary generator may produce uninteresting\n@@ -143,6 +147,17 @@ RevCommit next() throws MissingObjectException,\n \t\t\tg = new LIFORevQueue(g);\n \t\tif (boundary)\n \t\t\tg = new BoundaryGenerator(w, g);\n+\t\telse if (uninteresting) {\n+\t\t\t// Try to protect ourselves from uninteresting commits producing\n+\t\t\t// due to clock skew in the commit time stamps. Delay such that\n+\t\t\t// we have a chance at coloring enough of the graph correctly,\n+\t\t\t// and then strip any UNINTERESTING nodes that may have leaked\n+\t\t\t// through early.\n+\t\t\t//\n+\t\t\tif (pending.peek() != null)\n+\t\t\t\tg = new DelayRevQueue(g);\n+\t\t\tg = new FixUninterestingGenerator(g);\n+\t\t}\n \n \t\tw.pending = g;\n \t\treturn g.next();\n-- \n1.6.2.288.gc3f22\n"},{"id":"107979","messageId":"200903132100.26527.robin.rosenberg.lists@dewire.com","threadId":"18294","inReplyTo":"1236910062-18476-1-git-send-email-spearce@spearce.org","subject":"Re: [JGIT PATCH 0/5] RevWalk fixes for UNINTERESTING","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg.lists@dewire.com","sentAt":"2009-03-13T20:00:26Z","receivedAt":"2009-03-13T20:00:26Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"fredag 13 mars 2009 03:07:37 skrev \"Shawn O. Pearce\" <spearce@spearce.org>:\n> Today I uncovered some ugly cases with \"jgit rev-list B ^A\", where\n> some commits reachable from A were still being output, even though\n> we asked that they be excluded.\n\nHow about a test suite to prove this is better than before?\n\n-- robin\n"},{"id":"107984","messageId":"20090313223933.GH22920@spearce.org","threadId":"18294","inReplyTo":"200903132100.26527.robin.rosenberg.lists@dewire.com","subject":"[JGIT PATCH 0/6] Add tests for RevWalk and its supporting code","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-13T22:39:33Z","receivedAt":"2009-03-13T22:39:33Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"These new tests cover some of the common cases we see with using a\nRevWalk, and increase our code coverage in this critical area of\nthe JGit library.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n Robin Rosenberg <robin.rosenberg.lists@dewire.com> wrote:\n > fredag 13 mars 2009 03:07:37 skrev \"Shawn O. Pearce\" <spearce@spearce.org>:\n > > Today I uncovered some ugly cases with \"jgit rev-list B ^A\", where\n > > some commits reachable from A were still being output, even though\n > > we asked that they be excluded.\n > \n > How about a test suite to prove this is better than before?\n\n Its better.  :-)\n\n These tests don't pass before the series.  They pass after.\n \n .../org/spearce/jgit/revwalk/RevFlagSetTest.java   |  131 +++++++++++\n .../org/spearce/jgit/revwalk/RevWalkCullTest.java  |   75 +++++++\n .../spearce/jgit/revwalk/RevWalkFilterTest.java    |  233 ++++++++++++++++++++\n .../spearce/jgit/revwalk/RevWalkMergeBaseTest.java |  117 ++++++++++\n .../org/spearce/jgit/revwalk/RevWalkSortTest.java  |  164 ++++++++++++++\n .../org/spearce/jgit/revwalk/RevWalkTestCase.java  |  102 +++++++++\n 6 files changed, 822 insertions(+), 0 deletions(-)\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevFlagSetTest.java\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkCullTest.java\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkFilterTest.java\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkMergeBaseTest.java\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkSortTest.java\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkTestCase.java\n\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevFlagSetTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevFlagSetTest.java\nnew file mode 100644\nindex 0000000..76f3cbb\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevFlagSetTest.java\n@@ -0,0 +1,131 @@\n+/*\n+ * Copyright (C) 2008, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import java.util.Arrays;\n+import java.util.Iterator;\n+\n+public class RevFlagSetTest extends RevWalkTestCase {\n+\tpublic void testEmpty() {\n+\t\tfinal RevFlagSet set = new RevFlagSet();\n+\t\tassertEquals(0, set.mask);\n+\t\tassertEquals(0, set.size());\n+\t\tassertNotNull(set.iterator());\n+\t\tassertFalse(set.iterator().hasNext());\n+\t}\n+\n+\tpublic void testAddOne() {\n+\t\tfinal String flagName = \"flag\";\n+\t\tfinal RevFlag flag = rw.newFlag(flagName);\n+\t\tassertTrue(0 != flag.mask);\n+\t\tassertSame(flagName, flag.name);\n+\n+\t\tfinal RevFlagSet set = new RevFlagSet();\n+\t\tassertTrue(set.add(flag));\n+\t\tassertFalse(set.add(flag));\n+\t\tassertEquals(flag.mask, set.mask);\n+\t\tassertEquals(1, set.size());\n+\t\tfinal Iterator<RevFlag> i = set.iterator();\n+\t\tassertTrue(i.hasNext());\n+\t\tassertSame(flag, i.next());\n+\t\tassertFalse(i.hasNext());\n+\t}\n+\n+\tpublic void testAddTwo() {\n+\t\tfinal RevFlag flag1 = rw.newFlag(\"flag_1\");\n+\t\tfinal RevFlag flag2 = rw.newFlag(\"flag_2\");\n+\t\tassertTrue((flag1.mask & flag2.mask) == 0);\n+\n+\t\tfinal RevFlagSet set = new RevFlagSet();\n+\t\tassertTrue(set.add(flag1));\n+\t\tassertTrue(set.add(flag2));\n+\t\tassertEquals(flag1.mask | flag2.mask, set.mask);\n+\t\tassertEquals(2, set.size());\n+\t}\n+\n+\tpublic void testContainsAll() {\n+\t\tfinal RevFlag flag1 = rw.newFlag(\"flag_1\");\n+\t\tfinal RevFlag flag2 = rw.newFlag(\"flag_2\");\n+\t\tfinal RevFlagSet set1 = new RevFlagSet();\n+\t\tassertTrue(set1.add(flag1));\n+\t\tassertTrue(set1.add(flag2));\n+\n+\t\tassertTrue(set1.containsAll(set1));\n+\t\tassertTrue(set1.containsAll(Arrays\n+\t\t\t\t.asList(new RevFlag[] { flag1, flag2 })));\n+\n+\t\tfinal RevFlagSet set2 = new RevFlagSet();\n+\t\tset2.add(rw.newFlag(\"flag_3\"));\n+\t\tassertFalse(set1.containsAll(set2));\n+\t}\n+\n+\tpublic void testEquals() {\n+\t\tfinal RevFlag flag1 = rw.newFlag(\"flag_1\");\n+\t\tfinal RevFlag flag2 = rw.newFlag(\"flag_2\");\n+\t\tfinal RevFlagSet set = new RevFlagSet();\n+\t\tassertTrue(set.add(flag1));\n+\t\tassertTrue(set.add(flag2));\n+\n+\t\tassertTrue(new RevFlagSet(set).equals(set));\n+\t\tassertTrue(new RevFlagSet(Arrays.asList(new RevFlag[] { flag1, flag2 }))\n+\t\t\t\t.equals(set));\n+\t}\n+\n+\tpublic void testRemove() {\n+\t\tfinal RevFlag flag1 = rw.newFlag(\"flag_1\");\n+\t\tfinal RevFlag flag2 = rw.newFlag(\"flag_2\");\n+\t\tfinal RevFlagSet set = new RevFlagSet();\n+\t\tassertTrue(set.add(flag1));\n+\t\tassertTrue(set.add(flag2));\n+\n+\t\tassertTrue(set.remove(flag1));\n+\t\tassertFalse(set.remove(flag1));\n+\t\tassertEquals(flag2.mask, set.mask);\n+\t\tassertFalse(set.contains(flag1));\n+\t}\n+\n+\tpublic void testContains() {\n+\t\tfinal RevFlag flag1 = rw.newFlag(\"flag_1\");\n+\t\tfinal RevFlag flag2 = rw.newFlag(\"flag_2\");\n+\t\tfinal RevFlagSet set = new RevFlagSet();\n+\t\tset.add(flag1);\n+\t\tassertTrue(set.contains(flag1));\n+\t\tassertFalse(set.contains(flag2));\n+\t\tassertFalse(set.contains(\"bob\"));\n+\t}\n+}\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkCullTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkCullTest.java\nnew file mode 100644\nindex 0000000..ad78b16\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkCullTest.java\n@@ -0,0 +1,75 @@\n+/*\n+ * Copyright (C) 2008, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import org.spearce.jgit.lib.ObjectId;\n+\n+public class RevWalkCullTest extends RevWalkTestCase {\n+\tpublic void testProperlyCullAllAncestors1() throws Exception {\n+\t\t// Credit goes to Junio C Hamano <gitster@pobox.com> for this\n+\t\t// test case in git-core (t/t6009-rev-list-parent.sh)\n+\t\t//\n+\t\t// We induce a clock skew so two is dated before one.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(-2400, a);\n+\t\tfinal ObjectId c = commit(b);\n+\t\tfinal ObjectId d = commit(c);\n+\n+\t\tmarkStart(a);\n+\t\tmarkUninteresting(d);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testProperlyCullAllAncestors2() throws Exception {\n+\t\t// Despite clock skew on c1 being very old it should not\n+\t\t// produce, neither should a or b, or any part of that chain.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(-5, b);\n+\t\tfinal ObjectId c2 = commit(10, b);\n+\t\tfinal ObjectId d = commit(c1, c2);\n+\n+\t\tmarkStart(d);\n+\t\tmarkUninteresting(c1);\n+\t\tassertCommit(d, rw.next());\n+\t\tassertCommit(c2, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+}\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkFilterTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkFilterTest.java\nnew file mode 100644\nindex 0000000..cf2975d\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkFilterTest.java\n@@ -0,0 +1,233 @@\n+/*\n+ * Copyright (C) 2008, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import java.io.IOException;\n+\n+import org.spearce.jgit.errors.IncorrectObjectTypeException;\n+import org.spearce.jgit.errors.MissingObjectException;\n+import org.spearce.jgit.errors.StopWalkException;\n+import org.spearce.jgit.lib.ObjectId;\n+import org.spearce.jgit.revwalk.filter.AndRevFilter;\n+import org.spearce.jgit.revwalk.filter.NotRevFilter;\n+import org.spearce.jgit.revwalk.filter.OrRevFilter;\n+import org.spearce.jgit.revwalk.filter.RevFilter;\n+\n+public class RevWalkFilterTest extends RevWalkTestCase {\n+\tprivate static final MyAll MY_ALL = new MyAll();\n+\n+\tpublic void testFilter_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(RevFilter.ALL);\n+\t\tmarkStart(c);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_Negate_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(RevFilter.ALL.negate());\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NOT_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(NotRevFilter.create(RevFilter.ALL));\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NONE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(RevFilter.NONE);\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NOT_NONE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(NotRevFilter.create(RevFilter.NONE));\n+\t\tmarkStart(c);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_ALL_And_NONE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(AndRevFilter.create(RevFilter.ALL, RevFilter.NONE));\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NONE_And_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(AndRevFilter.create(RevFilter.NONE, RevFilter.ALL));\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_ALL_Or_NONE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(OrRevFilter.create(RevFilter.ALL, RevFilter.NONE));\n+\t\tmarkStart(c);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NONE_Or_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(OrRevFilter.create(RevFilter.NONE, RevFilter.ALL));\n+\t\tmarkStart(c);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_MY_ALL_And_NONE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(AndRevFilter.create(MY_ALL, RevFilter.NONE));\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NONE_And_MY_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(AndRevFilter.create(RevFilter.NONE, MY_ALL));\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_MY_ALL_Or_NONE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(OrRevFilter.create(MY_ALL, RevFilter.NONE));\n+\t\tmarkStart(c);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NONE_Or_MY_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(OrRevFilter.create(RevFilter.NONE, MY_ALL));\n+\t\tmarkStart(c);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NO_MERGES() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(b);\n+\t\tfinal ObjectId c2 = commit(b);\n+\t\tfinal ObjectId d = commit(c1, c2);\n+\t\tfinal ObjectId e = commit(d);\n+\n+\t\trw.setRevFilter(RevFilter.NO_MERGES);\n+\t\tmarkStart(e);\n+\t\tassertCommit(e, rw.next());\n+\t\tassertCommit(c2, rw.next());\n+\t\tassertCommit(c1, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tprivate static class MyAll extends RevFilter {\n+\t\t@Override\n+\t\tpublic RevFilter clone() {\n+\t\t\treturn this;\n+\t\t}\n+\n+\t\t@Override\n+\t\tpublic boolean include(RevWalk walker, RevCommit cmit)\n+\t\t\t\tthrows StopWalkException, MissingObjectException,\n+\t\t\t\tIncorrectObjectTypeException, IOException {\n+\t\t\treturn true;\n+\t\t}\n+\t}\n+}\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkMergeBaseTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkMergeBaseTest.java\nnew file mode 100644\nindex 0000000..b05e774\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkMergeBaseTest.java\n@@ -0,0 +1,117 @@\n+/*\n+ * Copyright (C) 2008, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import org.spearce.jgit.lib.ObjectId;\n+import org.spearce.jgit.revwalk.filter.RevFilter;\n+\n+public class RevWalkMergeBaseTest extends RevWalkTestCase {\n+\tpublic void testNone() throws Exception {\n+\t\tfinal ObjectId c1 = commit(commit(commit()));\n+\t\tfinal ObjectId c2 = commit(commit(commit()));\n+\n+\t\trw.setRevFilter(RevFilter.MERGE_BASE);\n+\t\tmarkStart(c1);\n+\t\tmarkStart(c2);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSimple() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(commit(commit(commit(commit(b)))));\n+\t\tfinal ObjectId c2 = commit(commit(commit(commit(commit(b)))));\n+\n+\t\trw.setRevFilter(RevFilter.MERGE_BASE);\n+\t\tmarkStart(c1);\n+\t\tmarkStart(c2);\n+\t\tassertCommit(b, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testMultipleHeads_SameBase1() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(commit(commit(commit(commit(b)))));\n+\t\tfinal ObjectId c2 = commit(commit(commit(commit(commit(b)))));\n+\t\tfinal ObjectId c3 = commit(commit(commit(b)));\n+\n+\t\trw.setRevFilter(RevFilter.MERGE_BASE);\n+\t\tmarkStart(c1);\n+\t\tmarkStart(c2);\n+\t\tmarkStart(c3);\n+\t\tassertCommit(b, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testMultipleHeads_SameBase2() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\t\tfinal ObjectId d1 = commit(commit(commit(commit(commit(b)))));\n+\t\tfinal ObjectId d2 = commit(commit(commit(commit(commit(c)))));\n+\t\tfinal ObjectId d3 = commit(commit(commit(c)));\n+\n+\t\trw.setRevFilter(RevFilter.MERGE_BASE);\n+\t\tmarkStart(d1);\n+\t\tmarkStart(d2);\n+\t\tmarkStart(d3);\n+\t\tassertCommit(b, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testCrissCross() throws Exception {\n+\t\t// See http://marc.info/?l=git&m=111463358500362&w=2 for a nice\n+\t\t// description of what this test is creating. We don't have a\n+\t\t// clean merge base for d,e as they each merged the parents b,c\n+\t\t// in different orders.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(a);\n+\t\tfinal ObjectId d = commit(b, c);\n+\t\tfinal ObjectId e = commit(c, b);\n+\n+\t\trw.setRevFilter(RevFilter.MERGE_BASE);\n+\t\tmarkStart(d);\n+\t\tmarkStart(e);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+}\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkSortTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkSortTest.java\nnew file mode 100644\nindex 0000000..6f2eedc\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkSortTest.java\n@@ -0,0 +1,164 @@\n+/*\n+ * Copyright (C) 2008, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import org.spearce.jgit.lib.ObjectId;\n+\n+public class RevWalkSortTest extends RevWalkTestCase {\n+\tpublic void testSort_Default() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(1, a);\n+\t\tfinal ObjectId c = commit(1, b);\n+\t\tfinal ObjectId d = commit(1, c);\n+\n+\t\tmarkStart(d);\n+\t\tassertCommit(d, rw.next());\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSort_COMMIT_TIME_DESC() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\t\tfinal ObjectId d = commit(c);\n+\n+\t\trw.sort(RevSort.COMMIT_TIME_DESC);\n+\t\tmarkStart(d);\n+\t\tassertCommit(d, rw.next());\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSort_REVERSE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\t\tfinal ObjectId d = commit(c);\n+\n+\t\trw.sort(RevSort.REVERSE);\n+\t\tmarkStart(d);\n+\t\tassertCommit(a, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(d, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSort_COMMIT_TIME_DESC_OutOfOrder1() throws Exception {\n+\t\t// Despite being out of order time-wise, a strand-of-pearls must\n+\t\t// still maintain topological order.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(-5, b);\n+\t\tfinal ObjectId d = commit(10, c);\n+\t\tassertTrue(parse(a).getCommitTime() < parse(d).getCommitTime());\n+\t\tassertTrue(parse(c).getCommitTime() < parse(b).getCommitTime());\n+\n+\t\trw.sort(RevSort.COMMIT_TIME_DESC);\n+\t\tmarkStart(d);\n+\t\tassertCommit(d, rw.next());\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSort_COMMIT_TIME_DESC_OutOfOrder2() throws Exception {\n+\t\t// c1 is back dated before its parent.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(-5, b);\n+\t\tfinal ObjectId c2 = commit(10, b);\n+\t\tfinal ObjectId d = commit(c1, c2);\n+\n+\t\trw.sort(RevSort.COMMIT_TIME_DESC);\n+\t\tmarkStart(d);\n+\t\tassertCommit(d, rw.next());\n+\t\tassertCommit(c2, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertCommit(c1, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSort_TOPO() throws Exception {\n+\t\t// c1 is back dated before its parent.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(-5, b);\n+\t\tfinal ObjectId c2 = commit(10, b);\n+\t\tfinal ObjectId d = commit(c1, c2);\n+\n+\t\trw.sort(RevSort.TOPO);\n+\t\tmarkStart(d);\n+\t\tassertCommit(d, rw.next());\n+\t\tassertCommit(c2, rw.next());\n+\t\tassertCommit(c1, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSort_TOPO_REVERSE() throws Exception {\n+\t\t// c1 is back dated before its parent.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(-5, b);\n+\t\tfinal ObjectId c2 = commit(10, b);\n+\t\tfinal ObjectId d = commit(c1, c2);\n+\n+\t\trw.sort(RevSort.TOPO);\n+\t\trw.sort(RevSort.REVERSE, true);\n+\t\tmarkStart(d);\n+\t\tassertCommit(a, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(c1, rw.next());\n+\t\tassertCommit(c2, rw.next());\n+\t\tassertCommit(d, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+}\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkTestCase.java b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkTestCase.java\nnew file mode 100644\nindex 0000000..bd696dd\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkTestCase.java\n@@ -0,0 +1,102 @@\n+/*\n+ * Copyright (C) 2008, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import java.util.Date;\n+\n+import org.spearce.jgit.lib.Commit;\n+import org.spearce.jgit.lib.ObjectId;\n+import org.spearce.jgit.lib.ObjectWriter;\n+import org.spearce.jgit.lib.PersonIdent;\n+import org.spearce.jgit.lib.RepositoryTestCase;\n+import org.spearce.jgit.lib.Tree;\n+\n+/** Support for tests of the {@link RevWalk} class. */\n+public abstract class RevWalkTestCase extends RepositoryTestCase {\n+\tprotected ObjectWriter ow;\n+\n+\tprotected ObjectId emptyTree;\n+\n+\tprotected long nowTick;\n+\n+\tprotected RevWalk rw;\n+\n+\tpublic void setUp() throws Exception {\n+\t\tsuper.setUp();\n+\t\tow = new ObjectWriter(db);\n+\t\temptyTree = ow.writeTree(new Tree(db));\n+\t\tnowTick = 1236977987000L;\n+\t\trw = new RevWalk(db);\n+\t}\n+\n+\tprotected void tick(final int secDelta) {\n+\t\tnowTick += secDelta * 1000L;\n+\t}\n+\n+\tprotected ObjectId commit(final ObjectId... parents) throws Exception {\n+\t\treturn commit(1, parents);\n+\t}\n+\n+\tprotected ObjectId commit(final int secDelta, final ObjectId... parents)\n+\t\t\tthrows Exception {\n+\t\ttick(secDelta);\n+\t\tfinal Commit c = new Commit(db);\n+\t\tc.setTreeId(emptyTree);\n+\t\tc.setParentIds(parents);\n+\t\tc.setAuthor(new PersonIdent(jauthor, new Date(nowTick)));\n+\t\tc.setCommitter(new PersonIdent(jcommitter, new Date(nowTick)));\n+\t\tc.setMessage(\"\");\n+\t\treturn ow.writeCommit(c);\n+\t}\n+\n+\tprotected RevCommit parse(final ObjectId commitId) throws Exception {\n+\t\treturn rw.parseCommit(commitId);\n+\t}\n+\n+\tprotected void markStart(final ObjectId commitId) throws Exception {\n+\t\trw.markStart(parse(commitId));\n+\t}\n+\n+\tprotected void markUninteresting(final ObjectId commitId) throws Exception {\n+\t\trw.markUninteresting(parse(commitId));\n+\t}\n+\n+\tprotected void assertCommit(final ObjectId commitId, final RevCommit commit) {\n+\t\tassertEquals(commitId.name(), commit != null ? commit.name() : null);\n+\t}\n+}\n-- \n1.6.2.288.gc3f22\n"},{"id":"107986","messageId":"20090314001345.GI22920@spearce.org","threadId":"18294","inReplyTo":"20090313223933.GH22920@spearce.org","subject":"Re: [JGIT PATCH 0/6] Add tests for RevWalk and its supporting code","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-14T00:13:45Z","receivedAt":"2009-03-14T00:13:45Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> wrote:\n> These new tests cover some of the common cases we see with using a\n> RevWalk, and increase our code coverage in this critical area of\n> the JGit library.\n> \n> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>\n> ---\n>  Robin Rosenberg <robin.rosenberg.lists@dewire.com> wrote:\n>  > fredag 13 mars 2009 03:07:37 skrev \"Shawn O. Pearce\" <spearce@spearce.org>:\n>  > > Today I uncovered some ugly cases with \"jgit rev-list B ^A\", where\n>  > > some commits reachable from A were still being output, even though\n>  > > we asked that they be excluded.\n>  > \n>  > How about a test suite to prove this is better than before?\n> \n>  Its better.  :-)\n\nIts actually not better.  Although the tests I'm replying to are\nright, there's another bug introduced by this series that they\ndon't detect, but that shows up on the Linux kernel repository.\n\nI have yet to track down the full thing... but I know its busted.\n \n-- \nShawn.\n"},{"id":"107987","messageId":"20090314005442.GJ22920@spearce.org","threadId":"18294","inReplyTo":"1236910062-18476-5-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 4/5 v2] Fix RevWalk with Linus Torvald's occasional bad commit date hack","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-14T00:54:42Z","receivedAt":"2009-03-14T00:54:42Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"In git-core commit 7d004199d134c9d465e013064f72dbc04507f6c0 Linus\ndescribes a hack he created to improve the handling of cases where\ncommit dates are out of order, such as a child commit having a date\nolder than its parent.  These cases can show up when there is bad\nimported data, or significant clock skew between distributed peers.\n\nThe original git-core bug report identified a failure in:\n\n  git rev-list A..B C\n\nwhere commits contained in both A and B were reported, due to out\nof order commit dates.\n\nWe keep running until the most recent commit in the pending queue\nis more recent than the last commit sent to the caller.  If the\npending queue suddenly goes \"backwards\" due to one of our parent's\nhaving a more recent commit date, this new check ensures we will\nkeep processing the graph until we see a more consistent cut.\n\nWe process an extra OVER_SCAN commits after we decide that all\nremaining commits are UNINTERESTING.  Processing these extra\ncommits ensures flags are carried back further in the graph,\nincreasing the chances that we correctly mark relevant nodes.\n\nAs a result of this hack, we may produce a commit to our caller,\nbut then later mark it UNINTERESTING if we discover date skew.\nTo handle such cases, callers could buffer produced commits and\nfilter out those that are UNINTERESTING, but this somewhat costly\nand may not always be necessary.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n\n This version inverts the \"n.commitTime <= last.commitTime\",\n I confused myself and wrote it backwards.\n\n The next patch I'm going to send with the tests has a test for\n this condition, to verify its correct.\n\n .../org/spearce/jgit/revwalk/PendingGenerator.java |   51 ++++++++++++++++++--\n 1 files changed, 47 insertions(+), 4 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java\nindex 144e909..4e24431 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/PendingGenerator.java\n@@ -42,6 +42,7 @@\n import org.spearce.jgit.errors.IncorrectObjectTypeException;\n import org.spearce.jgit.errors.MissingObjectException;\n import org.spearce.jgit.errors.StopWalkException;\n+import org.spearce.jgit.lib.ObjectId;\n import org.spearce.jgit.revwalk.filter.RevFilter;\n \n /**\n@@ -60,6 +61,24 @@\n \n \tprivate static final int UNINTERESTING = RevWalk.UNINTERESTING;\n \n+\t/**\n+\t * Number of additional commits to scan after we think we are done.\n+\t * <p>\n+\t * This small buffer of commits is scanned to ensure we didn't miss anything\n+\t * as a result of clock skew when the commits were made. We need to set our\n+\t * constant to 1 additional commit due to the use of a pre-increment\n+\t * operator when accessing the value.\n+\t */\n+\tprivate static final int OVER_SCAN = 5 + 1;\n+\n+\t/** A commit near the end of time, to initialize {@link #last} with. */\n+\tprivate static final RevCommit INIT_LAST;\n+\n+\tstatic {\n+\t\tINIT_LAST = new RevCommit(ObjectId.zeroId());\n+\t\tINIT_LAST.commitTime = Integer.MAX_VALUE;\n+\t}\n+\n \tprivate final RevWalk walker;\n \n \tprivate final DateRevQueue pending;\n@@ -68,6 +87,17 @@\n \n \tprivate final int output;\n \n+\t/** Last commit produced to the caller from {@link #next()}. */\n+\tprivate RevCommit last = INIT_LAST;\n+\n+\t/**\n+\t * Number of commits we have remaining in our over-scan allotment.\n+\t * <p>\n+\t * Only relevant if there are {@link #UNINTERESTING} commits in the\n+\t * {@link #pending} queue.\n+\t */\n+\tprivate int overScan = OVER_SCAN;\n+\n \tboolean canDispose;\n \n \tPendingGenerator(final RevWalk w, final DateRevQueue p,\n@@ -112,14 +142,27 @@ RevCommit next() throws MissingObjectException,\n \t\t\t\twalker.carryFlagsImpl(c);\n \n \t\t\t\tif ((c.flags & UNINTERESTING) != 0) {\n-\t\t\t\t\tif (pending.everbodyHasFlag(UNINTERESTING))\n-\t\t\t\t\t\tthrow StopWalkException.INSTANCE;\n-\t\t\t\t\tc.dispose();\n+\t\t\t\t\tif (pending.everbodyHasFlag(UNINTERESTING)) {\n+\t\t\t\t\t\tfinal RevCommit n = pending.peek();\n+\t\t\t\t\t\tif (n != null && n.commitTime >= last.commitTime) {\n+\t\t\t\t\t\t\t// This is too close to call. The next commit we\n+\t\t\t\t\t\t\t// would pop is dated after the last one produced.\n+\t\t\t\t\t\t\t// We have to keep going to ensure that we carry\n+\t\t\t\t\t\t\t// flags as much as necessary.\n+\t\t\t\t\t\t\t//\n+\t\t\t\t\t\t\toverScan = OVER_SCAN;\n+\t\t\t\t\t\t} else if (--overScan == 0)\n+\t\t\t\t\t\t\tthrow StopWalkException.INSTANCE;\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\toverScan = OVER_SCAN;\n+\t\t\t\t\t}\n+\t\t\t\t\tif (canDispose)\n+\t\t\t\t\t\tc.dispose();\n \t\t\t\t\tcontinue;\n \t\t\t\t}\n \n \t\t\t\tif (produce)\n-\t\t\t\t\treturn c;\n+\t\t\t\t\treturn last = c;\n \t\t\t\telse if (canDispose)\n \t\t\t\t\tc.dispose();\n \t\t\t}\n-- \n1.6.2.288.gc3f22\n"},{"id":"107988","messageId":"20090314005617.GK22920@spearce.org","threadId":"18294","inReplyTo":"20090314001345.GI22920@spearce.org","subject":"[JGIT PATCH 6/5 v2] Add tests for RevWalk and its supporting code","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-14T00:56:17Z","receivedAt":"2009-03-14T00:56:17Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"These new tests cover some of the common cases we see with using a\nRevWalk, and increase our code coverage in this critical area of\nthe JGit library.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n \"Shawn O. Pearce\" <spearce@spearce.org> wrote:\n > I have yet to track down the full thing... but I know its busted.\n \n This updated test patch includes a test for the bug I was talking\n about, and fixed with 4/5 v2.\n\n .../org/spearce/jgit/revwalk/RevFlagSetTest.java   |  131 +++++++++++\n .../org/spearce/jgit/revwalk/RevWalkCullTest.java  |   96 ++++++++\n .../spearce/jgit/revwalk/RevWalkFilterTest.java    |  233 ++++++++++++++++++++\n .../spearce/jgit/revwalk/RevWalkMergeBaseTest.java |  117 ++++++++++\n .../org/spearce/jgit/revwalk/RevWalkSortTest.java  |  164 ++++++++++++++\n .../org/spearce/jgit/revwalk/RevWalkTestCase.java  |  102 +++++++++\n 6 files changed, 843 insertions(+), 0 deletions(-)\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevFlagSetTest.java\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkCullTest.java\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkFilterTest.java\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkMergeBaseTest.java\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkSortTest.java\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkTestCase.java\n\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevFlagSetTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevFlagSetTest.java\nnew file mode 100644\nindex 0000000..76f3cbb\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevFlagSetTest.java\n@@ -0,0 +1,131 @@\n+/*\n+ * Copyright (C) 2008, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import java.util.Arrays;\n+import java.util.Iterator;\n+\n+public class RevFlagSetTest extends RevWalkTestCase {\n+\tpublic void testEmpty() {\n+\t\tfinal RevFlagSet set = new RevFlagSet();\n+\t\tassertEquals(0, set.mask);\n+\t\tassertEquals(0, set.size());\n+\t\tassertNotNull(set.iterator());\n+\t\tassertFalse(set.iterator().hasNext());\n+\t}\n+\n+\tpublic void testAddOne() {\n+\t\tfinal String flagName = \"flag\";\n+\t\tfinal RevFlag flag = rw.newFlag(flagName);\n+\t\tassertTrue(0 != flag.mask);\n+\t\tassertSame(flagName, flag.name);\n+\n+\t\tfinal RevFlagSet set = new RevFlagSet();\n+\t\tassertTrue(set.add(flag));\n+\t\tassertFalse(set.add(flag));\n+\t\tassertEquals(flag.mask, set.mask);\n+\t\tassertEquals(1, set.size());\n+\t\tfinal Iterator<RevFlag> i = set.iterator();\n+\t\tassertTrue(i.hasNext());\n+\t\tassertSame(flag, i.next());\n+\t\tassertFalse(i.hasNext());\n+\t}\n+\n+\tpublic void testAddTwo() {\n+\t\tfinal RevFlag flag1 = rw.newFlag(\"flag_1\");\n+\t\tfinal RevFlag flag2 = rw.newFlag(\"flag_2\");\n+\t\tassertTrue((flag1.mask & flag2.mask) == 0);\n+\n+\t\tfinal RevFlagSet set = new RevFlagSet();\n+\t\tassertTrue(set.add(flag1));\n+\t\tassertTrue(set.add(flag2));\n+\t\tassertEquals(flag1.mask | flag2.mask, set.mask);\n+\t\tassertEquals(2, set.size());\n+\t}\n+\n+\tpublic void testContainsAll() {\n+\t\tfinal RevFlag flag1 = rw.newFlag(\"flag_1\");\n+\t\tfinal RevFlag flag2 = rw.newFlag(\"flag_2\");\n+\t\tfinal RevFlagSet set1 = new RevFlagSet();\n+\t\tassertTrue(set1.add(flag1));\n+\t\tassertTrue(set1.add(flag2));\n+\n+\t\tassertTrue(set1.containsAll(set1));\n+\t\tassertTrue(set1.containsAll(Arrays\n+\t\t\t\t.asList(new RevFlag[] { flag1, flag2 })));\n+\n+\t\tfinal RevFlagSet set2 = new RevFlagSet();\n+\t\tset2.add(rw.newFlag(\"flag_3\"));\n+\t\tassertFalse(set1.containsAll(set2));\n+\t}\n+\n+\tpublic void testEquals() {\n+\t\tfinal RevFlag flag1 = rw.newFlag(\"flag_1\");\n+\t\tfinal RevFlag flag2 = rw.newFlag(\"flag_2\");\n+\t\tfinal RevFlagSet set = new RevFlagSet();\n+\t\tassertTrue(set.add(flag1));\n+\t\tassertTrue(set.add(flag2));\n+\n+\t\tassertTrue(new RevFlagSet(set).equals(set));\n+\t\tassertTrue(new RevFlagSet(Arrays.asList(new RevFlag[] { flag1, flag2 }))\n+\t\t\t\t.equals(set));\n+\t}\n+\n+\tpublic void testRemove() {\n+\t\tfinal RevFlag flag1 = rw.newFlag(\"flag_1\");\n+\t\tfinal RevFlag flag2 = rw.newFlag(\"flag_2\");\n+\t\tfinal RevFlagSet set = new RevFlagSet();\n+\t\tassertTrue(set.add(flag1));\n+\t\tassertTrue(set.add(flag2));\n+\n+\t\tassertTrue(set.remove(flag1));\n+\t\tassertFalse(set.remove(flag1));\n+\t\tassertEquals(flag2.mask, set.mask);\n+\t\tassertFalse(set.contains(flag1));\n+\t}\n+\n+\tpublic void testContains() {\n+\t\tfinal RevFlag flag1 = rw.newFlag(\"flag_1\");\n+\t\tfinal RevFlag flag2 = rw.newFlag(\"flag_2\");\n+\t\tfinal RevFlagSet set = new RevFlagSet();\n+\t\tset.add(flag1);\n+\t\tassertTrue(set.contains(flag1));\n+\t\tassertFalse(set.contains(flag2));\n+\t\tassertFalse(set.contains(\"bob\"));\n+\t}\n+}\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkCullTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkCullTest.java\nnew file mode 100644\nindex 0000000..93bd645\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkCullTest.java\n@@ -0,0 +1,96 @@\n+/*\n+ * Copyright (C) 2008, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import org.spearce.jgit.lib.ObjectId;\n+\n+public class RevWalkCullTest extends RevWalkTestCase {\n+\tpublic void testProperlyCullAllAncestors1() throws Exception {\n+\t\t// Credit goes to Junio C Hamano <gitster@pobox.com> for this\n+\t\t// test case in git-core (t/t6009-rev-list-parent.sh)\n+\t\t//\n+\t\t// We induce a clock skew so two is dated before one.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(-2400, a);\n+\t\tfinal ObjectId c = commit(b);\n+\t\tfinal ObjectId d = commit(c);\n+\n+\t\tmarkStart(a);\n+\t\tmarkUninteresting(d);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testProperlyCullAllAncestors2() throws Exception {\n+\t\t// Despite clock skew on c1 being very old it should not\n+\t\t// produce, neither should a or b, or any part of that chain.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(-5, b);\n+\t\tfinal ObjectId c2 = commit(10, b);\n+\t\tfinal ObjectId d = commit(c1, c2);\n+\n+\t\tmarkStart(d);\n+\t\tmarkUninteresting(c1);\n+\t\tassertCommit(d, rw.next());\n+\t\tassertCommit(c2, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testProperlyCullAllAncestors_LongHistory() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tObjectId b = commit(a);\n+\t\tfor (int i = 0; i < 24; i++) {\n+\t\t\tb = commit(b);\n+\t\t\tif ((i & 2) == 0)\n+\t\t\t\tmarkUninteresting(b);\n+\t\t}\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\tmarkStart(c);\n+\t\tmarkUninteresting(b);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertNull(rw.next());\n+\n+\t\t// We should have aborted before we got back so far that \"a\"\n+\t\t// would be parsed. Thus, its parents shouldn't be allocated.\n+\t\t//\n+\t\tassertNull(rw.lookupCommit(a).parents);\n+\t}\n+}\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkFilterTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkFilterTest.java\nnew file mode 100644\nindex 0000000..cf2975d\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkFilterTest.java\n@@ -0,0 +1,233 @@\n+/*\n+ * Copyright (C) 2008, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import java.io.IOException;\n+\n+import org.spearce.jgit.errors.IncorrectObjectTypeException;\n+import org.spearce.jgit.errors.MissingObjectException;\n+import org.spearce.jgit.errors.StopWalkException;\n+import org.spearce.jgit.lib.ObjectId;\n+import org.spearce.jgit.revwalk.filter.AndRevFilter;\n+import org.spearce.jgit.revwalk.filter.NotRevFilter;\n+import org.spearce.jgit.revwalk.filter.OrRevFilter;\n+import org.spearce.jgit.revwalk.filter.RevFilter;\n+\n+public class RevWalkFilterTest extends RevWalkTestCase {\n+\tprivate static final MyAll MY_ALL = new MyAll();\n+\n+\tpublic void testFilter_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(RevFilter.ALL);\n+\t\tmarkStart(c);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_Negate_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(RevFilter.ALL.negate());\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NOT_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(NotRevFilter.create(RevFilter.ALL));\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NONE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(RevFilter.NONE);\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NOT_NONE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(NotRevFilter.create(RevFilter.NONE));\n+\t\tmarkStart(c);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_ALL_And_NONE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(AndRevFilter.create(RevFilter.ALL, RevFilter.NONE));\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NONE_And_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(AndRevFilter.create(RevFilter.NONE, RevFilter.ALL));\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_ALL_Or_NONE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(OrRevFilter.create(RevFilter.ALL, RevFilter.NONE));\n+\t\tmarkStart(c);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NONE_Or_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(OrRevFilter.create(RevFilter.NONE, RevFilter.ALL));\n+\t\tmarkStart(c);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_MY_ALL_And_NONE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(AndRevFilter.create(MY_ALL, RevFilter.NONE));\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NONE_And_MY_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(AndRevFilter.create(RevFilter.NONE, MY_ALL));\n+\t\tmarkStart(c);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_MY_ALL_Or_NONE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(OrRevFilter.create(MY_ALL, RevFilter.NONE));\n+\t\tmarkStart(c);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NONE_Or_MY_ALL() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\n+\t\trw.setRevFilter(OrRevFilter.create(RevFilter.NONE, MY_ALL));\n+\t\tmarkStart(c);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testFilter_NO_MERGES() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(b);\n+\t\tfinal ObjectId c2 = commit(b);\n+\t\tfinal ObjectId d = commit(c1, c2);\n+\t\tfinal ObjectId e = commit(d);\n+\n+\t\trw.setRevFilter(RevFilter.NO_MERGES);\n+\t\tmarkStart(e);\n+\t\tassertCommit(e, rw.next());\n+\t\tassertCommit(c2, rw.next());\n+\t\tassertCommit(c1, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tprivate static class MyAll extends RevFilter {\n+\t\t@Override\n+\t\tpublic RevFilter clone() {\n+\t\t\treturn this;\n+\t\t}\n+\n+\t\t@Override\n+\t\tpublic boolean include(RevWalk walker, RevCommit cmit)\n+\t\t\t\tthrows StopWalkException, MissingObjectException,\n+\t\t\t\tIncorrectObjectTypeException, IOException {\n+\t\t\treturn true;\n+\t\t}\n+\t}\n+}\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkMergeBaseTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkMergeBaseTest.java\nnew file mode 100644\nindex 0000000..b05e774\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkMergeBaseTest.java\n@@ -0,0 +1,117 @@\n+/*\n+ * Copyright (C) 2008, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import org.spearce.jgit.lib.ObjectId;\n+import org.spearce.jgit.revwalk.filter.RevFilter;\n+\n+public class RevWalkMergeBaseTest extends RevWalkTestCase {\n+\tpublic void testNone() throws Exception {\n+\t\tfinal ObjectId c1 = commit(commit(commit()));\n+\t\tfinal ObjectId c2 = commit(commit(commit()));\n+\n+\t\trw.setRevFilter(RevFilter.MERGE_BASE);\n+\t\tmarkStart(c1);\n+\t\tmarkStart(c2);\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSimple() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(commit(commit(commit(commit(b)))));\n+\t\tfinal ObjectId c2 = commit(commit(commit(commit(commit(b)))));\n+\n+\t\trw.setRevFilter(RevFilter.MERGE_BASE);\n+\t\tmarkStart(c1);\n+\t\tmarkStart(c2);\n+\t\tassertCommit(b, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testMultipleHeads_SameBase1() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(commit(commit(commit(commit(b)))));\n+\t\tfinal ObjectId c2 = commit(commit(commit(commit(commit(b)))));\n+\t\tfinal ObjectId c3 = commit(commit(commit(b)));\n+\n+\t\trw.setRevFilter(RevFilter.MERGE_BASE);\n+\t\tmarkStart(c1);\n+\t\tmarkStart(c2);\n+\t\tmarkStart(c3);\n+\t\tassertCommit(b, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testMultipleHeads_SameBase2() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\t\tfinal ObjectId d1 = commit(commit(commit(commit(commit(b)))));\n+\t\tfinal ObjectId d2 = commit(commit(commit(commit(commit(c)))));\n+\t\tfinal ObjectId d3 = commit(commit(commit(c)));\n+\n+\t\trw.setRevFilter(RevFilter.MERGE_BASE);\n+\t\tmarkStart(d1);\n+\t\tmarkStart(d2);\n+\t\tmarkStart(d3);\n+\t\tassertCommit(b, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testCrissCross() throws Exception {\n+\t\t// See http://marc.info/?l=git&m=111463358500362&w=2 for a nice\n+\t\t// description of what this test is creating. We don't have a\n+\t\t// clean merge base for d,e as they each merged the parents b,c\n+\t\t// in different orders.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(a);\n+\t\tfinal ObjectId d = commit(b, c);\n+\t\tfinal ObjectId e = commit(c, b);\n+\n+\t\trw.setRevFilter(RevFilter.MERGE_BASE);\n+\t\tmarkStart(d);\n+\t\tmarkStart(e);\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+}\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkSortTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkSortTest.java\nnew file mode 100644\nindex 0000000..6f2eedc\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkSortTest.java\n@@ -0,0 +1,164 @@\n+/*\n+ * Copyright (C) 2008, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import org.spearce.jgit.lib.ObjectId;\n+\n+public class RevWalkSortTest extends RevWalkTestCase {\n+\tpublic void testSort_Default() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(1, a);\n+\t\tfinal ObjectId c = commit(1, b);\n+\t\tfinal ObjectId d = commit(1, c);\n+\n+\t\tmarkStart(d);\n+\t\tassertCommit(d, rw.next());\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSort_COMMIT_TIME_DESC() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\t\tfinal ObjectId d = commit(c);\n+\n+\t\trw.sort(RevSort.COMMIT_TIME_DESC);\n+\t\tmarkStart(d);\n+\t\tassertCommit(d, rw.next());\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSort_REVERSE() throws Exception {\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(b);\n+\t\tfinal ObjectId d = commit(c);\n+\n+\t\trw.sort(RevSort.REVERSE);\n+\t\tmarkStart(d);\n+\t\tassertCommit(a, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(d, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSort_COMMIT_TIME_DESC_OutOfOrder1() throws Exception {\n+\t\t// Despite being out of order time-wise, a strand-of-pearls must\n+\t\t// still maintain topological order.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c = commit(-5, b);\n+\t\tfinal ObjectId d = commit(10, c);\n+\t\tassertTrue(parse(a).getCommitTime() < parse(d).getCommitTime());\n+\t\tassertTrue(parse(c).getCommitTime() < parse(b).getCommitTime());\n+\n+\t\trw.sort(RevSort.COMMIT_TIME_DESC);\n+\t\tmarkStart(d);\n+\t\tassertCommit(d, rw.next());\n+\t\tassertCommit(c, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSort_COMMIT_TIME_DESC_OutOfOrder2() throws Exception {\n+\t\t// c1 is back dated before its parent.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(-5, b);\n+\t\tfinal ObjectId c2 = commit(10, b);\n+\t\tfinal ObjectId d = commit(c1, c2);\n+\n+\t\trw.sort(RevSort.COMMIT_TIME_DESC);\n+\t\tmarkStart(d);\n+\t\tassertCommit(d, rw.next());\n+\t\tassertCommit(c2, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertCommit(c1, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSort_TOPO() throws Exception {\n+\t\t// c1 is back dated before its parent.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(-5, b);\n+\t\tfinal ObjectId c2 = commit(10, b);\n+\t\tfinal ObjectId d = commit(c1, c2);\n+\n+\t\trw.sort(RevSort.TOPO);\n+\t\tmarkStart(d);\n+\t\tassertCommit(d, rw.next());\n+\t\tassertCommit(c2, rw.next());\n+\t\tassertCommit(c1, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(a, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+\n+\tpublic void testSort_TOPO_REVERSE() throws Exception {\n+\t\t// c1 is back dated before its parent.\n+\t\t//\n+\t\tfinal ObjectId a = commit();\n+\t\tfinal ObjectId b = commit(a);\n+\t\tfinal ObjectId c1 = commit(-5, b);\n+\t\tfinal ObjectId c2 = commit(10, b);\n+\t\tfinal ObjectId d = commit(c1, c2);\n+\n+\t\trw.sort(RevSort.TOPO);\n+\t\trw.sort(RevSort.REVERSE, true);\n+\t\tmarkStart(d);\n+\t\tassertCommit(a, rw.next());\n+\t\tassertCommit(b, rw.next());\n+\t\tassertCommit(c1, rw.next());\n+\t\tassertCommit(c2, rw.next());\n+\t\tassertCommit(d, rw.next());\n+\t\tassertNull(rw.next());\n+\t}\n+}\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkTestCase.java b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkTestCase.java\nnew file mode 100644\nindex 0000000..bd696dd\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/RevWalkTestCase.java\n@@ -0,0 +1,102 @@\n+/*\n+ * Copyright (C) 2008, Google Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.revwalk;\n+\n+import java.util.Date;\n+\n+import org.spearce.jgit.lib.Commit;\n+import org.spearce.jgit.lib.ObjectId;\n+import org.spearce.jgit.lib.ObjectWriter;\n+import org.spearce.jgit.lib.PersonIdent;\n+import org.spearce.jgit.lib.RepositoryTestCase;\n+import org.spearce.jgit.lib.Tree;\n+\n+/** Support for tests of the {@link RevWalk} class. */\n+public abstract class RevWalkTestCase extends RepositoryTestCase {\n+\tprotected ObjectWriter ow;\n+\n+\tprotected ObjectId emptyTree;\n+\n+\tprotected long nowTick;\n+\n+\tprotected RevWalk rw;\n+\n+\tpublic void setUp() throws Exception {\n+\t\tsuper.setUp();\n+\t\tow = new ObjectWriter(db);\n+\t\temptyTree = ow.writeTree(new Tree(db));\n+\t\tnowTick = 1236977987000L;\n+\t\trw = new RevWalk(db);\n+\t}\n+\n+\tprotected void tick(final int secDelta) {\n+\t\tnowTick += secDelta * 1000L;\n+\t}\n+\n+\tprotected ObjectId commit(final ObjectId... parents) throws Exception {\n+\t\treturn commit(1, parents);\n+\t}\n+\n+\tprotected ObjectId commit(final int secDelta, final ObjectId... parents)\n+\t\t\tthrows Exception {\n+\t\ttick(secDelta);\n+\t\tfinal Commit c = new Commit(db);\n+\t\tc.setTreeId(emptyTree);\n+\t\tc.setParentIds(parents);\n+\t\tc.setAuthor(new PersonIdent(jauthor, new Date(nowTick)));\n+\t\tc.setCommitter(new PersonIdent(jcommitter, new Date(nowTick)));\n+\t\tc.setMessage(\"\");\n+\t\treturn ow.writeCommit(c);\n+\t}\n+\n+\tprotected RevCommit parse(final ObjectId commitId) throws Exception {\n+\t\treturn rw.parseCommit(commitId);\n+\t}\n+\n+\tprotected void markStart(final ObjectId commitId) throws Exception {\n+\t\trw.markStart(parse(commitId));\n+\t}\n+\n+\tprotected void markUninteresting(final ObjectId commitId) throws Exception {\n+\t\trw.markUninteresting(parse(commitId));\n+\t}\n+\n+\tprotected void assertCommit(final ObjectId commitId, final RevCommit commit) {\n+\t\tassertEquals(commitId.name(), commit != null ? commit.name() : null);\n+\t}\n+}\n-- \n1.6.2.288.gc3f22\n"},{"id":"108040","messageId":"200903151234.36812.robin.rosenberg.lists@dewire.com","threadId":"18294","inReplyTo":"20090314005617.GK22920@spearce.org","subject":"Re: [JGIT PATCH 6/5 v2] Add tests for RevWalk and its supporting code","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg.lists@dewire.com","sentAt":"2009-03-15T11:34:36Z","receivedAt":"2009-03-15T11:34:36Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"\nA few /09 interesting/ places in StartGenerator are not covered by the tests.\n\n\t\tif (q instanceof DateRevQueue)\n\t\t\tpending = (DateRevQueue)q;\n\t\telse\n-->\t\t\tpending = new DateRevQueue(q);\n\nand\n\n\t\tif (tf != TreeFilter.ALL) {\n-->\t\t\trf = AndRevFilter.create(rf, new RewriteTreeFilter(w, tf));\n-->\t\t\tpendingOutputType |= HAS_REWRITE | NEEDS_REWRITE;\n\t\t}\n\nPendingGenerator\n\t\t\t\t\t\tif (n != null && n.commitTime >= last.commitTime) {\n\t\t\t\t\t\t\t// This is too close to call. The next commit we\n\t\t\t\t\t\t\t// would pop is dated after the last one produced.\n\t\t\t\t\t\t\t// We have to keep going to ensure that we carry\n\t\t\t\t\t\t\t// flags as much as necessary.\n\t\t\t\t\t\t\t//\n-->\t\t\t\t\t\t\toverScan = OVER_SCAN;\n\n\nI'll merge it anyway since this is still a huge improvement compared to the previous\nstate.\n\n-- robin\n"},{"id":"108084","messageId":"20090316143359.GM22920@spearce.org","threadId":"18294","inReplyTo":"200903151234.36812.robin.rosenberg.lists@dewire.com","subject":"Re: [JGIT PATCH 6/5 v2] Add tests for RevWalk and its supporting code","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-16T14:33:59Z","receivedAt":"2009-03-16T14:33:59Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Robin Rosenberg <robin.rosenberg.lists@dewire.com> wrote:\n> \n> A few /09 interesting/ places in StartGenerator are not covered by the tests.\n> \n> \t\tif (q instanceof DateRevQueue)\n> \t\t\tpending = (DateRevQueue)q;\n> \t\telse\n> -->\t\t\tpending = new DateRevQueue(q);\n\nThis one is difficult to test.  Near as I can tell from the code\nin the revwalk package, it never happens.  But if we did get here\nwith a non date rev queue, DateRevQueue()'s constructor can copy\nthe data from q over to one with no risk.\n\nPerhaps just test this constructor in isolation?\n\n> and\n> \n> \t\tif (tf != TreeFilter.ALL) {\n> -->\t\t\trf = AndRevFilter.create(rf, new RewriteTreeFilter(w, tf));\n> -->\t\t\tpendingOutputType |= HAS_REWRITE | NEEDS_REWRITE;\n> \t\t}\n\nThat says we have no tests on the path filter code.  Adding one is\nlikely to identify at least one bug.  Clearly we need additional\ntests on the path filter sections.  And it isn't just for this one\nlittle conditional; the entire RewriteTreeFilter and RewriteGenerator\nare untested right now.\n\nI can work on adding more test coverage here, but its not in the\ncritical path for me at day-job right now.  The other problems I\ntried to address in this series were.  So its lower in my queue\nso-to-speak.  But I'll see what I can do in the near future to\nwrite additional tests for this area of the revwalk package.\n \n> PendingGenerator\n> \t\t\t\t\t\tif (n != null && n.commitTime >= last.commitTime) {\n> \t\t\t\t\t\t\t// This is too close to call. The next commit we\n> \t\t\t\t\t\t\t// would pop is dated after the last one produced.\n> \t\t\t\t\t\t\t// We have to keep going to ensure that we carry\n> \t\t\t\t\t\t\t// flags as much as necessary.\n> \t\t\t\t\t\t\t//\n> -->\t\t\t\t\t\t\toverScan = OVER_SCAN;\n\n*sigh*  We never get here in the test suite? I missed that.  I'll try to\nwork out a test case today and send an additional patch to get coverage\nhere.  I thought RevWalkCullTest testProperlyCullAllAncestors1() would\nbe hitting here.  It doesn't.\n \n> I'll merge it anyway since this is still a huge improvement compared to the previous\n> state.\n\nThanks.\n\nA co-worker and I are also currently trying to track down a deadlock\nbetween C git-fetch and JGit upload-pack.  Both get stuck waiting\nfor the other to answer.  Clearly its JGit's fault.\n\n-- \nShawn.\n"}]}