{"thread":{"id":"12569","subject":"[jgit] index v2 pull request","startedAt":"2008-03-08T02:50:27Z","lastAt":"2008-03-12T08:19:41Z","messageCount":13,"participants":["Shawn O. Pearce","Jakub Narebski","Robin Rosenberg","Imran M Yousuf"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"71401","messageId":"20080308025027.GZ8410@spearce.org","threadId":"12569","inReplyTo":null,"subject":"[jgit] index v2 pull request","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-03-08T02:50:27Z","receivedAt":"2008-03-08T02:50:27Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"So I've started to hack on jgit again, to build out more of the lower\nlevel library.  \n\nThis particular series adds support for pack file index v2, which\nNico added to C Git several months ago and is slated to become the\ndefault pack index file format in a future release of Git, due to\nits increased error checking during delta reuse.\n\nI also cleaned up the pack file access code to be shorter and more\nconcise.  Unfortunately the overall series diffstat doesn't show it\nthat way, but I think its now easier to follow how the control flows.\n\nI've improved performance for packfile data access by adding a delta\nbase cache, like we did in C Git months ago.  This cache is really\nnecessary on modern repositories as pack-objects is tending to use\nlonger delta chains, due to the reader side now having this delta\nbase cache.  Profiling was showing jgit was spending a very large\namount of time in unpacking tree deltas.\n\nWe now actually use the following .git/config options to control\nhow the window cache limits work:\n\n  core.packedGitWindowSize\n  core.packedGitLimit\n  core.deltaBaseCacheLimit\n  core.packedGitMMAP\n\nThe configuration file parser now recognizes the \"k/m/g\" suffixes\nthat are comonly used in the first three parameters.  The last\noption is a boolean and is unique to jgit.\n\nThe window cache and delta base cache also exploit SoftReferences to\nmake the caches memory-sensitive.  This way the JVM's GC can whack\nour caches back if its running low on memory.  Its not quite the\nsame as C Git's concept of \"malloc failed, flush out some windows\nand retry\" but its reasonably close.\n\nFinally we now use a single WindowCache and delta base cache for\nthe entire JVM when running in an Eclipse workbench.  If the user\nhas multiple repositories open at once (say different projects)\nthey need to co-habitate in the JVM's virtual address space.  By\nsharing the same caches the repositories can evict each other's\nwindows when they need to make room.\n\n----\n\nThe following changes since commit 3cd4f3f9119b79750bbfc542119451a668c462e3:\n  Robin Rosenberg (1):\n        Readded qualifier to version 0.3.1\n\nare available in the git repository at:\n\n  repo.or.cz:/srv/git/egit/spearce.git master\n\nShawn O. Pearce (41):\n      Make the absolute path of a WindowedFile available to callers\n      Include the pack index file name when reporting a bad header\n      Report pack file open failures to the console\n      Refactor index reading code from PackFile to PackIndex\n      Rename PackIndex.readIndexHeader to loadVersion1\n      Read pack index files using FileInputStream and not WindowedFile\n      Don't bother checking the index file length after reading it\n      Move index:pack object count checking into PackFile class\n      Refactor PackIndex version 1 handling code into PackIndexV1\n      Fully document the PackIndex API\n      Hoist readFully and decodeUInt32 up from PackIndexV1 to PackIndex\n      Refactor PackIndex.readFully to support reading into the middle\n      Read the pack index header to perform automatic version detection\n      Add complete reading support for pack index v2\n      Stop creating \"new format\" loose objects as C Git no longer likes them\n      Refactor RepositoryConfig to be stacked many levels deep\n      Don't make unit tests depend upon compressed file lengths\n      Corrected name of the method that reloads the packed-refs data\n      Cleanup misspelling in Javadoc of Repository class\n      Extract StGitPatch from Repository to its own top-level type\n      Refactor RepositoryState into its own top-level type\n      Refactor PackFile construction to take the idxFile path from scan\n      Shuffle the length of a WindowedFile down into its provider\n      Defer opening pack files until we actually need object data\n      Use Java 5 bit twiddling APIs rather than hand-rolling bit counting\n      Support reading config file integers with k/m/g suffixes\n      Honor core.packedGitWindowSize, packedGitLimit, packedGitMMAP config\n      Enable easy access to the user's ~/.gitconfig\n      Use a single WindowCache for the entire Eclipse workspace\n      Modify the WindowedFile API to pass around a WindowCursor during reads\n      Change ByteWindow implementations to hold data by SoftReferences\n      Refactor WindowedFile/WindowCache so all windows are a uniform size\n      Simplify WindowCache and WindowedFile internal APIs to be private\n      Use a proper ReferenceQueue to avoid duplpicate window entries\n      New RepositoryConfig getInt,getBoolean helper methods with no subsection\n      Change delta packed object loaders to use a PackedObjectLoader for base\n      Implement core.deltaBaseCacheLimit to improve unpacking performance\n      Remove unnecessary bitwise AND masks in readTree\n      Precount the number of tree entries during readTree\n      Change the ObjectLoader.getType method to return int\n      Fix ArrayIndexOutOfBoundsException in WindowCache\n\n .../egit/core/op/ConnectProviderOperation.java     |    4 +-\n .../spearce/egit/core/project/GitProjectData.java  |   27 +++-\n .../src/org/spearce/egit/ui/GitHistoryPage.java    |    2 +-\n .../internal/decorators/GitResourceDecorator.java  |    2 +-\n .../tst/org/spearce/jgit/lib/ReadTreeTest.java     |    4 +-\n .../org/spearce/jgit/lib/RepositoryConfigTest.java |    9 +-\n .../tst/org/spearce/jgit/lib/T0003_Basic.java      |   90 ---------\n .../tst/org/spearce/jgit/lib/T0004_PackReader.java |   11 +-\n org.spearce.jgit/META-INF/MANIFEST.MF              |    3 +-\n .../src/org/spearce/jgit/lib/ByteArrayWindow.java  |   27 +--\n .../src/org/spearce/jgit/lib/ByteBufferWindow.java |   21 +--\n .../src/org/spearce/jgit/lib/ByteWindow.java       |   42 +++--\n .../src/org/spearce/jgit/lib/Constants.java        |   21 ++\n .../src/org/spearce/jgit/lib/CoreConfig.java       |   61 +++++-\n .../jgit/lib/DeltaOfsPackedObjectLoader.java       |    2 +-\n .../spearce/jgit/lib/DeltaPackedObjectLoader.java  |   29 ++-\n .../jgit/lib/DeltaRefPackedObjectLoader.java       |    4 +-\n .../src/org/spearce/jgit/lib/ObjectLoader.java     |    6 +-\n .../src/org/spearce/jgit/lib/ObjectWriter.java     |   40 +---\n .../src/org/spearce/jgit/lib/PackFile.java         |  155 +++++----------\n .../src/org/spearce/jgit/lib/PackIndex.java        |  165 +++++++++++++++\n .../src/org/spearce/jgit/lib/PackIndexV1.java      |   84 ++++++++\n .../src/org/spearce/jgit/lib/PackIndexV2.java      |  125 ++++++++++++\n .../org/spearce/jgit/lib/PackedObjectLoader.java   |   13 +-\n .../src/org/spearce/jgit/lib/Repository.java       |  211 +++++---------------\n .../src/org/spearce/jgit/lib/RepositoryConfig.java |  172 +++++++++++-----\n .../src/org/spearce/jgit/lib/RepositoryState.java  |  108 ++++++++++\n .../src/org/spearce/jgit/lib/Tree.java             |   40 ++--\n .../org/spearce/jgit/lib/UnpackedObjectCache.java  |  156 +++++++++++++++\n .../org/spearce/jgit/lib/UnpackedObjectLoader.java |   20 +--\n .../spearce/jgit/lib/WholePackedObjectLoader.java  |   12 +-\n .../src/org/spearce/jgit/lib/WindowCache.java      |  151 +++++++++++---\n .../src/org/spearce/jgit/lib/WindowCursor.java     |   67 ++++++\n .../src/org/spearce/jgit/lib/WindowProvider.java   |   75 -------\n .../src/org/spearce/jgit/lib/WindowedFile.java     |  207 +++++++++++--------\n .../src/org/spearce/jgit/stgit/StGitPatch.java     |   52 +++++\n 36 files changed, 1459 insertions(+), 759 deletions(-)\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/lib/PackIndex.java\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/lib/PackIndexV1.java\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/lib/PackIndexV2.java\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/lib/RepositoryState.java\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/lib/UnpackedObjectCache.java\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/lib/WindowCursor.java\n delete mode 100644 org.spearce.jgit/src/org/spearce/jgit/lib/WindowProvider.java\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/stgit/StGitPatch.java\n\n-- \nShawn.\n"},{"id":"71408","messageId":"fqtl2e$rvc$1@ger.gmane.org","threadId":"12569","inReplyTo":"20080308025027.GZ8410@spearce.org","subject":"Re: [jgit] index v2 pull request","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-03-08T09:08:36Z","receivedAt":"2008-03-08T09:08:36Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Shawn O. Pearce wrote:\n\n> Unfortunately the overall series diffstat doesn't show it\n> that way, but I think its now easier to follow how the control flows.\n\nIsn't it the place then to put --dirstat instead of --diffstat?\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n\n"},{"id":"71484","messageId":"20080309005153.GB8410@spearce.org","threadId":"12569","inReplyTo":"fqtl2e$rvc$1@ger.gmane.org","subject":"Re: [jgit] index v2 pull request","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-03-09T00:51:53Z","receivedAt":"2008-03-09T00:51:53Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> wrote:\n> Shawn O. Pearce wrote:\n> \n> > Unfortunately the overall series diffstat doesn't show it\n> > that way, but I think its now easier to follow how the control flows.\n> \n> Isn't it the place then to put --dirstat instead of --diffstat?\n\nHmm.  Well, jgit is basically all in one directory right now,\nso --dirstat wouldn't have shown a nice neat organization the\nway you think it would.\n\nI've started to create a new directory in jgit that contains\nrevision walking machinary.  So once that is complete then\nyea, --dirstat may show the two different parts nicely, but\neven then it still isn't very useful on this project.\n\n-- \nShawn.\n"},{"id":"71542","messageId":"200803100051.55367.robin.rosenberg@dewire.com","threadId":"12569","inReplyTo":"20080308025027.GZ8410@spearce.org","subject":"Re: [jgit] index v2 pull request","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2008-03-09T23:51:55Z","receivedAt":"2008-03-09T23:51:55Z","isPatch":false,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"Den Saturday 08 March 2008 03.50.27 skrev Shawn O. Pearce:\n> So I've started to hack on jgit again, to build out more of the lower\n> level library.\nWelcome back Shawn!\n\n> This particular series adds support for pack file index v2, which\n> Nico added to C Git several months ago and is slated to become the\n> default pack index file format in a future release of Git, due to\n> its increased error checking during delta reuse.\nThis i great news. I've been thinking about it, praying that you'd come\nand do the work. :)\n\n> We now actually use the following .git/config options to control\n> how the window cache limits work:\n>\n>   core.packedGitWindowSize\n>   core.packedGitLimit\n>   core.deltaBaseCacheLimit\n>   core.packedGitMMAP\n\nWill the net effect, in practice, be the same on Jgit as on C Git?\n\n>   repo.or.cz:/srv/git/egit/spearce.git master\nSomething missing in the formatting?\n\n> Shawn O. Pearce (41):\n>       Make the absolute path of a WindowedFile available to callers\n>       Include the pack index file name when reporting a bad header\n>       Report pack file open failures to the console\n>       Refactor index reading code from PackFile to PackIndex\n>       Rename PackIndex.readIndexHeader to loadVersion1\n>       Read pack index files using FileInputStream and not WindowedFile\n>       Don't bother checking the index file length after reading it\n>       Move index:pack object count checking into PackFile class\n>       Refactor PackIndex version 1 handling code into PackIndexV1\n>       Fully document the PackIndex API\n>       Hoist readFully and decodeUInt32 up from PackIndexV1 to PackIndex\n>       Refactor PackIndex.readFully to support reading into the middle\n>       Read the pack index header to perform automatic version detection\n>       Add complete reading support for pack index v2\nYum, yum. My 15 minute review so far likes it.\n>       Stop creating \"new format\" loose objects as C Git no longer likes\n> them Refactor RepositoryConfig to be stacked many levels deep\nAnd there goes the unit test for reading them...\n\n>       Don't make unit tests depend upon compressed file lengths\n>       Corrected name of the method that reloads the packed-refs data\n>       Cleanup misspelling in Javadoc of Repository class\n>       Extract StGitPatch from Repository to its own top-level type\nI'm considering dropping stacked git support. We should have much\nmore of it and I don't use it myself anymore to what support we have\ngets very little testing.\n\n>       Refactor RepositoryState into its own top-level type\n\\ No newline at end of file\n\n>       Refactor PackFile construction to take the idxFile path from scan\n>       Shuffle the length of a WindowedFile down into its provider\n>       Defer opening pack files until we actually need object data\n>       Use Java 5 bit twiddling APIs rather than hand-rolling bit counting\nI'm surprised *you* didn't know about them bitcounting algorithm java uses \nbefore. It's pretty common.\n\n>       Support reading config file integers with k/m/g suffixes\n>       Honor core.packedGitWindowSize, packedGitLimit, packedGitMMAP config\n>       Enable easy access to the user's ~/.gitconfig\n>       Use a single WindowCache for the entire Eclipse workspace\n>       Modify the WindowedFile API to pass around a WindowCursor during reads \n>       Change ByteWindow implementations to hold data by SoftReferences \n>       Refactor WindowedFile/WindowCache so all windows are a uniform size\n>       Simplify WindowCache and WindowedFile internal APIs to be private Use \na proper ReferenceQueue to avoid duplpicate window entries\n>       New  RepositoryConfig getInt,getBoolean helper methods with no \nsubsection Change delta packed object loaders to use a PackedObjectLoader for \nbase Implement core.deltaBaseCacheLimit to improve unpacking performance\n>       Remove unnecessary bitwise AND masks in readTree \nGood catch\n>       Precount the number of tree entries during readTree\nthis one too\n>       Change the ObjectLoader.getType method to return int\n>       Fix ArrayIndexOutOfBoundsException in WindowCache\n\nVery good work (as always) Shawn. I've only read the code so far. I'll do some \ntesting too before pushing. Do you have any unit tests for the v2 pack format \n(config reading too for that matter)?\n\n-- robin\n"},{"id":"71559","messageId":"7bfdc29a0803100032q6b30f16el97c021f3b051b944@mail.gmail.com","threadId":"12569","inReplyTo":"200803100051.55367.robin.rosenberg@dewire.com","subject":"Re: [jgit] index v2 pull request","fromName":"Imran M Yousuf","fromEmail":"imyousuf@gmail.com","sentAt":"2008-03-10T07:32:21Z","receivedAt":"2008-03-10T07:32:21Z","isPatch":false,"sender":{"key":"imyousuf@gmail.com","avatar":"https://gravatar.com/avatar/fda3c870262849d03c7b9c4d288842e128d6d80769fa7bc2d22731b7597928be?d=mp&s=160"},"body":"I would like to volunteer to work in JGit;\ncan someone let me know where I can pick some tasks to implement?\n\nBest regards,\n\nImran\n\nOn Mon, Mar 10, 2008 at 5:51 AM, Robin Rosenberg\n<robin.rosenberg@dewire.com> wrote:\n> Den Saturday 08 March 2008 03.50.27 skrev Shawn O. Pearce:\n>\n> > So I've started to hack on jgit again, to build out more of the lower\n>  > level library.\n>  Welcome back Shawn!\n>\n>\n>  > This particular series adds support for pack file index v2, which\n>  > Nico added to C Git several months ago and is slated to become the\n>  > default pack index file format in a future release of Git, due to\n>  > its increased error checking during delta reuse.\n>  This i great news. I've been thinking about it, praying that you'd come\n>  and do the work. :)\n>\n>\n>  > We now actually use the following .git/config options to control\n>  > how the window cache limits work:\n>  >\n>  >   core.packedGitWindowSize\n>  >   core.packedGitLimit\n>  >   core.deltaBaseCacheLimit\n>  >   core.packedGitMMAP\n>\n>  Will the net effect, in practice, be the same on Jgit as on C Git?\n>\n>\n>  >   repo.or.cz:/srv/git/egit/spearce.git master\n>  Something missing in the formatting?\n>\n>\n>  > Shawn O. Pearce (41):\n>  >       Make the absolute path of a WindowedFile available to callers\n>  >       Include the pack index file name when reporting a bad header\n>  >       Report pack file open failures to the console\n>  >       Refactor index reading code from PackFile to PackIndex\n>  >       Rename PackIndex.readIndexHeader to loadVersion1\n>  >       Read pack index files using FileInputStream and not WindowedFile\n>  >       Don't bother checking the index file length after reading it\n>  >       Move index:pack object count checking into PackFile class\n>  >       Refactor PackIndex version 1 handling code into PackIndexV1\n>  >       Fully document the PackIndex API\n>  >       Hoist readFully and decodeUInt32 up from PackIndexV1 to PackIndex\n>  >       Refactor PackIndex.readFully to support reading into the middle\n>  >       Read the pack index header to perform automatic version detection\n>  >       Add complete reading support for pack index v2\n>  Yum, yum. My 15 minute review so far likes it.\n>\n> >       Stop creating \"new format\" loose objects as C Git no longer likes\n>  > them Refactor RepositoryConfig to be stacked many levels deep\n>  And there goes the unit test for reading them...\n>\n>\n>  >       Don't make unit tests depend upon compressed file lengths\n>  >       Corrected name of the method that reloads the packed-refs data\n>  >       Cleanup misspelling in Javadoc of Repository class\n>  >       Extract StGitPatch from Repository to its own top-level type\n>  I'm considering dropping stacked git support. We should have much\n>  more of it and I don't use it myself anymore to what support we have\n>  gets very little testing.\n>\n>\n>  >       Refactor RepositoryState into its own top-level type\n>  \\ No newline at end of file\n>\n>\n>  >       Refactor PackFile construction to take the idxFile path from scan\n>  >       Shuffle the length of a WindowedFile down into its provider\n>  >       Defer opening pack files until we actually need object data\n>  >       Use Java 5 bit twiddling APIs rather than hand-rolling bit counting\n>  I'm surprised *you* didn't know about them bitcounting algorithm java uses\n>  before. It's pretty common.\n>\n>\n>  >       Support reading config file integers with k/m/g suffixes\n>  >       Honor core.packedGitWindowSize, packedGitLimit, packedGitMMAP config\n>  >       Enable easy access to the user's ~/.gitconfig\n>  >       Use a single WindowCache for the entire Eclipse workspace\n>  >       Modify the WindowedFile API to pass around a WindowCursor during reads\n>  >       Change ByteWindow implementations to hold data by SoftReferences\n>  >       Refactor WindowedFile/WindowCache so all windows are a uniform size\n>  >       Simplify WindowCache and WindowedFile internal APIs to be private Use\n>  a proper ReferenceQueue to avoid duplpicate window entries\n>  >       New  RepositoryConfig getInt,getBoolean helper methods with no\n>  subsection Change delta packed object loaders to use a PackedObjectLoader for\n>  base Implement core.deltaBaseCacheLimit to improve unpacking performance\n>  >       Remove unnecessary bitwise AND masks in readTree\n>  Good catch\n>\n> >       Precount the number of tree entries during readTree\n>  this one too\n>\n> >       Change the ObjectLoader.getType method to return int\n>  >       Fix ArrayIndexOutOfBoundsException in WindowCache\n>\n>  Very good work (as always) Shawn. I've only read the code so far. I'll do some\n>  testing too before pushing. Do you have any unit tests for the v2 pack format\n>  (config reading too for that matter)?\n>\n>  -- robin\n>\n>\n> --\n>  To unsubscribe from this list: send the line \"unsubscribe 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-- \nImran M Yousuf\nEntrepreneur & Software Engineer\nSmart IT Engineering\nDhaka, Bangladesh\nEmail: imran@smartitengineering.com\nMobile: +880-1711402557\n"},{"id":"71711","messageId":"200803102253.28469.robin.rosenberg@dewire.com","threadId":"12569","inReplyTo":"7bfdc29a0803100032q6b30f16el97c021f3b051b944@mail.gmail.com","subject":"Re: [jgit] index v2 pull request","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2008-03-10T21:53:27Z","receivedAt":"2008-03-10T21:53:27Z","isPatch":false,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"Den Monday 10 March 2008 08.32.21 skrev Imran M Yousuf:\n> I would like to volunteer to work in JGit;\n> can someone let me know where I can pick some tasks to implement?\n>\n\nYou can pick about anything you want that noone is working one. Pick something\nthat you feel is withing your grasp, or something simple outside. We need\nmore test cases (doesn't require much programming skills, but thinking). Unit\ntesting of Eclipse stuff falls into the same category. I have litte experience \nhere, but I think there are lots of examples in Eclipse itself if one starts \nto poke around.\n\nDiff against workspace/index doesn't work presently. The reworked \nindexdiffwalker or the iterator could be used for that. Please tell me if you \nstart hacking on this as it's on my listl, just not yet. Should be reasonably \nhard, involves both jgit and eclipse programming.\n\nThere are some issues with selecting versions in the history view on Windows.\n\nCopy diff as git patch to the clipboard and vice verse. Send email.\n\nHarder and might involve more changes all over (that either I or Shawn will \nobject to) is things like rename detection targeted fo r\n\nInterface to quickdiff machinery for committing specific hunks.\n\nBlame (even without rename detection) would be useful. Look at the CVS\nannotate for inspiration. \n\nSupport for git submodules. Will touch the core parts all over the place, but \nprobably not in very intrusive way. Will require lots of test cases.\n\nNot really git, but highlighting of trailing whitespace is on my wish list. I \ncan't find a plugin that does that.\n\nAdjust the commit dialog for amend so it shows all to-be commited changed \nfiles when amending.\n\nThe number of choices is infinite.\n\nAnt, Cruisecontrol, Maven, etc-tasks.\n\nPick a pet.\n\n-- robin\n"},{"id":"71625","messageId":"20080310233138.GG8410@spearce.org","threadId":"12569","inReplyTo":"200803100051.55367.robin.rosenberg@dewire.com","subject":"Re: [jgit] index v2 pull request","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-03-10T23:31:38Z","receivedAt":"2008-03-10T23:31:38Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Robin Rosenberg <robin.rosenberg@dewire.com> wrote:\n> Den Saturday 08 March 2008 03.50.27 skrev Shawn O. Pearce:\n> \n> > We now actually use the following .git/config options to control\n> > how the window cache limits work:\n> >\n> >   core.packedGitWindowSize\n> >   core.packedGitLimit\n> >   core.deltaBaseCacheLimit\n> >   core.packedGitMMAP\n> \n> Will the net effect, in practice, be the same on Jgit as on C Git?\n\nYes.  The options actually translate precisely into jgit and are\nthe exact same knobs as they are in C Git.  That shouldn't be a\nsurprise as the damn knobs were written in both places by the\nsame person (me).\n\nUnder an Eclipse workspace we read these options _only_ from the\nuser's ~/.gitconfig.  The values in the repository config file are\nnot honored as there is only one window cache and one delta base\ncase for the entire Eclipse workspace.  Given that all projects\nin the workspace must share the same virtual address space this is\nthe only sane configuration.\n\n> >   repo.or.cz:/srv/git/egit/spearce.git master\n> Something missing in the formatting?\n\nHeh.  That's the SSH URL.  I ran git-request-pull against my\nremote rather than the public git:// URL for the repository.\nSorry about that.\n\n> >       Stop creating \"new format\" loose objects as C Git no longer likes them\n>\n> And there goes the unit test for reading them...\n\nUhm, yeaaah.  I forgot about that.  Actually that's why the object\nsize changed in that test that I deleted the assert from.  It was\nno longer a new-style loose object and thus had to use a few extra\nbytes for the type code.  *sigh*\n\nI am pretty sure that C Git also has the same need-egg-no-chicken\nproblem we now have in jgit.  It has code to read a new style\nloose object but has no code to actually create those anymore.\nSo it cannot actually do a test for the new style reader either.\n \n> >       Don't make unit tests depend upon compressed file lengths\n\nYea, its this commit I was just talking about above.  Needing to\ndelete this length assert was because of the new format breakage\nabove.\n\n> >       Extract StGitPatch from Repository to its own top-level type\n>\n> I'm considering dropping stacked git support. We should have much\n> more of it and I don't use it myself anymore to what support we have\n> gets very little testing.\n\nI've never used it.  I played around with it in my early git days,\nthen got into the porcelain and plumbing business with pg, git-gui,\njgit, egit... ;-)\n \n> >       Refactor RepositoryState into its own top-level type\n> \\ No newline at end of file\n\nArrrrrrrgh.  Damnit Eclipse!  Do what I want, not what you want!\nI'll fix it with a follow-up commit.  Unless you really want me\nto rewrite that branch.  I'm suspecting not as you are talking\nabout pushing it below.\n\n> >       Use Java 5 bit twiddling APIs rather than hand-rolling bit counting\n>\n> I'm surprised *you* didn't know about them bitcounting algorithm java uses \n> before. It's pretty common.\n\nHeh.  Yea, I was surprised too.  Its fixed now.  ;-)\n \n> >       Remove unnecessary bitwise AND masks in readTree \n> Good catch\n> >       Precount the number of tree entries during readTree\n> this one too\n\nThese were micro-optimizations while I was trying to figure out\nwhy the hell the History view cost so much.  We spend about 95%\nof our time in readTree.  With the above changes we _still_ spend\nabout 95% of our time in readTree.\n\nI'm rewriting things so we don't do that.  We'll see how well\nthat works for me.\n\n> >       Change the ObjectLoader.getType method to return int\n> >       Fix ArrayIndexOutOfBoundsException in WindowCache\n> \n> Very good work (as always) Shawn. I've only read the code so far. I'll do some \n> testing too before pushing. Do you have any unit tests for the v2 pack format \n> (config reading too for that matter)?\n\nNope, I didn't write any yet.  :-)\n\nA good v2 pack index test probably requires having a v2 pack\nindex writer.  We don't have that yet.  Plus its a \"which is\ncorrect?\" game.\n\nI did manually test the pack index v2 reader by pulling history from\na tree that I know for a fact was fully repacked (nothing loose)\nand fully repacked with index v2 (I double checked the header\nwith dd|od).\n\nWhat I did fail to test was the 64 bit offset table.  Its a pita as\nnobody has a packfile that large.  Nico left some back door debugging\noptions in index-pack to generate an index with a mixture of offset\ntypes but I forgot to manually rebuild my .idx file with it.\n\n-- \nShawn.\n"},{"id":"71634","messageId":"20080311003526.GM8410@spearce.org","threadId":"12569","inReplyTo":"7bfdc29a0803100032q6b30f16el97c021f3b051b944@mail.gmail.com","subject":"Re: [jgit] index v2 pull request","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-03-11T00:35:26Z","receivedAt":"2008-03-11T00:35:26Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Imran M Yousuf <imyousuf@gmail.com> wrote:\n> I would like to volunteer to work in JGit;\n> can someone let me know where I can pick some tasks to implement?\n\nOne of the areas that I think is really weak in JGit and that we\nneed to do a _good_ fetch/push implementation is the branch model.\n\nFor example, if you look at Repository.getBranches() it returns\nto the caller a Collection<String>.\n\nBut in Git a branch is a heck of a lot more data, and that data is\nrelevant to the end user when we are talking about fetch and merge.\nThere are many configuration options stored in .git/config for a\nbranch, and these are (today) created by git-branch and git-checkout\nautomatically as the user creates and deletes branches.\n\nJGit has none of this model.  It thinks all that a branch is is a\nString.  Sad.\n\nAnother thing that bothers me is the packed refs cache.  We toss\naway the peeled information (the \"^\" lines), but that data is very\nuseful when you are talking about fetch as well as a few other\ntypes of operations, like plotting tag labels onto a history graph\n(such as how gitk does it).\n\nThe Ref class was started as a means of wrapping up the various\nimportant bits of data about a ref (of which branches are a subclass\nand annotated tags with peeled data is another) but I suspect it\ndidn't quite do everything so these string APIs got created.\n\nThe above is a farily small task, one that any good OO programmer\nshould be able to tackle, but it can be challenging if you are\nnew to Git plumbing as you'll have to learn what are the important\nparts of a branch/ref/annotated tag.\n\nAs a starting point look at the config file format in C Git and\nsee what is possible in a \"branch\" and \"remote\" section; that\ndata needs to be pretty readily available for any Ref, if such\ndata exists.  The backward mapping of Ref->Remote (which does\nnot exist yet, unless Robin created it) is quite relevant for\ntracking branches.\n\n-- \nShawn.\n"},{"id":"71641","messageId":"7bfdc29a0803101924r41a6e221w3d560114fd61a90a@mail.gmail.com","threadId":"12569","inReplyTo":"20080311003526.GM8410@spearce.org","subject":"Re: [jgit] index v2 pull request","fromName":"Imran M Yousuf","fromEmail":"imyousuf@gmail.com","sentAt":"2008-03-11T02:24:24Z","receivedAt":"2008-03-11T02:24:24Z","isPatch":false,"sender":{"key":"imyousuf@gmail.com","avatar":"https://gravatar.com/avatar/fda3c870262849d03c7b9c4d288842e128d6d80769fa7bc2d22731b7597928be?d=mp&s=160"},"body":"On Tue, Mar 11, 2008 at 6:35 AM, Shawn O. Pearce <spearce@spearce.org> wrote:\n> Imran M Yousuf <imyousuf@gmail.com> wrote:\n>  > I would like to volunteer to work in JGit;\n>  > can someone let me know where I can pick some tasks to implement?\n>\n>  One of the areas that I think is really weak in JGit and that we\n>  need to do a _good_ fetch/push implementation is the branch model.\n>\n>  For example, if you look at Repository.getBranches() it returns\n>  to the caller a Collection<String>.\n>\n>  But in Git a branch is a heck of a lot more data, and that data is\n>  relevant to the end user when we are talking about fetch and merge.\n>  There are many configuration options stored in .git/config for a\n>  branch, and these are (today) created by git-branch and git-checkout\n>  automatically as the user creates and deletes branches.\n>\n>  JGit has none of this model.  It thinks all that a branch is is a\n>  String.  Sad.\n>\n>  Another thing that bothers me is the packed refs cache.  We toss\n>  away the peeled information (the \"^\" lines), but that data is very\n>  useful when you are talking about fetch as well as a few other\n>  types of operations, like plotting tag labels onto a history graph\n>  (such as how gitk does it).\n>\n>  The Ref class was started as a means of wrapping up the various\n>  important bits of data about a ref (of which branches are a subclass\n>  and annotated tags with peeled data is another) but I suspect it\n>  didn't quite do everything so these string APIs got created.\n>\n>  The above is a farily small task, one that any good OO programmer\n>  should be able to tackle, but it can be challenging if you are\n>  new to Git plumbing as you'll have to learn what are the important\n>  parts of a branch/ref/annotated tag.\n>\n>  As a starting point look at the config file format in C Git and\n>  see what is possible in a \"branch\" and \"remote\" section; that\n>  data needs to be pretty readily available for any Ref, if such\n>  data exists.  The backward mapping of Ref->Remote (which does\n>  not exist yet, unless Robin created it) is quite relevant for\n>  tracking branches.\n\nI will have a look at them and will give you and update; if I have any\nquestions, I hope you and team wont mind :).\n\n>\n>  --\n>  Shawn.\n>\n\n\n\n-- \nImran M Yousuf\nEntrepreneur & Software Engineer\nSmart IT Engineering\nDhaka, Bangladesh\nEmail: imran@smartitengineering.com\nMobile: +880-1711402557\n"},{"id":"71772","messageId":"7bfdc29a0803111952h3cd37b78jd884cec94afe1bc4@mail.gmail.com","threadId":"12569","inReplyTo":"200803102253.28469.robin.rosenberg@dewire.com","subject":"Re: [jgit] index v2 pull request","fromName":"Imran M Yousuf","fromEmail":"imyousuf@gmail.com","sentAt":"2008-03-12T02:52:05Z","receivedAt":"2008-03-12T02:52:05Z","isPatch":false,"sender":{"key":"imyousuf@gmail.com","avatar":"https://gravatar.com/avatar/fda3c870262849d03c7b9c4d288842e128d6d80769fa7bc2d22731b7597928be?d=mp&s=160"},"body":"On Tue, Mar 11, 2008 at 3:53 AM, Robin Rosenberg\n<robin.rosenberg@dewire.com> wrote:\n> Den Monday 10 March 2008 08.32.21 skrev Imran M Yousuf:\n>\n> > I would like to volunteer to work in JGit;\n>  > can someone let me know where I can pick some tasks to implement?\n>  >\n>\n>  You can pick about anything you want that noone is working one. Pick something\n>  that you feel is withing your grasp, or something simple outside. We need\n>  more test cases (doesn't require much programming skills, but thinking). Unit\n>  testing of Eclipse stuff falls into the same category. I have litte experience\n>  here, but I think there are lots of examples in Eclipse itself if one starts\n>  to poke around.\n>\n>  Diff against workspace/index doesn't work presently. The reworked\n>  indexdiffwalker or the iterator could be used for that. Please tell me if you\n>  start hacking on this as it's on my listl, just not yet. Should be reasonably\n>  hard, involves both jgit and eclipse programming.\n>\n>  There are some issues with selecting versions in the history view on Windows.\n>\n>  Copy diff as git patch to the clipboard and vice verse. Send email.\n>\n>  Harder and might involve more changes all over (that either I or Shawn will\n>  object to) is things like rename detection targeted fo r\n>\n>  Interface to quickdiff machinery for committing specific hunks.\n>\n>  Blame (even without rename detection) would be useful. Look at the CVS\n>  annotate for inspiration.\n>\n>  Support for git submodules. Will touch the core parts all over the place, but\n>  probably not in very intrusive way. Will require lots of test cases.\n>\n>  Not really git, but highlighting of trailing whitespace is on my wish list. I\n>  can't find a plugin that does that.\n>\n>  Adjust the commit dialog for amend so it shows all to-be commited changed\n>  files when amending.\n>\n>  The number of choices is infinite.\n>\n>  Ant, Cruisecontrol, Maven, etc-tasks.\n\nMaven: Does this mean mavenizing the project? If so I would start it\nthis weekend. If you were referring to GIT Maven SCM please also let\nme know.\nCruisecontrol: I would instead like to setup Hudson; I find it to be\nquite user friendly and flexible at the same time. I would also like\nto set up it for JGit. Once we JGit has more features like DIff remote\nfetching and stuff we can also build a hudson plugin :).\n\nI am currently looking into .git/config format as Shawn suggested.\n\n- Imran\n\n>\n>  Pick a pet.\n>\n>  -- robin\n>\n>\n\n\n\n-- \nImran M Yousuf\nEntrepreneur & Software Engineer\nSmart IT Engineering\nDhaka, Bangladesh\nEmail: imran@smartitengineering.com\nMobile: +880-1711402557\n"},{"id":"71788","messageId":"200803120807.01715.robin.rosenberg@dewire.com","threadId":"12569","inReplyTo":"7bfdc29a0803111952h3cd37b78jd884cec94afe1bc4@mail.gmail.com","subject":"Re: [jgit] index v2 pull request","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2008-03-12T07:07:01Z","receivedAt":"2008-03-12T07:07:01Z","isPatch":false,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"Den Wednesday 12 March 2008 03.52.05 skrev Imran M Yousuf:\n> Maven: Does this mean mavenizing the project? If so I would start it\n> this weekend. If you were referring to GIT Maven SCM please also let\n> me know.\nNot to build using, but create SCM functions for those so thay can use\ngit without <exec> tasks. Git isn't available in any of those, while much\nworse SCM's have support.\n\n> I am currently looking into .git/config format as Shawn suggested.\n\nThat's a good one too. I have code for parsing the remotes specs, though\ne.g. \"+refs/heads/master/*:refs/remotes/origin/*\", but nothing for the \"branch\" config. I haven't used it yet, so it's a rip-out.\t\n\n-- robin\n\n>From 042fa0bef8b5d3ec8f5b1e385766ca61528e72aa Mon Sep 17 00:00:00 2001\nFrom: Robin Rosenberg <robin.rosenberg@dewire.com>\nDate: Wed, 5 Mar 2008 23:27:57 +0100\nSubject: [PATCH] Add support for parsing remote specs\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n---\n .../tst/org/spearce/jgit/lib/RemoteSpecTest.java   |   95 +++++++++++++\n .../src/org/spearce/jgit/lib/RemoteSpec.java       |  142 ++++++++++++++++++++\n .../src/org/spearce/jgit/lib/Repository.java       |   12 ++\n 3 files changed, 249 insertions(+), 0 deletions(-)\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/lib/RemoteSpecTest.java\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/lib/RemoteSpec.java\n\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RemoteSpecTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RemoteSpecTest.java\nnew file mode 100644\nindex 0000000..817e697\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RemoteSpecTest.java\n@@ -0,0 +1,95 @@\n+/*\n+ *  Copyright (C) 2007  Robin Rosenberg\n+ *\n+ *  This library is free software; you can redistribute it and/or\n+ *  modify it under the terms of the GNU General Public\n+ *  License, version 2, as published by the Free Software Foundation.\n+ *\n+ *  This library is distributed in the hope that it will be useful,\n+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+ *  General Public License for more details.\n+ *\n+ *  You should have received a copy of the GNU General Public\n+ *  License along with this library; if not, write to the Free Software\n+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301\n+ */\n+package org.spearce.jgit.lib;\n+\n+import java.io.File;\n+import java.io.FileOutputStream;\n+\n+/**\n+ * Test parsing of git remotes\n+ */\n+public class RemoteSpecTest extends RepositoryTestCase {\n+\n+\t/**\n+\t * Test simplest case\n+\t *\n+\t * @throws Exception\n+\t *\n+\t */\n+\tpublic void testSimplestOk() throws Exception {\n+\t\tRemoteSpec spec = new RemoteSpec(\"their\", \"git://foo.bar/zip.git\",\n+\t\t\t\t\"refs/heads/master:refs/heads/origin\",null);\n+\t\tassertEquals(\"refs/heads/master\", spec.getFetchRemoteRef());\n+\t\tassertEquals(\"refs/heads/origin\", spec.getFetchLocalRef());\n+\t\tassertFalse(spec.isFetchMatchAny());\n+\t\tassertFalse(spec.isFetchOverwriteAlways());\n+\t}\n+\n+\t/**\n+\t * Test a standard case\n+\t *\n+\t * @throws Exception\n+\t */\n+\tpublic void testStandardOk() throws Exception {\n+\t\tRemoteSpec spec = new RemoteSpec(\"their\", \"git://example.com/zip.git\",\n+\t\t\t\t\"+refs/heads/master/*:refs/remotes/origin/*\",null);\n+\t\tassertEquals(\"git://example.com/zip.git\", spec.getUrl());\n+\t\tassertEquals(\"refs/heads/master\", spec.getFetchRemoteRef());\n+\t\tassertEquals(\"refs/remotes/origin\", spec.getFetchLocalRef());\n+\t\tassertTrue(spec.isFetchMatchAny());\n+\t\tassertTrue(spec.isFetchOverwriteAlways());\n+\t}\n+\n+\t/**\n+\t * Test a <quote>safer</quote> almost standard case\n+\t *\n+\t * @throws Exception\n+\t */\n+\tpublic void testNonStandardSaferOk() throws Exception {\n+\t\tRemoteSpec spec = new RemoteSpec(\"their\", \"git://example.com/zip.git\",\n+\t\t\t\t\"refs/heads/master/*:refs/remotes/origin/*\",null);\n+\t\tassertEquals(\"git://example.com/zip.git\", spec.getUrl());\n+\t\tassertEquals(\"refs/heads/master\", spec.getFetchRemoteRef());\n+\t\tassertEquals(\"refs/remotes/origin\", spec.getFetchLocalRef());\n+\t\tassertTrue(spec.isFetchMatchAny());\n+\t\tassertFalse(spec.isFetchOverwriteAlways());\n+\t}\n+\n+\t/**\n+\t * Test a case copied from a real Git repo\n+\t *\n+\t * @throws Exception\n+\t */\n+\tpublic void testReadFromConfig() throws Exception {\n+\t\tFile file = new File(db.getDirectory(),\"config\");\n+\t\tFileOutputStream stream = new FileOutputStream(file,true);\n+\t\ttry {\n+\t\t\tstream.write((\"[remote \\\"spearce\\\"]\\n\"+\n+\t\t\"url = http://www.spearce.org/projects/scm/egit.git\\n\"+\n+\t\t\"fetch = +refs/heads/*:refs/remotes/spearce/*\\n\").getBytes());\n+\t\t} finally {\n+\t\t\tstream.close();\n+\t\t}\n+\t\tdb.getConfig().load();\n+\t\tRemoteSpec remoteSpec = db.getRemoteSpec(\"spearce\");\n+\t\tassertEquals(\"http://www.spearce.org/projects/scm/egit.git\", remoteSpec.getUrl());\n+\t\tassertEquals(\"refs/heads\", remoteSpec.getFetchRemoteRef());\n+\t\tassertEquals(\"refs/remotes/spearce\", remoteSpec.getFetchLocalRef());\n+\t\tassertTrue(remoteSpec.isFetchMatchAny());\n+\t\tassertTrue(remoteSpec.isFetchOverwriteAlways());\n+\t}\n+}\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RemoteSpec.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RemoteSpec.java\nnew file mode 100644\nindex 0000000..a6a3b6c\n--- /dev/null\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RemoteSpec.java\n@@ -0,0 +1,142 @@\n+/*\n+ *  Copyright (C) 2007  Robin Rosenberg\n+ *\n+ *  This library is free software; you can redistribute it and/or\n+ *  modify it under the terms of the GNU General Public\n+ *  License, version 2, as published by the Free Software Foundation.\n+ *\n+ *  This library is distributed in the hope that it will be useful,\n+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+ *  General Public License for more details.\n+ *\n+ *  You should have received a copy of the GNU General Public\n+ *  License along with this library; if not, write to the Free Software\n+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301\n+ */\n+package org.spearce.jgit.lib;\n+\n+/**\n+ * Information about how to synchronize with a remote Git repository.\n+ *\n+ * A remote is stored in the <GIT_DIR>/config as\n+ *\n+ * <pre>\n+ *  [remote &quot;name&quot;]\n+ *     url = URL:ish\n+ *     fetch = [+]remoteref:localref\n+ * </pre>\n+ *\n+ * There are more variants but we do not support them here yet.\n+ */\n+public class RemoteSpec {\n+\n+\tstatic class Info {\n+\t\tboolean overwriteAlways;\n+\n+\t\tboolean matchAny;\n+\n+\t\tString remoteRef;\n+\n+\t\tString localRef;\n+\t}\n+\n+\tInfo fetch = new Info();\n+\n+\tInfo push = null;\n+\n+\tprivate final String name;\n+\n+\tprivate final String url;\n+\n+\t/**\n+\t * @return name of remote. This is a local short identifier\n+\t */\n+\tpublic String getName() {\n+\t\treturn name;\n+\t}\n+\n+\t/**\n+\t * @return the URL:ish location of the remote Git repository\n+\t */\n+\tpublic String getUrl() {\n+\t\treturn url;\n+\t}\n+\n+\t/**\n+\t * @return the local ref part used for fetch heads info\n+\t */\n+\tpublic String getFetchLocalRef() {\n+\t\treturn fetch.localRef;\n+\t}\n+\n+\t/**\n+\t * @return the remote ref part used for fetching refs from the remote repo\n+\t */\n+\tpublic String getFetchRemoteRef() {\n+\t\treturn fetch.remoteRef;\n+\t}\n+\n+\t/**\n+\t * @return whether the fetch matches all branches under the ref or just the\n+\t *         named ref\n+\t */\n+\tpublic boolean isFetchMatchAny() {\n+\t\treturn fetch.matchAny;\n+\t}\n+\n+\t/**\n+\t * @return whether the tracking branch is always updated, or only when the\n+\t *         update is a fast forward\n+\t */\n+\tpublic boolean isFetchOverwriteAlways() {\n+\t\treturn fetch.overwriteAlways;\n+\t}\n+\n+\t/**\n+\t * Create a representation of a git remote specification.\n+\t *\n+\t * @param name A local short identifier\n+\t * @param url The URL:ish used for fetching / pushing\n+\t * @param fetchPattern refspec for fetching\n+\t * @param pushPattern refspec for pushing or null\n+\t */\n+\tpublic RemoteSpec(String name, String url, String fetchPattern,\n+\t\t\tString pushPattern) {\n+\t\tthis.name = name;\n+\t\tthis.url = url;\n+\t\tparse(fetchPattern, fetch);\n+\t\tif (pushPattern != null) {\n+\t\t\tpush = new Info();\n+\t\t\tparse(pushPattern, push);\n+\t\t}\n+\t}\n+\n+\tprivate void parse(String fetchSpec, Info info) {\n+\t\tint p = 0;\n+\t\tif (fetchSpec.charAt(p) == '+') {\n+\t\t\tinfo.overwriteAlways = true;\n+\t\t\t++p;\n+\t\t}\n+\t\tint cp = fetchSpec.indexOf(':');\n+\t\tif (cp < 0)\n+\t\t\tthrow new IllegalArgumentException(\"Bad remote format \" + fetchSpec);\n+\t\tinfo.remoteRef = fetchSpec.substring(p, cp);\n+\t\tinfo.localRef = fetchSpec.substring(cp + 1);\n+\t\tif (info.remoteRef.endsWith(\"/*\")) {\n+\t\t\tinfo.matchAny = true;\n+\t\t\tinfo.remoteRef = info.remoteRef.substring(0, info.remoteRef\n+\t\t\t\t\t.length() - 2);\n+\t\t}\n+\t\tif (info.localRef.endsWith(\"/*\")) {\n+\t\t\tif (!info.matchAny)\n+\t\t\t\tthrow new IllegalArgumentException(\"Bad remote format \"\n+\t\t\t\t\t\t+ fetchSpec);\n+\t\t\tinfo.localRef = info.localRef.substring(0,\n+\t\t\t\t\tinfo.localRef.length() - 2);\n+\t\t} else\n+\t\t\tif (info.matchAny)\n+\t\t\t\tthrow new IllegalArgumentException(\"Bad remote format \" + fetchSpec);\n+\n+\t}\n+}\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\nindex b3fa12e..821633d 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n@@ -1132,4 +1132,16 @@ public class Repository {\n \t\trelName = relName.replace(File.separatorChar, '/');\n \t\treturn relName;\n \t}\n+\n+\t/**\n+\t * @param name\n+\t *            The \"remote\" name in this repo\n+\t * @return information about how a remote repository is beging tracked\n+\t */\n+\tpublic RemoteSpec getRemoteSpec(String name) {\n+\t\tString url = getConfig().getString(\"remote.\"+name, null, \"url\");\n+\t\tString fetchPattern = getConfig().getString(\"remote.\"+name, null, \"fetch\");\n+\t\tString pushPattern = getConfig().getString(\"remote.\"+name, null, \"push\");\n+\t\treturn new RemoteSpec(name, url, fetchPattern, pushPattern);\n+\t}\n }\n-- \n1.5.4.3\n"},{"id":"71793","messageId":"20080312075205.GT8410@spearce.org","threadId":"12569","inReplyTo":"200803120807.01715.robin.rosenberg@dewire.com","subject":"Re: [jgit] index v2 pull request","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-03-12T07:52:05Z","receivedAt":"2008-03-12T07:52:05Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Robin Rosenberg <robin.rosenberg@dewire.com> wrote:\n> Den Wednesday 12 March 2008 03.52.05 skrev Imran M Yousuf:\n> \n> > I am currently looking into .git/config format as Shawn suggested.\n> \n> That's a good one too. I have code for parsing the remotes specs, though\n> e.g. \"+refs/heads/master/*:refs/remotes/origin/*\", but nothing for the \"branch\" config. I haven't used it yet, so it's a rip-out.\t\n\nYour RemoteSpec is missing the fact that some people have more than\none URL, fetch, and/or push lines in the same remote.  :-)\n \n> + * <pre>\n> + *  [remote &quot;name&quot;]\n> + *     url = URL:ish\n> + *     fetch = [+]remoteref:localref\n> + * </pre>\n> + *\n> + * There are more variants but we do not support them here yet.\n\nOr is that what you mean by the above statement?\n\nIn any case the remote spec needs a list of URLs a list of the\nfetch/push Info objects.  That changes the public API of the\nRemoteSpec class rather significantly.\n\n> +public class RemoteSpec {\n> +\n> +\tstatic class Info {\n> +\t\tboolean overwriteAlways;\n> +\n> +\t\tboolean matchAny;\n> +\n> +\t\tString remoteRef;\n> +\n> +\t\tString localRef;\n> +\t}\n> +\n> +\tInfo fetch = new Info();\n> +\n> +\tInfo push = null;\n> +\n> +\tprivate final String name;\n> +\n> +\tprivate final String url;\n\n-- \nShawn.\n"},{"id":"71794","messageId":"7bfdc29a0803120119sdf55c23h3ca50105d027ffca@mail.gmail.com","threadId":"12569","inReplyTo":"200803120807.01715.robin.rosenberg@dewire.com","subject":"Re: [jgit] index v2 pull request","fromName":"Imran M Yousuf","fromEmail":"imyousuf@gmail.com","sentAt":"2008-03-12T08:19:41Z","receivedAt":"2008-03-12T08:19:41Z","isPatch":false,"sender":{"key":"imyousuf@gmail.com","avatar":"https://gravatar.com/avatar/fda3c870262849d03c7b9c4d288842e128d6d80769fa7bc2d22731b7597928be?d=mp&s=160"},"body":"On Wed, Mar 12, 2008 at 1:07 PM, Robin Rosenberg\n<robin.rosenberg@dewire.com> wrote:\n> Den Wednesday 12 March 2008 03.52.05 skrev Imran M Yousuf:\n>\n> > Maven: Does this mean mavenizing the project? If so I would start it\n>  > this weekend. If you were referring to GIT Maven SCM please also let\n>  > me know.\n>  Not to build using, but create SCM functions for those so thay can use\n>  git without <exec> tasks. Git isn't available in any of those, while much\n>  worse SCM's have support.\n>\n\nI know a team who are currently working with the GIT SCM plugin for\nMaven; I think they are using CLI for the purpose. I am more\ninterested in GIT VCS Module for NB6; as I have some other projects\nwhich will be using it :).\n\n>\n>  > I am currently looking into .git/config format as Shawn suggested.\n>\n>  That's a good one too. I have code for parsing the remotes specs, though\n>  e.g. \"+refs/heads/master/*:refs/remotes/origin/*\", but nothing for the \"branch\" config. I haven't used it yet, so it's a rip-out.\n\nI will have a look at it; currently we have a long tasklist in a\nproject; I will have a look at them as soon as I can make some time\n:).\n\n- Imran\n\n>\n>  -- robin\n>\n>  From 042fa0bef8b5d3ec8f5b1e385766ca61528e72aa Mon Sep 17 00:00:00 2001\n>  From: Robin Rosenberg <robin.rosenberg@dewire.com>\n>  Date: Wed, 5 Mar 2008 23:27:57 +0100\n>  Subject: [PATCH] Add support for parsing remote specs\n>\n>  Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n>  ---\n>   .../tst/org/spearce/jgit/lib/RemoteSpecTest.java   |   95 +++++++++++++\n>   .../src/org/spearce/jgit/lib/RemoteSpec.java       |  142 ++++++++++++++++++++\n>   .../src/org/spearce/jgit/lib/Repository.java       |   12 ++\n>   3 files changed, 249 insertions(+), 0 deletions(-)\n>   create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/lib/RemoteSpecTest.java\n>   create mode 100644 org.spearce.jgit/src/org/spearce/jgit/lib/RemoteSpec.java\n>\n>  diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RemoteSpecTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RemoteSpecTest.java\n>  new file mode 100644\n>  index 0000000..817e697\n>  --- /dev/null\n>  +++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RemoteSpecTest.java\n>  @@ -0,0 +1,95 @@\n>  +/*\n>  + *  Copyright (C) 2007  Robin Rosenberg\n>  + *\n>  + *  This library is free software; you can redistribute it and/or\n>  + *  modify it under the terms of the GNU General Public\n>  + *  License, version 2, as published by the Free Software Foundation.\n>  + *\n>  + *  This library is distributed in the hope that it will be useful,\n>  + *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n>  + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n>  + *  General Public License for more details.\n>  + *\n>  + *  You should have received a copy of the GNU General Public\n>  + *  License along with this library; if not, write to the Free Software\n>  + *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301\n>  + */\n>  +package org.spearce.jgit.lib;\n>  +\n>  +import java.io.File;\n>  +import java.io.FileOutputStream;\n>  +\n>  +/**\n>  + * Test parsing of git remotes\n>  + */\n>  +public class RemoteSpecTest extends RepositoryTestCase {\n>  +\n>  +       /**\n>  +        * Test simplest case\n>  +        *\n>  +        * @throws Exception\n>  +        *\n>  +        */\n>  +       public void testSimplestOk() throws Exception {\n>  +               RemoteSpec spec = new RemoteSpec(\"their\", \"git://foo.bar/zip.git\",\n>  +                               \"refs/heads/master:refs/heads/origin\",null);\n>  +               assertEquals(\"refs/heads/master\", spec.getFetchRemoteRef());\n>  +               assertEquals(\"refs/heads/origin\", spec.getFetchLocalRef());\n>  +               assertFalse(spec.isFetchMatchAny());\n>  +               assertFalse(spec.isFetchOverwriteAlways());\n>  +       }\n>  +\n>  +       /**\n>  +        * Test a standard case\n>  +        *\n>  +        * @throws Exception\n>  +        */\n>  +       public void testStandardOk() throws Exception {\n>  +               RemoteSpec spec = new RemoteSpec(\"their\", \"git://example.com/zip.git\",\n>  +                               \"+refs/heads/master/*:refs/remotes/origin/*\",null);\n>  +               assertEquals(\"git://example.com/zip.git\", spec.getUrl());\n>  +               assertEquals(\"refs/heads/master\", spec.getFetchRemoteRef());\n>  +               assertEquals(\"refs/remotes/origin\", spec.getFetchLocalRef());\n>  +               assertTrue(spec.isFetchMatchAny());\n>  +               assertTrue(spec.isFetchOverwriteAlways());\n>  +       }\n>  +\n>  +       /**\n>  +        * Test a <quote>safer</quote> almost standard case\n>  +        *\n>  +        * @throws Exception\n>  +        */\n>  +       public void testNonStandardSaferOk() throws Exception {\n>  +               RemoteSpec spec = new RemoteSpec(\"their\", \"git://example.com/zip.git\",\n>  +                               \"refs/heads/master/*:refs/remotes/origin/*\",null);\n>  +               assertEquals(\"git://example.com/zip.git\", spec.getUrl());\n>  +               assertEquals(\"refs/heads/master\", spec.getFetchRemoteRef());\n>  +               assertEquals(\"refs/remotes/origin\", spec.getFetchLocalRef());\n>  +               assertTrue(spec.isFetchMatchAny());\n>  +               assertFalse(spec.isFetchOverwriteAlways());\n>  +       }\n>  +\n>  +       /**\n>  +        * Test a case copied from a real Git repo\n>  +        *\n>  +        * @throws Exception\n>  +        */\n>  +       public void testReadFromConfig() throws Exception {\n>  +               File file = new File(db.getDirectory(),\"config\");\n>  +               FileOutputStream stream = new FileOutputStream(file,true);\n>  +               try {\n>  +                       stream.write((\"[remote \\\"spearce\\\"]\\n\"+\n>  +               \"url = http://www.spearce.org/projects/scm/egit.git\\n\"+\n>  +               \"fetch = +refs/heads/*:refs/remotes/spearce/*\\n\").getBytes());\n>  +               } finally {\n>  +                       stream.close();\n>  +               }\n>  +               db.getConfig().load();\n>  +               RemoteSpec remoteSpec = db.getRemoteSpec(\"spearce\");\n>  +               assertEquals(\"http://www.spearce.org/projects/scm/egit.git\", remoteSpec.getUrl());\n>  +               assertEquals(\"refs/heads\", remoteSpec.getFetchRemoteRef());\n>  +               assertEquals(\"refs/remotes/spearce\", remoteSpec.getFetchLocalRef());\n>  +               assertTrue(remoteSpec.isFetchMatchAny());\n>  +               assertTrue(remoteSpec.isFetchOverwriteAlways());\n>  +       }\n>  +}\n>  diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RemoteSpec.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RemoteSpec.java\n>  new file mode 100644\n>  index 0000000..a6a3b6c\n>  --- /dev/null\n>  +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RemoteSpec.java\n>  @@ -0,0 +1,142 @@\n>  +/*\n>  + *  Copyright (C) 2007  Robin Rosenberg\n>  + *\n>  + *  This library is free software; you can redistribute it and/or\n>  + *  modify it under the terms of the GNU General Public\n>  + *  License, version 2, as published by the Free Software Foundation.\n>  + *\n>  + *  This library is distributed in the hope that it will be useful,\n>  + *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n>  + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n>  + *  General Public License for more details.\n>  + *\n>  + *  You should have received a copy of the GNU General Public\n>  + *  License along with this library; if not, write to the Free Software\n>  + *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301\n>  + */\n>  +package org.spearce.jgit.lib;\n>  +\n>  +/**\n>  + * Information about how to synchronize with a remote Git repository.\n>  + *\n>  + * A remote is stored in the <GIT_DIR>/config as\n>  + *\n>  + * <pre>\n>  + *  [remote &quot;name&quot;]\n>  + *     url = URL:ish\n>  + *     fetch = [+]remoteref:localref\n>  + * </pre>\n>  + *\n>  + * There are more variants but we do not support them here yet.\n>  + */\n>  +public class RemoteSpec {\n>  +\n>  +       static class Info {\n>  +               boolean overwriteAlways;\n>  +\n>  +               boolean matchAny;\n>  +\n>  +               String remoteRef;\n>  +\n>  +               String localRef;\n>  +       }\n>  +\n>  +       Info fetch = new Info();\n>  +\n>  +       Info push = null;\n>  +\n>  +       private final String name;\n>  +\n>  +       private final String url;\n>  +\n>  +       /**\n>  +        * @return name of remote. This is a local short identifier\n>  +        */\n>  +       public String getName() {\n>  +               return name;\n>  +       }\n>  +\n>  +       /**\n>  +        * @return the URL:ish location of the remote Git repository\n>  +        */\n>  +       public String getUrl() {\n>  +               return url;\n>  +       }\n>  +\n>  +       /**\n>  +        * @return the local ref part used for fetch heads info\n>  +        */\n>  +       public String getFetchLocalRef() {\n>  +               return fetch.localRef;\n>  +       }\n>  +\n>  +       /**\n>  +        * @return the remote ref part used for fetching refs from the remote repo\n>  +        */\n>  +       public String getFetchRemoteRef() {\n>  +               return fetch.remoteRef;\n>  +       }\n>  +\n>  +       /**\n>  +        * @return whether the fetch matches all branches under the ref or just the\n>  +        *         named ref\n>  +        */\n>  +       public boolean isFetchMatchAny() {\n>  +               return fetch.matchAny;\n>  +       }\n>  +\n>  +       /**\n>  +        * @return whether the tracking branch is always updated, or only when the\n>  +        *         update is a fast forward\n>  +        */\n>  +       public boolean isFetchOverwriteAlways() {\n>  +               return fetch.overwriteAlways;\n>  +       }\n>  +\n>  +       /**\n>  +        * Create a representation of a git remote specification.\n>  +        *\n>  +        * @param name A local short identifier\n>  +        * @param url The URL:ish used for fetching / pushing\n>  +        * @param fetchPattern refspec for fetching\n>  +        * @param pushPattern refspec for pushing or null\n>  +        */\n>  +       public RemoteSpec(String name, String url, String fetchPattern,\n>  +                       String pushPattern) {\n>  +               this.name = name;\n>  +               this.url = url;\n>  +               parse(fetchPattern, fetch);\n>  +               if (pushPattern != null) {\n>  +                       push = new Info();\n>  +                       parse(pushPattern, push);\n>  +               }\n>  +       }\n>  +\n>  +       private void parse(String fetchSpec, Info info) {\n>  +               int p = 0;\n>  +               if (fetchSpec.charAt(p) == '+') {\n>  +                       info.overwriteAlways = true;\n>  +                       ++p;\n>  +               }\n>  +               int cp = fetchSpec.indexOf(':');\n>  +               if (cp < 0)\n>  +                       throw new IllegalArgumentException(\"Bad remote format \" + fetchSpec);\n>  +               info.remoteRef = fetchSpec.substring(p, cp);\n>  +               info.localRef = fetchSpec.substring(cp + 1);\n>  +               if (info.remoteRef.endsWith(\"/*\")) {\n>  +                       info.matchAny = true;\n>  +                       info.remoteRef = info.remoteRef.substring(0, info.remoteRef\n>  +                                       .length() - 2);\n>  +               }\n>  +               if (info.localRef.endsWith(\"/*\")) {\n>  +                       if (!info.matchAny)\n>  +                               throw new IllegalArgumentException(\"Bad remote format \"\n>  +                                               + fetchSpec);\n>  +                       info.localRef = info.localRef.substring(0,\n>  +                                       info.localRef.length() - 2);\n>  +               } else\n>  +                       if (info.matchAny)\n>  +                               throw new IllegalArgumentException(\"Bad remote format \" + fetchSpec);\n>  +\n>  +       }\n>  +}\n>  diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n>  index b3fa12e..821633d 100644\n>  --- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n>  +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n>  @@ -1132,4 +1132,16 @@ public class Repository {\n>                 relName = relName.replace(File.separatorChar, '/');\n>                 return relName;\n>         }\n>  +\n>  +       /**\n>  +        * @param name\n>  +        *            The \"remote\" name in this repo\n>  +        * @return information about how a remote repository is beging tracked\n>  +        */\n>  +       public RemoteSpec getRemoteSpec(String name) {\n>  +               String url = getConfig().getString(\"remote.\"+name, null, \"url\");\n>  +               String fetchPattern = getConfig().getString(\"remote.\"+name, null, \"fetch\");\n>  +               String pushPattern = getConfig().getString(\"remote.\"+name, null, \"push\");\n>  +               return new RemoteSpec(name, url, fetchPattern, pushPattern);\n>  +       }\n>   }\n>  --\n>  1.5.4.3\n>\n>\n\n\n\n-- \nImran M Yousuf\nEntrepreneur & Software Engineer\nSmart IT Engineering\nDhaka, Bangladesh\nEmail: imran@smartitengineering.com\nMobile: +880-1711402557\n"}]}