From 749dfeffc8bed6caf39dfae196a98537bc36a326 Mon Sep 17 00:00:00 2001 From: Yuxuan 'fishy' Wang Date: Thu, 20 Nov 2014 15:50:24 -0800 Subject: [PATCH] upload-pack: send symbolic refs as capabilities cgit has this feature for some time. This will teach JGit to send symbolic refs, too. Change-Id: I7cb2ab4e6d31a838a0af92eac64535fdb66ed74a Signed-off-by: Yuxuan 'fishy' Wang --- .../jgit/transport/GitProtocolConstants.java | 7 ++++++ .../eclipse/jgit/transport/RefAdvertiser.java | 23 +++++++++++++++++++ .../eclipse/jgit/transport/UploadPack.java | 12 +++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java index 43fd07944c..9ec14aade7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java @@ -129,6 +129,13 @@ public class GitProtocolConstants { */ public static final String OPTION_ALLOW_TIP_SHA1_IN_WANT = "allow-tip-sha1-in-want"; //$NON-NLS-1$ + /** + * Symbolic reference support for better negotiation. + * + * @since 3.6 + */ + public static final String OPTION_SYMREF = "symref"; //$NON-NLS-1$ + /** * The client supports atomic pushes. If this option is used, the server * will update all refs within one atomic transaction. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java index 581a44b1dc..76547a628b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java @@ -43,6 +43,8 @@ package org.eclipse.jgit.transport; +import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SYMREF; + import java.io.IOException; import java.util.HashSet; import java.util.LinkedHashSet; @@ -145,6 +147,27 @@ public abstract class RefAdvertiser { capablities.add(name); } + /** + * Add a symbolic ref to capabilities. + *

+ * This method must be invoked prior to any of the following: + *

+ * + * @param from + * The symbolic ref, e.g. "HEAD" + * @param to + * The real ref it points to, e.g. "refs/heads/master" + * + * @since 3.6 + */ + public void addSymref(String from, String to) { + String symref = String.format("%s=%s:%s", OPTION_SYMREF, from, to); //$NON-NLS-1$ + advertiseCapability(symref); + } + /** * Format an advertisement for the supplied refs. * diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java index 83806f129a..1a653bd2be 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -807,7 +807,9 @@ public class UploadPack { || policy == null) adv.advertiseCapability(OPTION_ALLOW_TIP_SHA1_IN_WANT); adv.setDerefTags(true); - advertised = adv.send(getAdvertisedOrDefaultRefs()); + Map refs = getAdvertisedOrDefaultRefs(); + findSymrefs(adv, refs); + advertised = adv.send(refs); if (adv.isEmpty()) adv.advertiseId(ObjectId.zeroId(), "capabilities^{}"); //$NON-NLS-1$ adv.end(); @@ -1430,4 +1432,12 @@ public class UploadPack { if (sideband) pckOut.end(); } + + private void findSymrefs( + final RefAdvertiser adv, final Map refs) { + Ref head = refs.get(Constants.HEAD); + if (head != null && head.isSymbolic()) { + adv.addSymref(Constants.HEAD, head.getLeaf().getName()); + } + } } -- 2.39.5