summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse
diff options
context:
space:
mode:
authorJonathan Tan <jonathantanmy@google.com>2018-02-22 10:24:19 -0800
committerJonathan Nieder <jrn@google.com>2018-04-23 10:26:51 -0700
commit332bc611249d21f9b604f2c0207bf0bdfbfc3a78 (patch)
tree7238a842e2c4481c0ebe279d30f1a8caa0177a5b /org.eclipse.jgit/src/org/eclipse
parent2661bc081340ae83d2a2ecba11994d3e8d56586b (diff)
downloadjgit-332bc611249d21f9b604f2c0207bf0bdfbfc3a78.tar.gz
jgit-332bc611249d21f9b604f2c0207bf0bdfbfc3a78.zip
Implement ls-refs in UploadPack
Implement support for Git protocol v2's "ls-refs" command and its "symrefs" and "peel" parameters. This adds support for this command to UploadPack but the git://, ssh://, and git:// transports do not make use of it yet. That will have to wait for later patches. Change-Id: I8abc6bcc6ed4a88c165677ff1245625aca01267b Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Jonathan Nieder <jrn@google.com>
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java7
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java38
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java35
3 files changed, 79 insertions, 1 deletions
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 6d39dcd8a7..ccefb51684 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java
@@ -222,6 +222,13 @@ public class GitProtocolConstants {
*/
public static final String CAPABILITY_PUSH_OPTIONS = "push-options"; //$NON-NLS-1$
+ /**
+ * The server supports listing refs using protocol v2.
+ *
+ * @since 5.0
+ */
+ public static final String COMMAND_LS_REFS = "ls-refs"; //$NON-NLS-1$
+
static enum MultiAck {
OFF, CONTINUE, DETAILED;
}
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 6ad39e3ddd..0257ebec63 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java
@@ -53,6 +53,7 @@ import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
@@ -176,6 +177,11 @@ public abstract class RefAdvertiser {
boolean first = true;
+ private boolean useProtocolV2;
+
+ /* only used in protocol v2 */
+ private final Map<String, String> symrefs = new HashMap<>();
+
/**
* Initialize this advertiser with a repository for peeling tags.
*
@@ -187,6 +193,15 @@ public abstract class RefAdvertiser {
}
/**
+ * @param b
+ * true if this advertiser should advertise using the
+ * protocol v2 format, false otherwise
+ */
+ public void setUseProtocolV2(boolean b) {
+ useProtocolV2 = b;
+ }
+
+ /**
* Toggle tag peeling.
* <p>
* <p>
@@ -253,7 +268,11 @@ public abstract class RefAdvertiser {
* @since 3.6
*/
public void addSymref(String from, String to) {
- advertiseCapability(OPTION_SYMREF, from + ':' + to);
+ if (useProtocolV2) {
+ symrefs.put(from, to);
+ } else {
+ advertiseCapability(OPTION_SYMREF, from + ':' + to);
+ }
}
/**
@@ -273,6 +292,23 @@ public abstract class RefAdvertiser {
if (ref.getObjectId() == null)
continue;
+ if (useProtocolV2) {
+ String symrefPart = symrefs.containsKey(ref.getName())
+ ? (" symref-target:" + symrefs.get(ref.getName()))
+ : "";
+ String peelPart = "";
+ if (derefTags) {
+ if (!ref.isPeeled() && repository != null) {
+ ref = repository.peel(ref);
+ }
+ if (ref.getPeeledObjectId() != null) {
+ peelPart = " peeled:" + ref.getPeeledObjectId().getName();
+ }
+ }
+ writeOne(ref.getObjectId().getName() + " " + ref.getName() + symrefPart + peelPart + "\n");
+ continue;
+ }
+
advertiseAny(ref.getObjectId(), ref.getName());
if (!derefTags)
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 7f6182bf9b..b2b346a6b3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -44,6 +44,7 @@
package org.eclipse.jgit.transport;
import static org.eclipse.jgit.lib.RefDatabase.ALL;
+import static org.eclipse.jgit.transport.GitProtocolConstants.COMMAND_LS_REFS;
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_AGENT;
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_ALLOW_REACHABLE_SHA1_IN_WANT;
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_ALLOW_TIP_SHA1_IN_WANT;
@@ -117,6 +118,7 @@ public class UploadPack {
// supports protocol version 2.
private static final String[] v2CapabilityAdvertisement = {
"version 2",
+ COMMAND_LS_REFS
};
/** Policy the server uses to validate client requests */
@@ -864,6 +866,35 @@ public class UploadPack {
sendPack(accumulator);
}
+ private void lsRefsV2() throws IOException {
+ PacketLineOutRefAdvertiser adv = new PacketLineOutRefAdvertiser(pckOut);
+ Map<String, Ref> refs = getAdvertisedOrDefaultRefs();
+ String line;
+
+ adv.setUseProtocolV2(true);
+
+ line = pckIn.readString();
+
+ // Currently, we do not support any capabilities, so the next
+ // line is DELIM if there are arguments or END if not.
+ if (line == PacketLineIn.DELIM) {
+ while ((line = pckIn.readString()) != PacketLineIn.END) {
+ if (line.equals("peel")) {
+ adv.setDerefTags(true);
+ } else if (line.equals("symrefs")) {
+ findSymrefs(adv, refs);
+ } else {
+ throw new PackProtocolException("unexpected " + line);
+ }
+ }
+ } else if (line != PacketLineIn.END) {
+ throw new PackProtocolException("unexpected " + line);
+ }
+
+ adv.send(refs);
+ adv.end();
+ }
+
/*
* Returns true if this is the last command and we should tear down the
* connection.
@@ -882,6 +913,10 @@ public class UploadPack {
// case.
return true;
}
+ if (command.equals("command=" + COMMAND_LS_REFS)) {
+ lsRefsV2();
+ return false;
+ }
throw new PackProtocolException("unknown command " + command);
}