{"thread":{"id":"20829","subject":"[JGIT] Request for help","startedAt":"2009-09-02T23:28:49Z","lastAt":"2009-10-01T21:47:00Z","messageCount":28,"participants":["Nasser Grainawi","Johannes Schindelin","Shawn O. Pearce","Jonas Fonseca","Christian Halstrick","Gabe McArthur","Mark Struberg"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"122335","messageId":"4A9EFFB1.9090501@codeaurora.org","threadId":"20829","inReplyTo":null,"subject":"[JGIT] Request for help","fromName":"Nasser Grainawi","fromEmail":"nasser@codeaurora.org","sentAt":"2009-09-02T23:28:49Z","receivedAt":"2009-09-02T23:28:49Z","isPatch":false,"sender":{"key":"nasser@codeaurora.org","avatar":"https://avatars.githubusercontent.com/u/757421?v=4"},"body":"Hello all,\n\nI'm looking to add 'git patch-id' to JGit and I could use a few \npointers. I'm not very familiar with the JGit code base or Java, so \nplease excuse any blatant oversights or unintelligent questions.\n\nFirst off, is there a \"hacking JGit\" document anywhere? One of those \nwould be great right now.\n\nSo far I'm just trying to define the inputs and outputs. On Shawn's \nsuggestion I'm planning on making it part of the org.spearce.jgit.patch \npackage. C Git patch-id very generically has an input of a 'patch', so \nI'm thinking this implementation should use the Patch object. Looking at \nthat class it seems that has everything patch-id should need, so perhaps \nthat's the only input.\n\nAs far as output, C Git patch-id has the special feature to output the \ncommit-id along with the patch-id when it gets input in the format of \ngit-diff-tree. Should JGit do the same or just return the patch-id? I \ndon't know that this question even makes sense in the context of JGit \n(since the commit-id is almost certainly available elsewhere and someone \ncalling 'getPatchId()' is likely only interested in the patch-id).\n\nShould PatchId be a class on its own, or just a method within the Patch \nclass?\n\nThanks,\nNasser\n"},{"id":"122336","messageId":"alpine.DEB.1.00.0909030157090.8306@pacific.mpi-cbg.de","threadId":"20829","inReplyTo":"4A9EFFB1.9090501@codeaurora.org","subject":"Re: [JGIT] Request for help","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-09-03T00:04:17Z","receivedAt":"2009-09-03T00:04:17Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 2 Sep 2009, Nasser Grainawi wrote:\n\n> I'm looking to add 'git patch-id' to JGit and I could use a few \n> pointers. I'm not very familiar with the JGit code base or Java, so \n> please excuse any blatant oversights or unintelligent questions.\n> \n> First off, is there a \"hacking JGit\" document anywhere? One of those \n> would be great right now.\n\nThere have been some mails with details about JGit from Shawn (IIRC) to \nthis very list.\n\n> So far I'm just trying to define the inputs and outputs. On Shawn's \n> suggestion I'm planning on making it part of the org.spearce.jgit.patch \n> package. C Git patch-id very generically has an input of a 'patch', so \n> I'm thinking this implementation should use the Patch object.\n\nC Git patch-id takes a valid patch as input; I do not think that you want \nto use the Patch object.\n\nFWIW a patch-id is nothing else than the SHA-1 of a diff where the \"diff\", \n\"index\", \"@@\" lines and all the whitespace was removed.\n\nThis is not really difficult in Java, however, it relies on a working diff \nimplementation (and IIRC my implementation has not yet been integrated \ninto JGit).\n\nCiao,\nDscho\n"},{"id":"122338","messageId":"20090903012207.GF1033@spearce.org","threadId":"20829","inReplyTo":"alpine.DEB.1.00.0909030157090.8306@pacific.mpi-cbg.de","subject":"Re: [JGIT] Request for help","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-09-03T01:22:07Z","receivedAt":"2009-09-03T01:22:07Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> On Wed, 2 Sep 2009, Nasser Grainawi wrote:\n> \n> > I'm looking to add 'git patch-id' to JGit and I could use a few \n> > pointers. I'm not very familiar with the JGit code base or Java, so \n> > please excuse any blatant oversights or unintelligent questions.\n> > \n> > First off, is there a \"hacking JGit\" document anywhere? One of those \n> > would be great right now.\n> \n> There have been some mails with details about JGit from Shawn (IIRC) to \n> this very list.\n\nYea, for the most part I think we use Eclipse, and you just have\nto import JGit's top level directory into Eclipse as it comes with\nEclipse project files.  But I know some folks only use our Maven\nbuild (under jgit-maven/jgit) or use NetBeans.  I have no idea how\nto import the project into the latter or configure its unit tests\nto run.\n \n> > So far I'm just trying to define the inputs and outputs. On Shawn's \n> > suggestion I'm planning on making it part of the org.spearce.jgit.patch \n> > package. C Git patch-id very generically has an input of a 'patch', so \n> > I'm thinking this implementation should use the Patch object.\n> \n> C Git patch-id takes a valid patch as input; I do not think that you want \n> to use the Patch object.\n\nI think we do want to use the Patch object.  The Patch entity in\nJGit is a parsed representation of the git diff or unified diff\nstructure.  Its relatively easy to walk over, and all of the mess\nabout determining line type has already been done.\n\nWe'd probably want to do something that is a lot like the object\nPatch as the output of our diff routine.  A tool (e.g. Gerrit Code\nReview) might only want the EditList for a given file, and not\nreally care about the actual formatted patch text, as it reformats\neverything itself.  I think patch-id computation is along those\nsame lines.\n\nIf we were to compute a patch-id off an InputStream we would probably\njust send it through the Patch object first.\n\n> This is not really difficult in Java, however, it relies on a working diff \n> implementation (and IIRC my implementation has not yet been integrated \n> into JGit).\n\nSpeaking of... where does that stand?\n\n-- \nShawn.\n"},{"id":"122339","messageId":"20090903012315.GG1033@spearce.org","threadId":"20829","inReplyTo":"4A9EFFB1.9090501@codeaurora.org","subject":"Re: [JGIT] Request for help","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-09-03T01:23:15Z","receivedAt":"2009-09-03T01:23:15Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Nasser Grainawi <nasser@codeaurora.org> wrote:\n> Should PatchId be a class on its own, or just a method within the Patch  \n> class?\n\nHmm, maybe a method on Patch is reasonable.\n\n-- \nShawn.\n"},{"id":"122342","messageId":"alpine.DEB.1.00.0909030846230.8306@pacific.mpi-cbg.de","threadId":"20829","inReplyTo":"20090903012207.GF1033@spearce.org","subject":"jgit diff, was Re: [JGIT] Request for help","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-09-03T06:55:47Z","receivedAt":"2009-09-03T06:55:47Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 2 Sep 2009, Shawn O. Pearce wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> > On Wed, 2 Sep 2009, Nasser Grainawi wrote:\n> > \n> > > I'm looking to add 'git patch-id' to JGit and I could use a few \n> > > pointers. I'm not very familiar with the JGit code base or Java, so \n> > > please excuse any blatant oversights or unintelligent questions.\n> > > \n> > > First off, is there a \"hacking JGit\" document anywhere? One of those \n> > > would be great right now.\n> > \n> > There have been some mails with details about JGit from Shawn (IIRC) \n> > to this very list.\n> \n> Yea, for the most part I think we use Eclipse, and you just have to \n> import JGit's top level directory into Eclipse as it comes with Eclipse \n> project files.  But I know some folks only use our Maven build (under \n> jgit-maven/jgit) or use NetBeans.  I have no idea how to import the \n> project into the latter or configure its unit tests to run.\n\nFWIW I use vim & shell most of the time (yes, even for JGit).\n\n> > This is not really difficult in Java, however, it relies on a working \n> > diff implementation (and IIRC my implementation has not yet been \n> > integrated into JGit).\n> \n> Speaking of... where does that stand?\n\nSame as where I left off.  IOW it is a working implementation that saw \nsome testing, but I simply lack the time for performance tuning.\n\nIt should not be all that bad, though.\n\n***goes looking at \nhttp://repo.or.cz/w/jgit/dscho.git?a=shortlog;h=refs/heads/diff\n***\n\nSeems I misremembered a bit.  Christian provided a patch to make it \ncompileable, but I think that I ran the script to verify that the diffs \nare correct on jgit.git and IIRC it completed fine.\n\nThere is a project in my day-job, however, which eats all my time at the \nmoment (it is actually wrapping up a \"succeeded\" GSoC project where the \nstudent -- *sigh* -- has gone away).  So all I can do is to rebase to \ncurrent jgit.git's 's master, to run the script, and submit the current \npatch series (valuing correctness over speed).\n\nCiao,\nDscho\n"},{"id":"122346","messageId":"cover.1251974493u.git.johannes.schindelin@gmx.de","threadId":"20829","inReplyTo":"alpine.DEB.1.00.0909030846230.8306@pacific.mpi-cbg.de","subject":"[JGIT PATCH 0/5] jgit diff","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-09-03T10:45:43Z","receivedAt":"2009-09-03T10:45:43Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This patch series provides a rudimentary, working implementation of \"jgit \ndiff\".  It does not provide all modes of \"git diff\" -- by far! -- but it \nis robust, and should provide a good starting point for further work.\n\nUnfortunately, I lack the time to do proper profiling/benchmarking, but I \nverified at least that it succeeds in recreating valid patches for all \ncommits in jgit.git with this script:\n\n\tgit rev-list HEAD |\n\tsed '$d' |\n\twhile read commit\n\tdo\n\t        printf \"\\\\r$commit \"\n\t        (export GIT_INDEX_FILE=test-index &&\n\t         ./jgit diff $commit^ $commit > test-patch &&\n\t         git read-tree $commit^ &&\n\t         git apply --cached test-patch &&\n\t         git diff --exit-code --cached $commit) || break\n\tdone\n\nJohannes Schindelin (5):\n  Add set to IntList\n  Add Myers' algorithm to generate diff scripts\n  Add a test class for Myers' diff algorithm\n  Prepare RawText for diff-index and diff-files\n  Add the \"jgit diff\" command\n\n .../services/org.spearce.jgit.pgm.TextBuiltin      |    1 +\n .../src/org/spearce/jgit/pgm/Diff.java             |  133 +++++\n .../tst/org/spearce/jgit/diff/MyersDiffTest.java   |  103 ++++\n .../tst/org/spearce/jgit/util/IntListTest.java     |   21 +\n .../src/org/spearce/jgit/diff/DiffFormatter.java   |    2 +-\n .../src/org/spearce/jgit/diff/MyersDiff.java       |  515 ++++++++++++++++++++\n .../src/org/spearce/jgit/diff/RawText.java         |   28 +-\n .../src/org/spearce/jgit/util/IntList.java         |   17 +\n 8 files changed, 818 insertions(+), 2 deletions(-)\n create mode 100644 org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Diff.java\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/diff/MyersDiffTest.java\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/diff/MyersDiff.java\n"},{"id":"122347","messageId":"14843cb5774e11411f37a60e6cd16f7274649719.1251974493u.git.johannes.schindelin@gmx.de","threadId":"20829","inReplyTo":"cover.1251974493u.git.johannes.schindelin@gmx.de","subject":"[JGIT PATCH 1/5] Add set to IntList","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-09-03T10:46:31Z","receivedAt":"2009-09-03T10:46:31Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Some applications may wish to modify an int list.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n .../tst/org/spearce/jgit/util/IntListTest.java     |   21 ++++++++++++++++++++\n .../src/org/spearce/jgit/util/IntList.java         |   17 ++++++++++++++++\n 2 files changed, 38 insertions(+), 0 deletions(-)\n\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/util/IntListTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/util/IntListTest.java\nindex c470d55..a7a12cd 100644\n--- a/org.spearce.jgit.test/tst/org/spearce/jgit/util/IntListTest.java\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/util/IntListTest.java\n@@ -144,6 +144,27 @@ public void testClear() {\n \t\t}\n \t}\n \n+\tpublic void testSet() {\n+\t\tfinal IntList i = new IntList();\n+\t\ti.add(1);\n+\t\tassertEquals(1, i.size());\n+\t\tassertEquals(1, i.get(0));\n+\n+\t\ti.set(0, 5);\n+\t\tassertEquals(5, i.get(0));\n+\n+\t\ttry {\n+\t\t\ti.set(5, 5);\n+\t\t\tfail(\"accepted set of 5 beyond end of list\");\n+\t\t} catch (ArrayIndexOutOfBoundsException e){\n+\t\t\tassertTrue(true);\n+\t\t}\n+\n+\t\ti.set(1, 2);\n+\t\tassertEquals(2, i.size());\n+\t\tassertEquals(2, i.get(1));\n+\t}\n+\n \tpublic void testToString() {\n \t\tfinal IntList i = new IntList();\n \t\ti.add(1);\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/util/IntList.java b/org.spearce.jgit/src/org/spearce/jgit/util/IntList.java\nindex 0a84793..32d24fc 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/util/IntList.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/util/IntList.java\n@@ -94,6 +94,23 @@ public void add(final int n) {\n \t}\n \n \t/**\n+\t * Assign an entry in the list.\n+\t *\n+\t * @param index\n+\t *            index to set, must be in the range [0, {@link #size()}).\n+\t * @param n\n+\t *            value to store at the position.\n+\t */\n+\tpublic void set(final int index, final int n) {\n+\t\tif (count < index)\n+\t\t\tthrow new ArrayIndexOutOfBoundsException(index);\n+\t\telse if (count == index)\n+\t\t\tadd(n);\n+\t\telse\n+\t\t\tentries[index] = n;\n+\t}\n+\n+\t/**\n \t * Pad the list with entries.\n \t *\n \t * @param toIndex\n-- \n1.6.4.297.gcb4cc\n"},{"id":"122348","messageId":"71719b694f593f104537dd4c7246f4577d02125e.1251974493u.git.johannes.schindelin@gmx.de","threadId":"20829","inReplyTo":"cover.1251974493u.git.johannes.schindelin@gmx.de","subject":"[JGIT PATCH 2/5] Add Myers' algorithm to generate diff scripts","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-09-03T10:46:41Z","receivedAt":"2009-09-03T10:46:41Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Myers' algorithm is the standard way to generate diff scripts in an\nefficient manner (especially memory-wise).\n\nThe source contains extensive documentation about the principal\nideas of the algorithm.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n .../src/org/spearce/jgit/diff/MyersDiff.java       |  515 ++++++++++++++++++++\n 1 files changed, 515 insertions(+), 0 deletions(-)\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/diff/MyersDiff.java\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/diff/MyersDiff.java b/org.spearce.jgit/src/org/spearce/jgit/diff/MyersDiff.java\nnew file mode 100644\nindex 0000000..e19cea4\n--- /dev/null\n+++ b/org.spearce.jgit/src/org/spearce/jgit/diff/MyersDiff.java\n@@ -0,0 +1,515 @@\n+/*\n+ * Copyright (C) 2008-2009 Johannes E. Schindelin <johannes.schindelin@gmx.de>\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+/**\n+ * Diff algorithm, based on \"An O(ND) Difference Algorithm and its\n+ * Variations\", by Eugene Myers.\n+ *\n+ * The basic idea is to put the line numbers of text A as columns (\"x\") and the\n+ * lines of text B as rows (\"y\").  Now you try to find the shortest \"edit path\"\n+ * from the upper left corner to the lower right corner, where you can\n+ * always go horizontally or vertically, but diagonally from (x,y) to\n+ * (x+1,y+1) only if line x in text A is identical to line y in text B.\n+ *\n+ * Myers' fundamental concept is the \"furthest reaching D-path on diagonal k\":\n+ * a D-path is an edit path starting at the upper left corner and containing\n+ * exactly D non-diagonal elements (\"differences\").  The furthest reaching\n+ * D-path on diagonal k is the one that contains the most (diagonal) elements\n+ * which ends on diagonal k (where k = y - x).\n+ *\n+ * Example:\n+ *\n+ *    H E L L O   W O R L D\n+ *    ____\n+ *  L     \\___\n+ *  O         \\___\n+ *  W             \\________\n+ *\n+ * Since every D-path has exactly D horizontal or vertical elements, it can\n+ * only end on the diagonals -D, -D+2, ..., D-2, D.\n+ *\n+ * Since every furthest reaching D-path contains at least one furthest\n+ * reaching (D-1)-path (except for D=0), we can construct them recursively.\n+ *\n+ * Since we are really interested in the shortest edit path, we can start\n+ * looking for a 0-path, then a 1-path, and so on, until we find a path that\n+ * ends in the lower right corner.\n+ *\n+ * To save space, we do not need to store all paths (which has quadratic space\n+ * requirements), but generate the D-paths simultaneously from both sides.\n+ * When the ends meet, we will have found \"the middle\" of the path.  From the\n+ * end points of that diagonal part, we can generate the rest recursively.\n+ *\n+ * This only requires linear space.\n+ *\n+ * The overall (runtime) complexity is\n+ *\n+ *\tO(N * D^2 + 2 * N/2 * (D/2)^2 + 4 * N/4 * (D/4)^2 + ...)\n+ *\t= O(N * D^2 * 5 / 4) = O(N * D^2),\n+ *\n+ * (With each step, we have to find the middle parts of twice as many regions\n+ * as before, but the regions (as well as the D) are halved.)\n+ *\n+ * So the overall runtime complexity stays the same with linear space,\n+ * albeit with a larger constant factor.\n+ */\n+\n+package org.spearce.jgit.diff;\n+\n+import java.util.ArrayList;\n+import java.util.Iterator;\n+import java.util.List;\n+\n+import org.spearce.jgit.util.IntList;\n+\n+public class MyersDiff {\n+\tprotected EditList edits;\n+\tprotected Sequence a, b;\n+\n+\tpublic MyersDiff(Sequence a, Sequence b) {\n+\t\tthis.a = a;\n+\t\tthis.b = b;\n+\t\tcalculateEdits();\n+\t}\n+\n+\tpublic EditList getEdits() {\n+\t\treturn edits;\n+\t}\n+\n+\t// TODO: use ThreadLocal for future multi-threaded operations\n+\tMiddleEdit middle = new MiddleEdit();\n+\n+\tprotected void calculateEdits() {\n+\t\tedits = new EditList();\n+\n+\t\tmiddle.initialize(0, a.size(), 0, b.size());\n+\t\tif (middle.beginA >= middle.endA &&\n+\t\t\t\tmiddle.beginB >= middle.endB)\n+\t\t\treturn;\n+\n+\t\tcalculateEdits(middle.beginA, middle.endA,\n+\t\t\t\tmiddle.beginB, middle.endB);\n+\t}\n+\n+\tprotected void calculateEdits(int beginA, int endA,\n+\t\t\tint beginB, int endB) {\n+\t\tEdit edit = middle.calculate(beginA, endA, beginB, endB);\n+\n+\t\tif (beginA < edit.beginA || beginB < edit.beginB) {\n+\t\t\tint k = edit.beginB - edit.beginA;\n+\t\t\tint x = middle.backward.snake(k, edit.beginA);\n+\t\t\tcalculateEdits(beginA, x, beginB, k + x);\n+\t\t}\n+\n+\t\tif (edit.getType() != Edit.Type.EMPTY)\n+\t\t\tedits.add(edits.size(), edit);\n+\n+\t\t// after middle\n+\t\tif (endA > edit.endA || endB > edit.endB) {\n+\t\t\tint k = edit.endB - edit.endA;\n+\t\t\tint x = middle.forward.snake(k, edit.endA);\n+\t\t\tcalculateEdits(x, endA, k + x, endB);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * A class to help bisecting the sequences a and b to find minimal\n+\t * edit paths.\n+\t *\n+\t * As the arrays are reused for space efficiency, you will need one\n+\t * instance per thread.\n+\t *\n+\t * The entry function is the calculate() method.\n+\t */\n+\tclass MiddleEdit {\n+\t\tvoid initialize(int beginA, int endA, int beginB, int endB) {\n+\t\t\tthis.beginA = beginA; this.endA = endA;\n+\t\t\tthis.beginB = beginB; this.endB = endB;\n+\n+\t\t\t// strip common parts on either end\n+\t\t\tint k = beginB - beginA;\n+\t\t\tthis.beginA = forward.snake(k, beginA);\n+\t\t\tthis.beginB = k + this.beginA;\n+\n+\t\t\tk = endB - endA;\n+\t\t\tthis.endA = backward.snake(k, endA);\n+\t\t\tthis.endB = k + this.endA;\n+\t\t}\n+\n+\t\t/*\n+\t\t * This function calculates the \"middle\" Edit of the shortest\n+\t\t * edit path between the given subsequences of a and b.\n+\t\t *\n+\t\t * Once a forward path and a backward path meet, we found the\n+\t\t * middle part.  From the last snake end point on both of them,\n+\t\t * we construct the Edit.\n+\t\t *\n+\t\t * It is assumed that there is at least one edit in the range.\n+\t\t */\n+\t\t// TODO: measure speed impact when this is synchronized\n+\t\tEdit calculate(int beginA, int endA, int beginB, int endB) {\n+\t\t\tif (beginA == endA || beginB == endB)\n+\t\t\t\treturn new Edit(beginA, endA, beginB, endB);\n+\t\t\tthis.beginA = beginA; this.endA = endA;\n+\t\t\tthis.beginB = beginB; this.endB = endB;\n+\n+\t\t\t/*\n+\t\t\t * Following the conventions in Myers' paper, \"k\" is\n+\t\t\t * the difference between the index into \"b\" and the\n+\t\t\t * index into \"a\".\n+\t\t\t */\n+\t\t\tint minK = beginB - endA;\n+\t\t\tint maxK = endB - beginA;\n+\n+\t\t\tforward.initialize(beginB - beginA, beginA, minK, maxK);\n+\t\t\tbackward.initialize(endB - endA, endA, minK, maxK);\n+\n+\t\t\tfor (int d = 1; ; d++)\n+\t\t\t\tif (forward.calculate(d) ||\n+\t\t\t\t\t\tbackward.calculate(d))\n+\t\t\t\t\treturn edit;\n+\t\t}\n+\n+\t\t/*\n+\t\t * For each d, we need to hold the d-paths for the diagonals\n+\t\t * k = -d, -d + 2, ..., d - 2, d.  These are stored in the\n+\t\t * forward (and backward) array.\n+\t\t *\n+\t\t * As we allow subsequences, too, this needs some refinement:\n+\t\t * the forward paths start on the diagonal forwardK =\n+\t\t * beginB - beginA, and backward paths start on the diagonal\n+\t\t * backwardK = endB - endA.\n+\t\t *\n+\t\t * So, we need to hold the forward d-paths for the diagonals\n+\t\t * k = forwardK - d, forwardK - d + 2, ..., forwardK + d and\n+\t\t * the analogue for the backward d-paths.  This means that\n+\t\t * we can turn (k, d) into the forward array index using this\n+\t\t * formula:\n+\t\t *\n+\t\t *\ti = (d + k - forwardK) / 2\n+\t\t *\n+\t\t * There is a further complication: the edit paths should not\n+\t\t * leave the specified subsequences, so k is bounded by\n+\t\t * minK = beginB - endA and maxK = endB - beginA.  However,\n+\t\t * (k - forwardK) _must_ be odd whenever d is odd, and it\n+\t\t * _must_ be even when d is even.\n+\t\t *\n+\t\t * The values in the \"forward\" and \"backward\" arrays are\n+\t\t * positions (\"x\") in the sequence a, to get the corresponding\n+\t\t * positions (\"y\") in the sequence b, you have to calculate\n+\t\t * the appropriate k and then y:\n+\t\t *\n+\t\t *\tk = forwardK - d + i * 2\n+\t\t *\ty = k + x\n+\t\t *\n+\t\t * (substitute backwardK for forwardK if you want to get the\n+\t\t * y position for an entry in the \"backward\" array.\n+\t\t */\n+\t\tEditPaths forward = new ForwardEditPaths();\n+\t\tEditPaths backward = new BackwardEditPaths();\n+\n+\t\t/* Some variables which are shared between methods */\n+\t\tprotected int beginA, endA, beginB, endB;\n+\t\tprotected Edit edit;\n+\n+\t\tabstract class EditPaths {\n+\t\t\tprivate IntList x = new IntList();\n+\t\t\tprivate IntList snake = new IntList();\n+\t\t\tint beginK, endK, middleK;\n+\t\t\tint prevBeginK, prevEndK;\n+\t\t\t/* if we hit one end early, no need to look further */\n+\t\t\tint minK, maxK; // TODO: better explanation\n+\n+\t\t\tfinal int getIndex(int d, int k) {\n+// TODO: remove\n+if (((d + k - middleK) % 2) == 1)\n+\tthrow new RuntimeException(\"odd: \" + d + \" + \" + k + \" - \" + middleK);\n+\t\t\t\treturn (d + k - middleK) / 2;\n+\t\t\t}\n+\n+\t\t\tfinal int getX(int d, int k) {\n+// TODO: remove\n+if (k < beginK || k > endK)\n+\tthrow new RuntimeException(\"k \" + k + \" not in \" + beginK + \" - \" + endK);\n+\t\t\t\treturn x.get(getIndex(d, k));\n+\t\t\t}\n+\n+\t\t\tfinal int getSnake(int d, int k) {\n+// TODO: remove\n+if (k < beginK || k > endK)\n+\tthrow new RuntimeException(\"k \" + k + \" not in \" + beginK + \" - \" + endK);\n+\t\t\t\treturn snake.get(getIndex(d, k));\n+\t\t\t}\n+\n+\t\t\tprivate int forceKIntoRange(int k) {\n+\t\t\t\t/* if k is odd, so must be the result */\n+\t\t\t\tif (k < minK)\n+\t\t\t\t\treturn minK + ((k ^ minK) & 1);\n+\t\t\t\telse if (k > maxK)\n+\t\t\t\t\treturn maxK - ((k ^ maxK) & 1);\n+\t\t\t\treturn k;\n+\t\t\t}\n+\n+\t\t\tvoid initialize(int k, int x, int minK, int maxK) {\n+\t\t\t\tthis.minK = minK;\n+\t\t\t\tthis.maxK = maxK;\n+\t\t\t\tbeginK = endK = middleK = k;\n+\t\t\t\tthis.x.clear();\n+\t\t\t\tthis.x.add(x);\n+\t\t\t\tsnake.clear();\n+\t\t\t\tsnake.add(newSnake(k, x));\n+\t\t\t}\n+\n+\t\t\tabstract int snake(int k, int x);\n+\t\t\tabstract int getLeft(int x);\n+\t\t\tabstract int getRight(int x);\n+\t\t\tabstract boolean isBetter(int left, int right);\n+\t\t\tabstract void adjustMinMaxK(final int k, final int x);\n+\t\t\tabstract boolean meets(int d, int k, int x, int snake);\n+\n+\t\t\tfinal int newSnake(int k, int x) {\n+\t\t\t\tint y = k + x;\n+\t\t\t\treturn x + (endA + 1) * y;\n+\t\t\t}\n+\n+\t\t\tfinal int snake2x(int snake) {\n+\t\t\t\treturn snake % (endA + 1);\n+\t\t\t}\n+\n+\t\t\tfinal int snake2y(int snake) {\n+\t\t\t\treturn snake / (endA + 1);\n+\t\t\t}\n+\n+\t\t\tfinal boolean makeEdit(int snake1, int snake2) {\n+\t\t\t\tint x1 = snake2x(snake1), x2 = snake2x(snake2);\n+\t\t\t\tint y1 = snake2y(snake1), y2 = snake2y(snake2);\n+\t\t\t\t/*\n+\t\t\t\t * Check for incompatible partial edit paths:\n+\t\t\t\t * when there are ambiguities, we might have\n+\t\t\t\t * hit incompatible (i.e. non-overlapping)\n+\t\t\t\t * forward/backward paths.\n+\t\t\t\t *\n+\t\t\t\t * In that case, just pretend that we have\n+\t\t\t\t * an empty edit at the end of one snake; this\n+\t\t\t\t * will force a decision which path to take\n+\t\t\t\t * in the next recursion step.\n+\t\t\t\t */\n+\t\t\t\tif (x1 > x2 || y1 > y2) {\n+\t\t\t\t\tx1 = x2;\n+\t\t\t\t\ty1 = y2;\n+\t\t\t\t}\n+\t\t\t\tedit = new Edit(x1, x2, y1, y2);\n+\t\t\t\treturn true;\n+\t\t\t}\n+\n+\t\t\tboolean calculate(int d) {\n+\t\t\t\tprevBeginK = beginK;\n+\t\t\t\tprevEndK = endK;\n+\t\t\t\tbeginK = forceKIntoRange(middleK - d);\n+\t\t\t\tendK = forceKIntoRange(middleK + d);\n+\t\t\t\t// TODO: handle i more efficiently\n+\t\t\t\t// TODO: walk snake(k, getX(d, k)) only once per (d, k)\n+\t\t\t\t// TODO: move end points out of the loop to avoid conditionals inside the loop\n+\t\t\t\t// go backwards so that we can avoid temp vars\n+\t\t\t\tfor (int k = endK; k >= beginK; k -= 2) {\n+\t\t\t\t\tint left = -1, right = -1;\n+\t\t\t\t\tint leftSnake = -1, rightSnake = -1;\n+\t\t\t\t\t// TODO: refactor into its own function\n+\t\t\t\t\tif (k > prevBeginK) {\n+\t\t\t\t\t\tint i = getIndex(d - 1, k - 1);\n+\t\t\t\t\t\tleft = x.get(i);\n+\t\t\t\t\t\tint end = snake(k - 1, left);\n+\t\t\t\t\t\tleftSnake = left != end ?\n+\t\t\t\t\t\t\tnewSnake(k - 1, end) :\n+\t\t\t\t\t\t\tsnake.get(i);\n+\t\t\t\t\t\tif (meets(d, k - 1, end, leftSnake))\n+\t\t\t\t\t\t\treturn true;\n+\t\t\t\t\t\tleft = getLeft(end);\n+\t\t\t\t\t}\n+\t\t\t\t\tif (k < prevEndK) {\n+\t\t\t\t\t\tint i = getIndex(d - 1, k + 1);\n+\t\t\t\t\t\tright = x.get(i);\n+\t\t\t\t\t\tint end = snake(k + 1, right);\n+\t\t\t\t\t\trightSnake = right != end ?\n+\t\t\t\t\t\t\tnewSnake(k + 1, end) :\n+\t\t\t\t\t\t\tsnake.get(i);\n+\t\t\t\t\t\tif (meets(d, k + 1, end, rightSnake))\n+\t\t\t\t\t\t\treturn true;\n+\t\t\t\t\t\tright = getRight(end);\n+\t\t\t\t\t}\n+\t\t\t\t\tint newX, newSnake;\n+\t\t\t\t\tif (k >= prevEndK ||\n+\t\t\t\t\t\t\t(k > prevBeginK &&\n+\t\t\t\t\t\t\t isBetter(left, right))) {\n+\t\t\t\t\t\tnewX = left;\n+\t\t\t\t\t\tnewSnake = leftSnake;\n+\t\t\t\t\t}\n+\t\t\t\t\telse {\n+\t\t\t\t\t\tnewX = right;\n+\t\t\t\t\t\tnewSnake = rightSnake;\n+\t\t\t\t\t}\n+\t\t\t\t\tif (meets(d, k, newX, newSnake))\n+\t\t\t\t\t\treturn true;\n+\t\t\t\t\tadjustMinMaxK(k, newX);\n+\t\t\t\t\tint i = getIndex(d, k);\n+\t\t\t\t\tx.set(i, newX);\n+\t\t\t\t\tsnake.set(i, newSnake);\n+\t\t\t\t}\n+\t\t\t\treturn false;\n+\t\t\t}\n+\t\t}\n+\n+\t\tclass ForwardEditPaths extends EditPaths {\n+\t\t\tfinal int snake(int k, int x) {\n+\t\t\t\tfor (; x < endA && k + x < endB; x++)\n+\t\t\t\t\tif (!a.equals(x, b, k + x))\n+\t\t\t\t\t\tbreak;\n+\t\t\t\treturn x;\n+\t\t\t}\n+\n+\t\t\tfinal int getLeft(final int x) {\n+\t\t\t\treturn x;\n+\t\t\t}\n+\n+\t\t\tfinal int getRight(final int x) {\n+\t\t\t\treturn x + 1;\n+\t\t\t}\n+\n+\t\t\tfinal boolean isBetter(final int left, final int right) {\n+\t\t\t\treturn left > right;\n+\t\t\t}\n+\n+\t\t\tfinal void adjustMinMaxK(final int k, final int x) {\n+\t\t\t\tif (x >= endA || k + x >= endB) {\n+\t\t\t\t\tif (k > backward.middleK)\n+\t\t\t\t\t\tmaxK = k;\n+\t\t\t\t\telse\n+\t\t\t\t\t\tminK = k;\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\tfinal boolean meets(int d, int k, int x, int snake) {\n+\t\t\t\tif (k < backward.beginK || k > backward.endK)\n+\t\t\t\t\treturn false;\n+\t\t\t\t// TODO: move out of loop\n+\t\t\t\tif (((d - 1 + k - backward.middleK) % 2) == 1)\n+\t\t\t\t\treturn false;\n+\t\t\t\tif (x < backward.getX(d - 1, k))\n+\t\t\t\t\treturn false;\n+\t\t\t\tmakeEdit(snake, backward.getSnake(d - 1, k));\n+\t\t\t\treturn true;\n+\t\t\t}\n+\t\t}\n+\n+\t\tclass BackwardEditPaths extends EditPaths {\n+\t\t\tfinal int snake(int k, int x) {\n+\t\t\t\tfor (; x > beginA && k + x > beginB; x--)\n+\t\t\t\t\tif (!a.equals(x - 1, b, k + x - 1))\n+\t\t\t\t\t\tbreak;\n+\t\t\t\treturn x;\n+\t\t\t}\n+\n+\t\t\tfinal int getLeft(final int x) {\n+\t\t\t\treturn x - 1;\n+\t\t\t}\n+\n+\t\t\tfinal int getRight(final int x) {\n+\t\t\t\treturn x;\n+\t\t\t}\n+\n+\t\t\tfinal boolean isBetter(final int left, final int right) {\n+\t\t\t\treturn left < right;\n+\t\t\t}\n+\n+\t\t\tfinal void adjustMinMaxK(final int k, final int x) {\n+\t\t\t\tif (x <= beginA || k + x <= beginB) {\n+\t\t\t\t\tif (k > forward.middleK)\n+\t\t\t\t\t\tmaxK = k;\n+\t\t\t\t\telse\n+\t\t\t\t\t\tminK = k;\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\tfinal boolean meets(int d, int k, int x, int snake) {\n+\t\t\t\tif (k < forward.beginK || k > forward.endK)\n+\t\t\t\t\treturn false;\n+\t\t\t\t// TODO: move out of loop\n+\t\t\t\tif (((d + k - forward.middleK) % 2) == 1)\n+\t\t\t\t\treturn false;\n+\t\t\t\tif (x > forward.getX(d, k))\n+\t\t\t\t\treturn false;\n+\t\t\t\tmakeEdit(forward.getSnake(d, k), snake);\n+\t\t\t\treturn true;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t// debugging (TODO: remove)\n+\tpublic void print(Sequence s, int begin, int end) {\n+\t\tRawText raw = (RawText)s;\n+\t\ttry {\n+\t\t\twhile (begin < end) {\n+\t\t\t\tSystem.err.print(\"\" + begin + \": \");\n+\t\t\t\traw.writeLine(System.err, begin++);\n+\t\t\t\tSystem.err.println(\"\");\n+\t\t\t}\n+\t\t} catch (Exception e) { e.printStackTrace(); }\n+\t}\n+\n+\tpublic void print(int beginA, int endA, int beginB, int endB) {\n+\t\tSystem.err.println(\"<<<<<<\");\n+\t\tprint(a, beginA, endA);\n+\t\tSystem.err.println(\"======\");\n+\t\tprint(b, beginB, endB);\n+\t\tSystem.err.println(\">>>>>>\");\n+\t}\n+\n+\tpublic static void main(String[] args) {\n+\t\tif (args.length != 2) {\n+\t\t\tSystem.err.println(\"Need 2 arguments\");\n+\t\t\tSystem.exit(1);\n+\t\t}\n+\t\ttry {\n+\t\t\tRawText a = new RawText(new java.io.File(args[0]));\n+\t\t\tRawText b = new RawText(new java.io.File(args[1]));\n+\t\t\tMyersDiff diff = new MyersDiff(a, b);\n+\t\t\tSystem.out.println(diff.getEdits().toString());\n+\t\t} catch (Exception e) {\n+\t\t\te.printStackTrace();\n+\t\t}\n+\t}\n+}\n-- \n1.6.4.297.gcb4cc\n"},{"id":"122349","messageId":"6363048a79f234bce8c06356aeab07c94eac85a7.1251974493u.git.johannes.schindelin@gmx.de","threadId":"20829","inReplyTo":"cover.1251974493u.git.johannes.schindelin@gmx.de","subject":"[JGIT PATCH 3/5] Add a test class for Myers' diff algorithm","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-09-03T10:46:51Z","receivedAt":"2009-09-03T10:46:51Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n .../tst/org/spearce/jgit/diff/MyersDiffTest.java   |  103 ++++++++++++++++++++\n 1 files changed, 103 insertions(+), 0 deletions(-)\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/diff/MyersDiffTest.java\n\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/diff/MyersDiffTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/diff/MyersDiffTest.java\nnew file mode 100644\nindex 0000000..0d62790\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/diff/MyersDiffTest.java\n@@ -0,0 +1,103 @@\n+/*\n+ * Copyright (C) 2009, Johannes E. Schindelin\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.diff;\n+\n+import junit.framework.TestCase;\n+\n+public class MyersDiffTest extends TestCase {\n+\tpublic void testAtEnd() {\n+\t\tassertDiff(\"HELLO\", \"HELL\", \" -4,1 +4,0\");\n+\t}\n+\n+\tpublic void testAtStart() {\n+\t\tassertDiff(\"Git\", \"JGit\", \" -0,0 +0,1\");\n+\t}\n+\n+\tpublic void testSimple() {\n+\t\tassertDiff(\"HELLO WORLD\", \"LOW\",\n+\t\t\t\" -0,3 +0,0 -5,1 +2,0 -7,4 +3,0\");\n+\t\t// is ambiguous, could be this, too:\n+\t\t// \" -0,2 +0,0 -3,1 +1,0 -5,1 +2,0 -7,4 +3,0\"\n+\t}\n+\n+\tpublic void assertDiff(String a, String b, String edits) {\n+\t\tMyersDiff diff = new MyersDiff(toCharArray(a), toCharArray(b));\n+System.err.println(\"edits: \" + diff.getEdits());\n+\t\tassertEquals(edits, toString(diff.getEdits()));\n+\t}\n+\n+\tprivate static String toString(EditList list) {\n+\t\tStringBuilder builder = new StringBuilder();\n+\t\tfor (Edit e : list)\n+\t\t\tbuilder.append(\" -\" + e.beginA\n+\t\t\t\t\t+ \",\" + (e.endA - e.beginA)\n+\t\t\t\t+ \" +\" + e.beginB + \",\" + (e.endB - e.beginB));\n+\t\treturn builder.toString();\n+\t}\n+\n+\tprivate static CharArray toCharArray(String s) {\n+\t\treturn new CharArray(s);\n+\t}\n+\n+\tprotected static String toString(Sequence seq, int begin, int end) {\n+\t\tCharArray a = (CharArray)seq;\n+\t\treturn new String(a.array, begin, end - begin);\n+\t}\n+\n+\tprotected static String toString(CharArray a, CharArray b,\n+\t\t\tint x, int k) {\n+\t\treturn \"(\" + x + \",\" + (k + x)\n+\t\t\t+ (x < 0 ? '<' :\n+\t\t\t\t\t(x >= a.array.length ?\n+\t\t\t\t\t '>' : a.array[x]))\n+\t\t\t+ (k + x < 0 ? '<' :\n+\t\t\t\t\t(k + x >= b.array.length ?\n+\t\t\t\t\t '>' : b.array[k + x]))\n+\t\t\t+ \")\";\n+\t}\n+\n+\tprivate static class CharArray implements Sequence {\n+\t\tchar[] array;\n+\t\tpublic CharArray(String s) { array = s.toCharArray(); }\n+\t\tpublic int size() { return array.length; }\n+\t\tpublic boolean equals(int i, Sequence other, int j) {\n+\t\t\tCharArray o = (CharArray)other;\n+\t\t\treturn array[i] == o.array[j];\n+\t\t}\n+\t}\n+}\n-- \n1.6.4.297.gcb4cc\n"},{"id":"122350","messageId":"ba3eaaf6590a49c904ef6f8e139c3201c53a7b11.1251974493u.git.johannes.schindelin@gmx.de","threadId":"20829","inReplyTo":"cover.1251974493u.git.johannes.schindelin@gmx.de","subject":"[JGIT PATCH 4/5] Prepare RawText for diff-index and diff-files","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-09-03T10:47:01Z","receivedAt":"2009-09-03T10:47:01Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n .../src/org/spearce/jgit/diff/RawText.java         |   28 +++++++++++++++++++-\n 1 files changed, 27 insertions(+), 1 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/diff/RawText.java b/org.spearce.jgit/src/org/spearce/jgit/diff/RawText.java\nindex 9886d36..15d1c12 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/diff/RawText.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/diff/RawText.java\n@@ -38,6 +38,8 @@\n \n package org.spearce.jgit.diff;\n \n+import java.io.File;\n+import java.io.FileInputStream;\n import java.io.IOException;\n import java.io.OutputStream;\n \n@@ -81,6 +83,18 @@ public RawText(final byte[] input) {\n \t\thashes = computeHashes();\n \t}\n \n+\t/**\n+\t * Create a new sequence from a file.\n+\t * <p>\n+\t * The entire file contents are used.\n+\t *\n+\t * @param file\n+\t *            the text file.\n+\t */\n+\tpublic RawText(File file) throws IOException {\n+\t\tthis(readFile(file));\n+\t}\n+\n \tpublic int size() {\n \t\t// The line map is always 2 entries larger than the number of lines in\n \t\t// the file. Index 0 is padded out/unused. The last index is the total\n@@ -181,4 +195,16 @@ protected int hashLine(final byte[] raw, int ptr, final int end) {\n \t\t\thash = (hash << 5) ^ (raw[ptr] & 0xff);\n \t\treturn hash;\n \t}\n-}\n\\ No newline at end of file\n+\n+\tprivate static byte[] readFile(File file) throws IOException {\n+\t\tbyte[] result = new byte[(int)file.length()];\n+\t\tFileInputStream in = new FileInputStream(file);\n+\t\tfor (int off = 0; off < result.length; ) {\n+\t\t\tint read = in.read(result, off, result.length - off);\n+\t\t\tif (read < 0)\n+\t\t\t\tthrow new IOException(\"Early EOF\");\n+\t\t\toff += read;\n+\t\t}\n+\t\treturn result;\n+\t}\n+}\n-- \n1.6.4.297.gcb4cc\n"},{"id":"122351","messageId":"258665cf172892785f4b72496f033b7cc18b8a2f.1251974493u.git.johannes.schindelin@gmx.de","threadId":"20829","inReplyTo":"cover.1251974493u.git.johannes.schindelin@gmx.de","subject":"[JGIT PATCH 5/5] Add the \"jgit diff\" command","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-09-03T10:47:08Z","receivedAt":"2009-09-03T10:47:08Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This commit contains fixes provided by Christian Halstrick.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n .../services/org.spearce.jgit.pgm.TextBuiltin      |    1 +\n .../src/org/spearce/jgit/pgm/Diff.java             |  133 ++++++++++++++++++++\n .../src/org/spearce/jgit/diff/DiffFormatter.java   |    2 +-\n 3 files changed, 135 insertions(+), 1 deletions(-)\n create mode 100644 org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Diff.java\n\ndiff --git a/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin b/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin\nindex 3a8cc09..107ef38 100644\n--- a/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin\n+++ b/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin\n@@ -1,6 +1,7 @@\n org.spearce.jgit.pgm.Branch\n org.spearce.jgit.pgm.Clone\n org.spearce.jgit.pgm.Daemon\n+org.spearce.jgit.pgm.Diff\n org.spearce.jgit.pgm.DiffTree\n org.spearce.jgit.pgm.Fetch\n org.spearce.jgit.pgm.Glog\ndiff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Diff.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Diff.java\nnew file mode 100644\nindex 0000000..56e352d\n--- /dev/null\n+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Diff.java\n@@ -0,0 +1,133 @@\n+/*\n+ * Copyright (C) 2009, Johannes E. Schindelin\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.pgm;\n+\n+import java.io.IOException;\n+import java.io.PrintStream;\n+\n+import java.util.ArrayList;\n+import java.util.List;\n+\n+import org.kohsuke.args4j.Argument;\n+import org.kohsuke.args4j.ExampleMode;\n+import org.kohsuke.args4j.Option;\n+\n+import org.spearce.jgit.diff.DiffFormatter;\n+import org.spearce.jgit.diff.MyersDiff;\n+import org.spearce.jgit.diff.RawText;\n+\n+import org.spearce.jgit.lib.Constants;\n+import org.spearce.jgit.lib.FileMode;\n+import org.spearce.jgit.lib.ObjectId;\n+import org.spearce.jgit.lib.Ref;\n+\n+import org.spearce.jgit.pgm.opt.CmdLineParser;\n+import org.spearce.jgit.pgm.opt.PathTreeFilterHandler;\n+\n+import org.spearce.jgit.treewalk.AbstractTreeIterator;\n+import org.spearce.jgit.treewalk.TreeWalk;\n+\n+import org.spearce.jgit.treewalk.filter.AndTreeFilter;\n+import org.spearce.jgit.treewalk.filter.TreeFilter;\n+\n+@Command(common = true, usage = \"Show diffs\")\n+class Diff extends TextBuiltin {\n+\t@Argument(index = 0, metaVar = \"tree-ish\", required = true)\n+\tvoid tree_0(final AbstractTreeIterator c) {\n+\t\ttrees.add(c);\n+\t}\n+\n+\t@Argument(index = 1, metaVar = \"tree-ish\", required = true)\n+\tprivate final List<AbstractTreeIterator> trees = new ArrayList<AbstractTreeIterator>();\n+\n+\t@Option(name = \"--\", metaVar = \"path\", multiValued = true, handler = PathTreeFilterHandler.class)\n+\tprivate TreeFilter pathFilter = TreeFilter.ALL;\n+\n+\tprivate DiffFormatter fmt = new DiffFormatter();\n+\n+\t@Override\n+\tprotected void run() throws Exception {\n+\t\tfinal TreeWalk walk = new TreeWalk(db);\n+\t\twalk.reset();\n+\t\twalk.setRecursive(true);\n+\t\tfor (final AbstractTreeIterator i : trees)\n+\t\t\twalk.addTree(i);\n+\t\twalk.setFilter(AndTreeFilter.create(TreeFilter.ANY_DIFF, pathFilter));\n+\n+\t\tfinal int nTree = walk.getTreeCount();\n+\t\twhile (walk.next())\n+\t\t\toutputDiff(System.out, walk.getPathString(),\n+\t\t\t\twalk.getObjectId(0), walk.getFileMode(0),\n+\t\t\t\twalk.getObjectId(1), walk.getFileMode(1));\n+\t}\n+\n+\tprotected void outputDiff(PrintStream out, String path,\n+\t\t\tObjectId id1, FileMode mode1, ObjectId id2, FileMode mode2) throws IOException {\n+\t\tString name1 = \"a/\" + path;\n+\t\tString name2 =  \"b/\" + path;\n+\t\tout.println(\"diff --git \" + name1 + \" \" + name2);\n+\t\tboolean isNew=false;\n+\t\tboolean isDelete=false;\n+\t\tif (id1.equals(id1.zeroId())) {\n+\t\t\tout.println(\"new file mode \" + mode2);\n+\t\t\tisNew=true;\n+\t\t} else if (id2.equals(id2.zeroId())) {\n+\t\t\tout.println(\"deleted file mode \" + mode1);\n+\t\t\tisDelete=true;\n+\t\t} else if (!mode1.equals(mode2)) {\n+\t\t\tout.println(\"old mode \" + mode1);\n+\t\t\tout.println(\"new mode \" + mode2);\n+\t\t}\n+\t\tout.println(\"index \" + id1.abbreviate(db, 7).name()\n+\t\t\t+ \"..\" + id2.abbreviate(db, 7).name()\n+\t\t\t+ (mode1.equals(mode2) ? \" \" + mode1 : \"\"));\n+\t\tout.println(\"--- \" + (isNew ?  \"/dev/null\" : name1));\n+\t\tout.println(\"+++ \" + (isDelete ?  \"/dev/null\" : name2));\n+\t\tRawText a = getRawText(id1);\n+\t\tRawText b = getRawText(id2);\n+\t\tMyersDiff diff = new MyersDiff(a, b);\n+\t\tfmt.formatEdits(out, a, b, diff.getEdits());\n+\t}\n+\n+\tprivate RawText getRawText(ObjectId id) throws IOException {\n+\t\tif (id.equals(id.zeroId()))\n+\t\t\treturn new RawText(new byte[] { });\n+\t\treturn new RawText(db.openBlob(id).getCachedBytes());\n+\t}\n+}\n+\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/diff/DiffFormatter.java b/org.spearce.jgit/src/org/spearce/jgit/diff/DiffFormatter.java\nindex fa86737..fda3f4c 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/diff/DiffFormatter.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/diff/DiffFormatter.java\n@@ -108,7 +108,7 @@ public void format(final OutputStream out, final FileHeader head,\n \t\tformatEdits(out, a, b, head.toEditList());\n \t}\n \n-\tprivate void formatEdits(final OutputStream out, final RawText a,\n+\tpublic void formatEdits(final OutputStream out, final RawText a,\n \t\t\tfinal RawText b, final EditList edits) throws IOException {\n \t\tfor (int curIdx = 0; curIdx < edits.size();) {\n \t\t\tEdit curEdit = edits.get(curIdx);\n-- \n1.6.4.297.gcb4cc\n"},{"id":"122352","messageId":"alpine.DEB.1.00.0909031247310.4409@intel-tinevez-2-302","threadId":"20829","inReplyTo":"cover.1251974493u.git.johannes.schindelin@gmx.de","subject":"Re: [JGIT PATCH 0/5] jgit diff","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-09-03T10:48:14Z","receivedAt":"2009-09-03T10:48:14Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 3 Sep 2009, Johannes Schindelin wrote:\n\n> This patch series provides a rudimentary, working implementation of \n> \"jgit diff\".  It does not provide all modes of \"git diff\" -- by far! -- \n> but it is robust, and should provide a good starting point for further \n> work.\n\nI forgot to mention that this is rebased to current jgit.git's master (and \ntested there, too; took 713 seconds on this here machine).\n\nCiao,\nDscho\n"},{"id":"122356","messageId":"2c6b72b30909030545y4465b5c8j4b2b5587a07762c0@mail.gmail.com","threadId":"20829","inReplyTo":"20090903012207.GF1033@spearce.org","subject":"Re: [JGIT] Request for help","fromName":"Jonas Fonseca","fromEmail":"jonas.fonseca@gmail.com","sentAt":"2009-09-03T12:45:49Z","receivedAt":"2009-09-03T12:45:49Z","isPatch":false,"sender":{"key":"jonas.fonseca@gmail.com","avatar":"https://gravatar.com/avatar/9b7fa23cce50269e5d164312b6ac5ae818a180f837b38f28f3bdf689dd7f96cd?d=mp&s=160"},"body":"On Wed, Sep 2, 2009 at 21:22, Shawn O. Pearce<spearce@spearce.org> wrote:\n> Yea, for the most part I think we use Eclipse, and you just have\n> to import JGit's top level directory into Eclipse as it comes with\n> Eclipse project files.  But I know some folks only use our Maven\n> build (under jgit-maven/jgit) or use NetBeans.  I have no idea how\n> to import the project into the latter or configure its unit tests\n> to run.\n\nNetBeans comes with very good support for Maven projects. Importing\nJGit into NetBeans is just a matter of using the \"Open Project\" wizard\nand locating jgit-maven/jgit. This will also configure the unit tests\nto run.\n\nBTW, what is your opinion of making it a bit easier to import and use\nthe Maven configuration by putting a pom.xml in the top-level\ndirectory? The actual pom.xml file responsible for building the jgit\nlibrary can still live on in jgit-maven/ if that is preferable.\n\nI am also thinking about \"mavenizing\" the .pgm subproject to make it\neasier to browse and search the code from within NetBeans.\n\n-- \nJonas Fonseca\n"},{"id":"122358","messageId":"20090903144227.GH1033@spearce.org","threadId":"20829","inReplyTo":"2c6b72b30909030545y4465b5c8j4b2b5587a07762c0@mail.gmail.com","subject":"Re: [JGIT] Request for help","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-09-03T14:42:27Z","receivedAt":"2009-09-03T14:42:27Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Jonas Fonseca <jonas.fonseca@gmail.com> wrote:\n> BTW, what is your opinion of making it a bit easier to import and use\n> the Maven configuration by putting a pom.xml in the top-level\n> directory? The actual pom.xml file responsible for building the jgit\n> library can still live on in jgit-maven/ if that is preferable.\n> \n> I am also thinking about \"mavenizing\" the .pgm subproject to make it\n> easier to browse and search the code from within NetBeans.\n\nActually, now that we have forked out of the egit.git repository,\nI want to refactor the layout of the JGit project to be more maven\nlike, and have a proper top-level pom to build things.\n\nUnfortunately it seems that nobody can program a proper Maven pom\nfor a multi-project project unless they are one of the authors\nof Maven itself.  I watched the Apache MINA team struggle with it\nuntil the Maven guys wanted to use their code, and fixed their build.\n\nSo, this refactoring is waiting for a Maven guru to contribute\nan improvement.  Unfortunately they are all busy...\n\nSo, to answer your original question, yes, we should make this\nbetter, and patches are welcome.  My own Maven-fu is just not up\nto the task.\n\n-- \nShawn.\n"},{"id":"122359","messageId":"2c6b72b30909030838q10b88705gb8c553f2c2d74379@mail.gmail.com","threadId":"20829","inReplyTo":"20090903144227.GH1033@spearce.org","subject":"Re: [JGIT] Request for help","fromName":"Jonas Fonseca","fromEmail":"jonas.fonseca@gmail.com","sentAt":"2009-09-03T15:38:47Z","receivedAt":"2009-09-03T15:38:47Z","isPatch":false,"sender":{"key":"jonas.fonseca@gmail.com","avatar":"https://gravatar.com/avatar/9b7fa23cce50269e5d164312b6ac5ae818a180f837b38f28f3bdf689dd7f96cd?d=mp&s=160"},"body":"On Thu, Sep 3, 2009 at 10:42, Shawn O. Pearce<spearce@spearce.org> wrote:\n> Jonas Fonseca <jonas.fonseca@gmail.com> wrote:\n>> BTW, what is your opinion of making it a bit easier to import and use\n>> the Maven configuration by putting a pom.xml in the top-level\n>> directory? The actual pom.xml file responsible for building the jgit\n>> library can still live on in jgit-maven/ if that is preferable.\n>>\n>> I am also thinking about \"mavenizing\" the .pgm subproject to make it\n>> easier to browse and search the code from within NetBeans.\n>\n> Actually, now that we have forked out of the egit.git repository,\n> I want to refactor the layout of the JGit project to be more maven\n> like, and have a proper top-level pom to build things.\n\nWhat kind of module structure do you have in mind? Do you want to move\nsome of the modules/subdirectories?\nSome refactoring of the maven setup for JGit back was done back in\nApril in sonatype's (a maven company) JGit clone. It is not\nsigned-off, but can serve as a reference.\n\n - http://github.com/sonatype/JGit/commit/641ae523c496f381a7673f4acfa0acdff9d3913e\n\nThe Maven layout in the sonatype clone simply uses the Eclipse project layout.\n\npom.xml: JGit :: Parent\n |- org.spearce.jgit/pom.xml: JGit :: Core\n |- org.spearce.jgit.pgm/pom.xml: JGit :: Programs\n `- org.spearce.jgit.test/pom.xml: JGit :: Test\n\nHowever, having tests in a separate module can be both good/bad. For\nexample, they will not automatically get run when you only build the\nCore module.\n\nAnyway, I would like to help.\n\n-- \nJonas Fonseca\n"},{"id":"122360","messageId":"20090903155219.GI1033@spearce.org","threadId":"20829","inReplyTo":"2c6b72b30909030838q10b88705gb8c553f2c2d74379@mail.gmail.com","subject":"Re: [JGIT] Request for help","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-09-03T15:52:19Z","receivedAt":"2009-09-03T15:52:19Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Jonas Fonseca <jonas.fonseca@gmail.com> wrote:\n> On Thu, Sep 3, 2009 at 10:42, Shawn O. Pearce<spearce@spearce.org> wrote:\n> > Actually, now that we have forked out of the egit.git repository,\n> > I want to refactor the layout of the JGit project to be more maven\n> > like, and have a proper top-level pom to build things.\n> \n> What kind of module structure do you have in mind? Do you want to move\n> some of the modules/subdirectories?\n> Some refactoring of the maven setup for JGit back was done back in\n> April in sonatype's (a maven company) JGit clone. It is not\n> signed-off, but can serve as a reference.\n\nYea, I was hoping they would contribute this back as patches,\nbut thus far they haven't.\n \n> The Maven layout in the sonatype clone simply uses the Eclipse project layout.\n> \n> pom.xml: JGit :: Parent\n>  |- org.spearce.jgit/pom.xml: JGit :: Core\n>  |- org.spearce.jgit.pgm/pom.xml: JGit :: Programs\n>  `- org.spearce.jgit.test/pom.xml: JGit :: Test\n> \n> However, having tests in a separate module can be both good/bad. For\n> example, they will not automatically get run when you only build the\n> Core module.\n\nYea, I know.  This is one area where Maven is just whack, by putting\nthe tests in the same project the Maven plugin for Eclipse puts\nthem into the same classpath, which means you can see test code\nfrom project code.  Wrong.  They should be different projects so\nthe test classpath is isolated.\n\nHowever.  This is a bug in the Eclipse plugin I think, not\nnecessarily with Maven's approach of trying to keep tests alongside\nthe code they test.  Thus we probably want:\n\n  pom.xml: JGit :: Parent\n   |- jgit-lib/pom.xml: JGit\n   |     src/main/java  <-- from org.spearce.jgit/src\n   |     src/test/java  <-- from org.spearce.jgit.test/src\n   |\n   `- jgit-pgm/pom.xml: JGit pgm\n         src/main/java  <-- from org.spearce.jgit.pgm/src\n\nIIRC there is Maven support to create proper MANIFEST.MF files for\nOSGI bundles, which is what we need for the Eclipse plugin support.\nThat should be able to replace the META-INF/MANIFEST.MF in the top\nof each of the current directories.\n\n> Anyway, I would like to help.\n\nPlease post patches; formatted with -M.  I do want to do this, I just\ndon't have the patience and Maven-fu to write the new poms myself.\n\n-- \nShawn.\n"},{"id":"122361","messageId":"loom.20090903T155033-910@post.gmane.org","threadId":"20829","inReplyTo":"alpine.DEB.1.00.0909030846230.8306@pacific.mpi-cbg.de","subject":"Re: jgit diff, was Re: [JGIT] Request for help","fromName":"Christian Halstrick","fromEmail":"christian.halstrick@sap.com","sentAt":"2009-09-03T15:54:35Z","receivedAt":"2009-09-03T15:54:35Z","isPatch":false,"sender":{"key":"christian.halstrick@sap.com","avatar":"https://gravatar.com/avatar/032940727041870bc7374e44e8f659ac0a8f8d97d679b4c2cbd05bcb39b088bb?d=mp&s=160"},"body":"Johannes Schindelin <Johannes.Schindelin <at> gmx.de> writes:\n\n...\n> > > This is not really difficult in Java, however, it relies on a working \n> > > diff implementation (and IIRC my implementation has not yet been \n> > > integrated into JGit).\n> > \n> > Speaking of... where does that stand?\n> \n> Same as where I left off.  IOW it is a working implementation that saw \n> some testing, but I simply lack the time for performance tuning.\n\nI can offer my help here. I looked at Dscho's code before, provided patches to\nlet it compile and run the tests (IIRC not fully successfully). I started in my\nlocal repo to modify enhance the tests but didn't finished with that yet. I'll\ntry now to add some performance tests and tests derived from native Git diff \ntests. \n\n> \n> It should not be all that bad, though.\n> \n...\n> Seems I misremembered a bit.  Christian provided a patch to make it \n> compileable, but I think that I ran the script to verify that the diffs \n> are correct on jgit.git and IIRC it completed fine.\n"},{"id":"122366","messageId":"4AA01D08.3060400@codeaurora.org","threadId":"20829","inReplyTo":"20090903012315.GG1033@spearce.org","subject":"Re: [JGIT] Request for help","fromName":"Nasser Grainawi","fromEmail":"nasser@codeaurora.org","sentAt":"2009-09-03T19:46:16Z","receivedAt":"2009-09-03T19:46:16Z","isPatch":false,"sender":{"key":"nasser@codeaurora.org","avatar":"https://avatars.githubusercontent.com/u/757421?v=4"},"body":"Shawn O. Pearce wrote:\n> Nasser Grainawi <nasser@codeaurora.org> wrote:\n>> Should PatchId be a class on its own, or just a method within the Patch  \n>> class?\n> \n> Hmm, maybe a method on Patch is reasonable.\n> \n\nGoing down this route, I'd add a few things to Patch.\npatchId would be a private field (of type ObjectId?)\ngetPatchId would be a public method that returns patchId\nand then likely a private method (computePatchId?) that actually \ngenerates the patchId\n\nThis way any method in Patch that would potentially change a Patch \nobject's patch-id would call computePatchId before it returns.\n\nThoughts?\n"},{"id":"122367","messageId":"20090903194955.GL1033@spearce.org","threadId":"20829","inReplyTo":"4AA01D08.3060400@codeaurora.org","subject":"Re: [JGIT] Request for help","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-09-03T19:49:55Z","receivedAt":"2009-09-03T19:49:55Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Nasser Grainawi <nasser@codeaurora.org> wrote:\n> Shawn O. Pearce wrote:\n>> Hmm, maybe a method on Patch is reasonable.\n>\n> Going down this route, I'd add a few things to Patch.\n> patchId would be a private field (of type ObjectId?)\n> getPatchId would be a public method that returns patchId\n> and then likely a private method (computePatchId?) that actually  \n> generates the patchId\n\nSure, but getPatchId can compute it on demand on the first call,\nand anyone who modifies the Patch would just need to clear out\nthe cached patchId value so the next call (if it ever comes) to\ngetPatchId would force it to recompute.\n\nMost users of Patch won't want the patchId, so there is no reason\nto compute it.\n\n-- \nShawn.\n"},{"id":"122369","messageId":"4AA0308F.9@codeaurora.org","threadId":"20829","inReplyTo":"20090903194955.GL1033@spearce.org","subject":"Re: [JGIT] Request for help","fromName":"Nasser Grainawi","fromEmail":"nasser@codeaurora.org","sentAt":"2009-09-03T21:09:35Z","receivedAt":"2009-09-03T21:09:35Z","isPatch":false,"sender":{"key":"nasser@codeaurora.org","avatar":"https://avatars.githubusercontent.com/u/757421?v=4"},"body":"Shawn O. Pearce wrote:\n> Nasser Grainawi <nasser@codeaurora.org> wrote:\n>> Shawn O. Pearce wrote:\n>>> Hmm, maybe a method on Patch is reasonable.\n>> Going down this route, I'd add a few things to Patch.\n>> patchId would be a private field (of type ObjectId?)\n>> getPatchId would be a public method that returns patchId\n>> and then likely a private method (computePatchId?) that actually  \n>> generates the patchId\n> \n> Sure, but getPatchId can compute it on demand on the first call,\n> and anyone who modifies the Patch would just need to clear out\n> the cached patchId value so the next call (if it ever comes) to\n> getPatchId would force it to recompute.\n> \n> Most users of Patch won't want the patchId, so there is no reason\n> to compute it.\n> \nWorks for me, that's even easier. I'll get to work on implementing this,\nbut between (re-)learning Java and our legal dept, don't know when I'll\nhave a finished product to share...\n\nI'll continue to post questions as I get them.\nThanks everyone for their help thus far :)\n"},{"id":"122387","messageId":"loom.20090904T064602-511@post.gmane.org","threadId":"20829","inReplyTo":"20090903155219.GI1033@spearce.org","subject":"Re: [JGIT] Request for help","fromName":"Gabe McArthur","fromEmail":"gabriel.mcarthur@gmail.com","sentAt":"2009-09-04T05:00:37Z","receivedAt":"2009-09-04T05:00:37Z","isPatch":false,"sender":{"key":"gabriel.mcarthur@gmail.com","avatar":"https://gravatar.com/avatar/434c21d8f1156f0f0ba4459af899f1d18e33e7158febc3be490d344f2d252261?d=mp&s=160"},"body":" \nShawn O. Pearce <spearce <at> spearce.org> writes:\n\n> \n> Please post patches; formatted with -M.  I do want to do this, I just\n> don't have the patience and Maven-fu to write the new poms myself.\n> \n\n\nHey,\nI'm a build engineer with a considerable amount of \"Maven-fu\" :).  I've actually \ngenerated a patch that does everything you want (and a bit more).  I'm not that \nfamiliar with git's command line yet, so it's a bit tricky to get the patch \nthing right.  However, here's a rough overview of what I did:\n\nROOT\n====\nREADME\n/bin\n  bash.env   -- A script that you can source from Bash that\n                will add the 'jgit' executable and the other\n                scripts in this 'bin' directory to your PATH\n  build.sh   -- A general build script, that hides some\n                Maven complexities for initiates.\n  tag.sh     -- Ok, this is the only thing that will have to \n                be re-written.  It's too tied in with git commands for\n                me to fully extract what it's supposed to do.\n/docs\n  LICENSE\n  SUBMITTING_PATCHES\n  TODO\npom.xml      -- A considerable amount of build logic has been\n                centralized here.  It references 3 sub-module\n                projects, listed below.\n/sources\n  /jgit-lib\n    pom.xml\n    /src/main/java....\n    /src/test\n      /java....\n      /resources \n      /exttst   -- Don't know exactly where this goes, as it\n                   doesn't seem to be doing much/being run \n                   currently.\n  /jgit-pgm\n    pom.xml     -- Does the work to do a 'jar-with-dependencies' \n                   so that org.spearce.jgit.pgm.build can be removed.\n    /src/main/java....\n  /jgit-exec\n    pom.xml     -- Actually generates the 'jgit' executable and\n                   installs it in ROOT/target/bin, so that it will\n                   be on your path after sourcing 'bin/bash.env'\n    /src/main/scripts/jgit\n\nI'll try to submit a full patch later, using your conventions.\n\nMy appreciation to Shawn for pointing out this thread....\n-Gabe\n                \n"},{"id":"122393","messageId":"554991.93608.qm@web27807.mail.ukl.yahoo.com","threadId":"20829","inReplyTo":"loom.20090904T064602-511@post.gmane.org","subject":"Re: [JGIT] Request for help","fromName":"Mark Struberg","fromEmail":"struberg@yahoo.de","sentAt":"2009-09-04T07:33:06Z","receivedAt":"2009-09-04T07:33:06Z","isPatch":false,"sender":{"key":"struberg@yahoo.de","avatar":"https://gravatar.com/avatar/119742c3e8dbc8db35a92bdff0581aec8d364d415f770e60431cba262daa974f?d=mp&s=160"},"body":"Seems this speeds up lately ;)\n\nGabe, please allow me a few questions:\n\n.) why do we need the /sources directory layer? I think /jgit and /jgit-pgm would be enough.\n\n.) imho the docs should stay in / at least the LICENSE file\n\n.) we don't need a tag.sh any more if we work with maven. Maven now has the maven-scm-provider-gitexe activated by default (since early 2008), so \nmvn release:prepare\nmvn release:perform\nshould work if we set the proper <scm> section. Any feedback or bugreporting on the maven-git integration is highly welcome btw ;)\n\n\nLieGrue,\nstrub\n\n\n--- On Fri, 9/4/09, Gabe McArthur <gabriel.mcarthur@gmail.com> wrote:\n\n> From: Gabe McArthur <gabriel.mcarthur@gmail.com>\n> Subject: Re: [JGIT] Request for help\n> To: git@vger.kernel.org\n> Date: Friday, September 4, 2009, 7:00 AM\n>  \n> Shawn O. Pearce <spearce <at> spearce.org>\n> writes:\n> \n> > \n> > Please post patches; formatted with -M.  I do\n> want to do this, I just\n> > don't have the patience and Maven-fu to write the new\n> poms myself.\n> > \n> \n> \n> Hey,\n> I'm a build engineer with a considerable amount of\n> \"Maven-fu\" :).  I've actually \n> generated a patch that does everything you want (and a bit\n> more).  I'm not that \n> familiar with git's command line yet, so it's a bit tricky\n> to get the patch \n> thing right.  However, here's a rough overview of what\n> I did:\n> \n> ROOT\n> ====\n> README\n> /bin\n>   bash.env   -- A script that you can\n> source from Bash that\n>                \n> will add the 'jgit' executable and the other\n>                \n> scripts in this 'bin' directory to your PATH\n>   build.sh   -- A general build script,\n> that hides some\n>                \n> Maven complexities for initiates.\n>   tag.sh     -- Ok, this is the\n> only thing that will have to \n>                 be\n> re-written.  It's too tied in with git commands for\n>                 me\n> to fully extract what it's supposed to do.\n> /docs\n>   LICENSE\n>   SUBMITTING_PATCHES\n>   TODO\n> pom.xml      -- A considerable amount of\n> build logic has been\n>                \n> centralized here.  It references 3 sub-module\n>                \n> projects, listed below.\n> /sources\n>   /jgit-lib\n>     pom.xml\n>     /src/main/java....\n>     /src/test\n>       /java....\n>       /resources \n>       /exttst   -- Don't know\n> exactly where this goes, as it\n>                \n>    doesn't seem to be doing much/being run \n>                \n>    currently.\n>   /jgit-pgm\n>     pom.xml     -- Does the\n> work to do a 'jar-with-dependencies' \n>                \n>    so that org.spearce.jgit.pgm.build can be\n> removed.\n>     /src/main/java....\n>   /jgit-exec\n>     pom.xml     -- Actually\n> generates the 'jgit' executable and\n>                \n>    installs it in ROOT/target/bin, so that it\n> will\n>                \n>    be on your path after sourcing\n> 'bin/bash.env'\n>     /src/main/scripts/jgit\n> \n> I'll try to submit a full patch later, using your\n> conventions.\n> \n> My appreciation to Shawn for pointing out this thread....\n> -Gabe\n>                 \n> \n> --\n> To unsubscribe from this list: send the line \"unsubscribe\n> git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n> \n\n\n      \n"},{"id":"122426","messageId":"2c6b72b30909040522l4f27ed36u10f47517d42d57a3@mail.gmail.com","threadId":"20829","inReplyTo":"554991.93608.qm@web27807.mail.ukl.yahoo.com","subject":"Re: [JGIT] Request for help","fromName":"Jonas Fonseca","fromEmail":"jonas.fonseca@gmail.com","sentAt":"2009-09-04T12:22:11Z","receivedAt":"2009-09-04T12:22:11Z","isPatch":false,"sender":{"key":"jonas.fonseca@gmail.com","avatar":"https://gravatar.com/avatar/9b7fa23cce50269e5d164312b6ac5ae818a180f837b38f28f3bdf689dd7f96cd?d=mp&s=160"},"body":"On Fri, Sep 4, 2009 at 03:33, Mark Struberg<struberg@yahoo.de> wrote:\n> .) we don't need a tag.sh any more if we work with maven. Maven now has the maven-scm-provider-gitexe activated by default (since early 2008), so\n> mvn release:prepare\n> mvn release:perform\n> should work if we set the proper <scm> section. Any feedback or bugreporting on the maven-git integration is highly welcome btw ;)\n\nIf tag_jgit.sh goes away, it could be nice to add a document showing\nhow releasing/tagging it's done the maven way.\n\n-- \nJonas Fonseca\n"},{"id":"122427","messageId":"843148.96940.qm@web27803.mail.ukl.yahoo.com","threadId":"20829","inReplyTo":"2c6b72b30909040522l4f27ed36u10f47517d42d57a3@mail.gmail.com","subject":"Re: [JGIT] Request for help","fromName":"Mark Struberg","fromEmail":"struberg@yahoo.de","sentAt":"2009-09-04T12:27:13Z","receivedAt":"2009-09-04T12:27:13Z","isPatch":false,"sender":{"key":"struberg@yahoo.de","avatar":"https://gravatar.com/avatar/119742c3e8dbc8db35a92bdff0581aec8d364d415f770e60431cba262daa974f?d=mp&s=160"},"body":"Hi Jonas!\n\nSee the following documentation:\n\nhttp://maven.apache.org/plugins/maven-release-plugin/index.html\nhttp://maven.apache.org/plugins/maven-release-plugin/examples/prepare-release.html\nhttp://maven.apache.org/plugins/maven-release-plugin/examples/perform-release.html\n\nThere is also a freely available book from sonatype [1] which contains all the documemtation you need - plus fn lot more :)\n\nLieGrue,\nstrub\n\n[1] http://www.sonatype.com/book/\n\n\n--- On Fri, 9/4/09, Jonas Fonseca <jonas.fonseca@gmail.com> wrote:\n\n> From: Jonas Fonseca <jonas.fonseca@gmail.com>\n> Subject: Re: [JGIT] Request for help\n> To: \"Mark Struberg\" <struberg@yahoo.de>\n> Cc: git@vger.kernel.org, \"Gabe McArthur\" <gabriel.mcarthur@gmail.com>\n> Date: Friday, September 4, 2009, 2:22 PM\n> On Fri, Sep 4, 2009 at 03:33, Mark\n> Struberg<struberg@yahoo.de>\n> wrote:\n> > .) we don't need a tag.sh any more if we work with\n> maven. Maven now has the maven-scm-provider-gitexe activated\n> by default (since early 2008), so\n> > mvn release:prepare\n> > mvn release:perform\n> > should work if we set the proper <scm> section.\n> Any feedback or bugreporting on the maven-git integration is\n> highly welcome btw ;)\n> \n> If tag_jgit.sh goes away, it could be nice to add a\n> document showing\n> how releasing/tagging it's done the maven way.\n> \n> -- \n> Jonas Fonseca\n> \n\n\n      \n"},{"id":"122430","messageId":"2c6b72b30909040541t4c781378g3f35aeb70021050c@mail.gmail.com","threadId":"20829","inReplyTo":"554991.93608.qm@web27807.mail.ukl.yahoo.com","subject":"Re: [JGIT] Request for help","fromName":"Jonas Fonseca","fromEmail":"jonas.fonseca@gmail.com","sentAt":"2009-09-04T12:41:07Z","receivedAt":"2009-09-04T12:41:07Z","isPatch":false,"sender":{"key":"jonas.fonseca@gmail.com","avatar":"https://gravatar.com/avatar/9b7fa23cce50269e5d164312b6ac5ae818a180f837b38f28f3bdf689dd7f96cd?d=mp&s=160"},"body":"On Fri, Sep 4, 2009 at 03:33, Mark Struberg<struberg@yahoo.de> wrote:\n>> From: Gabe McArthur <gabriel.mcarthur@gmail.com>\n> >\n>> I'll try to submit a full patch later, using your\n>> conventions.\n\nI have a question as well:\n\nSupport for using find bug is part of the Eclipse configuration (see\norg.spearce.jgit/findBugs/), and I know that there's a find bug plugin\nfor Maven. From looking at sonatype's JGit repositories it is not\nintegrated. Have you managed to include it?\n\n-- \nJonas Fonseca\n"},{"id":"122432","messageId":"956681.9844.qm@web27803.mail.ukl.yahoo.com","threadId":"20829","inReplyTo":"2c6b72b30909040541t4c781378g3f35aeb70021050c@mail.gmail.com","subject":"Re: [JGIT] Request for help","fromName":"Mark Struberg","fromEmail":"struberg@yahoo.de","sentAt":"2009-09-04T12:47:15Z","receivedAt":"2009-09-04T12:47:15Z","isPatch":false,"sender":{"key":"struberg@yahoo.de","avatar":"https://gravatar.com/avatar/119742c3e8dbc8db35a92bdff0581aec8d364d415f770e60431cba262daa974f?d=mp&s=160"},"body":"as an old saying tells us: how to climb a mountain? step after step! ;)\n\nI suggest we create a fresh branch based on the Shawns current version and add all the features incrementally.\n\n1.) move the directory structure over to mavens std layout\n2.) create the scm section and try releases\n3.) improve site generation and documentation\ntbc\n\n\nLieGrue,\nstrub\n\n\n--- On Fri, 9/4/09, Jonas Fonseca <jonas.fonseca@gmail.com> wrote:\n\n> From: Jonas Fonseca <jonas.fonseca@gmail.com>\n> Subject: Re: [JGIT] Request for help\n> To: \"Mark Struberg\" <struberg@yahoo.de>\n> Cc: git@vger.kernel.org, \"Gabe McArthur\" <gabriel.mcarthur@gmail.com>\n> Date: Friday, September 4, 2009, 2:41 PM\n> On Fri, Sep 4, 2009 at 03:33, Mark\n> Struberg<struberg@yahoo.de>\n> wrote:\n> >> From: Gabe McArthur <gabriel.mcarthur@gmail.com>\n> > >\n> >> I'll try to submit a full patch later, using your\n> >> conventions.\n> \n> I have a question as well:\n> \n> Support for using find bug is part of the Eclipse\n> configuration (see\n> org.spearce.jgit/findBugs/), and I know that there's a find\n> bug plugin\n> for Maven. From looking at sonatype's JGit repositories it\n> is not\n> integrated. Have you managed to include it?\n> \n> -- \n> Jonas Fonseca\n> \n\n\n      \n"},{"id":"124096","messageId":"20091001184721.GR14660@spearce.org","threadId":"20829","inReplyTo":"cover.1251974493u.git.johannes.schindelin@gmx.de","subject":"Re: [JGIT PATCH 0/5] jgit diff","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-10-01T18:47:21Z","receivedAt":"2009-10-01T18:47:21Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> wrote:\n> This patch series provides a rudimentary, working implementation of \"jgit \n> diff\".  It does not provide all modes of \"git diff\" -- by far! -- but it \n> is robust, and should provide a good starting point for further work.\n\nI have rebased this patch series on our new JGit history, and then\nopened a bug at eclipse.org to get it through the IP review process:\n\n  https://bugs.eclipse.org/bugs/show_bug.cgi?id=291083\n \n-- \nShawn.\n"},{"id":"124101","messageId":"alpine.DEB.1.00.0910012346510.4985@pacific.mpi-cbg.de","threadId":"20829","inReplyTo":"20091001184721.GR14660@spearce.org","subject":"Re: [JGIT PATCH 0/5] jgit diff","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-10-01T21:47:00Z","receivedAt":"2009-10-01T21:47:00Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 1 Oct 2009, Shawn O. Pearce wrote:\n\n> Johannes Schindelin <johannes.schindelin@gmx.de> wrote:\n> > This patch series provides a rudimentary, working implementation of \"jgit \n> > diff\".  It does not provide all modes of \"git diff\" -- by far! -- but it \n> > is robust, and should provide a good starting point for further work.\n> \n> I have rebased this patch series on our new JGit history, and then\n> opened a bug at eclipse.org to get it through the IP review process:\n> \n>   https://bugs.eclipse.org/bugs/show_bug.cgi?id=291083\n\nGreat, thanks!\n\nCiao,\nDscho\n"}]}