{"thread":{"id":"15656","subject":"[JGIT PATCH] Use \".have\" advertisements during push to reduce what is transferred","startedAt":"2008-09-24T19:05:53Z","lastAt":"2008-09-24T19:05:53Z","messageCount":1,"participants":["Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"91511","messageId":"1222283153-10534-1-git-send-email-spearce@spearce.org","threadId":"15656","inReplyTo":null,"subject":"[JGIT PATCH] Use \".have\" advertisements during push to reduce what is transferred","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-09-24T19:05:53Z","receivedAt":"2008-09-24T19:05:53Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"If a remote peer has an alternate object database it might show\nthe refs of the alternate repositories by sending special \".have\"\nref lines in the advertisement.  These can be used to compute a\nbetter common base, avoiding uploading objects which the remote\nside has physically available (and complete), but which aren't in\nthe ref space of the remote repository.\n\nAs most repositories have more than one ref, there can be more than\none \".have\" line, and the same object might appear more than once.\nCollecting these into a special \"additionalHaves\" set avoids them\nfrom showing up in the advertised refs collection.\n\nPackWriter already gracefully skips over remoteObjects that\nwe don't have locally.  We can simply include the entire set\nof additionalHaves when we start creating a pack for the push\ntransfer and PackWriter will seek the best common base available.\nAnything advertised that we lack will be silently skipped.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n\n I'm likely to merge Junio's jc/alternate-push branch in git.git\n from next to master when I start merging over the cooked topics.\n\n JGit clients need this to prevent crashing when they talk to a\n newer git-receive-pack process that is sending these .have lines.\n Without this patch JGit will throw a \"duplicate advertisement\"\n error when it receives more than one ref with the name \".have\".\n\n Fortunately the entire implementation of the client side of this\n alternate-push feature is 7 lines of Java.\n\n See http://thread.gmane.org/gmane.comp.version-control.git/95351\n\n .../spearce/jgit/transport/BasePackConnection.java |    7 ++++++-\n .../jgit/transport/BasePackPushConnection.java     |    1 +\n 2 files changed, 7 insertions(+), 1 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java\nindex 2d145a6..e5fc040 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java\n@@ -93,6 +93,9 @@\n \t/** Capability tokens advertised by the remote side. */\n \tprivate final Set<String> remoteCapablities = new HashSet<String>();\n \n+\t/** Extra objects the remote has, but which aren't offered as refs. */\n+\tprotected final Set<ObjectId> additionalHaves = new HashSet<ObjectId>();\n+\n \tBasePackConnection(final PackTransport packTransport) {\n \t\tlocal = packTransport.local;\n \t\turi = packTransport.uri;\n@@ -160,7 +163,9 @@ private void readAdvertisedRefsImpl() throws IOException {\n \t\t\t}\n \n \t\t\tfinal ObjectId id = ObjectId.fromString(line.substring(0, 40));\n-\t\t\tif (name.endsWith(\"^{}\")) {\n+\t\t\tif (name.equals(\".have\")) {\n+\t\t\t\tadditionalHaves.add(id);\n+\t\t\t} else if (name.endsWith(\"^{}\")) {\n \t\t\t\tname = name.substring(0, name.length() - 3);\n \t\t\t\tfinal Ref prior = avail.get(name);\n \t\t\t\tif (prior == null)\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackPushConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackPushConnection.java\nindex 2594623..17f6915 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackPushConnection.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackPushConnection.java\n@@ -195,6 +195,7 @@ private void writePack(final Map<String, RemoteRefUpdate> refUpdates,\n \n \t\tfor (final Ref r : getRefs())\n \t\t\tremoteObjects.add(r.getObjectId());\n+\t\tremoteObjects.addAll(additionalHaves);\n \t\tfor (final RemoteRefUpdate r : refUpdates.values()) {\n \t\t\tif (!ObjectId.zeroId().equals(r.getNewObjectId()))\n \t\t\t\tnewObjects.add(r.getNewObjectId());\n-- \n1.6.0.2.471.g47a76\n"}]}