diff options
author | Thomas Wolf <thomas.wolf@paranor.ch> | 2020-11-03 23:33:19 +0100 |
---|---|---|
committer | Thomas Wolf <thomas.wolf@paranor.ch> | 2020-11-03 23:50:21 +0100 |
commit | d69fb4d4ac7bcf7d0d84109bba56cf944646fb24 (patch) | |
tree | 12a796e526b04e9207ef7f05b28d263154150053 /org.eclipse.jgit | |
parent | 5dcc46591aa1ad63f19e5240eff2cabe6bb9f306 (diff) | |
download | jgit-d69fb4d4ac7bcf7d0d84109bba56cf944646fb24.tar.gz jgit-d69fb4d4ac7bcf7d0d84109bba56cf944646fb24.zip |
Revert "Client-side protocol V2 support for fetching"
This reverts commit f802f06e7fd5a98f256b7b7727598491f563bf2f.
I had misunderstood how protocol V2 works. This implementation only
works if the negotiation during fetch is done in one round.
Fixing this is substantial work in BasePackFetchConnection. Basically
I think I'd have to change back negotiate to the V0 version, and have
a doFetch() that does
if protocol V2
doFetchV2()
else
doFetchV0()
with doFetchV0 the old code, and doFetchV2 completely new.
Plus there would need to be a HTTP test case requiring several
negotiation rounds.
This is a couple of days work at least, and I don't know when I will
have the time to revisit this. So although the rest of the code is
fine I prefer to back this out completely and not leave a only half
working implementation in the code for an indeterminate time.
Bug: 553083
Change-Id: Icbbbb09882b3b83f9897deac4a06d5f8dc99d84e
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.jgit')
16 files changed, 125 insertions, 915 deletions
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties index 3027e39a75..c9e48a5c09 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -232,7 +232,6 @@ downloadCancelled=Download cancelled downloadCancelledDuringIndexing=Download cancelled during indexing duplicateAdvertisementsOf=duplicate advertisements of {0} duplicateRef=Duplicate ref: {0} -duplicateRefAttribute=Duplicate ref attribute: {0} duplicateRemoteRefUpdateIsIllegal=Duplicate remote ref update is illegal. Affected remote name: {0} duplicateStagesNotAllowed=Duplicate stages not allowed eitherGitDirOrWorkTreeRequired=One of setGitDir or setWorkTree must be called. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java index 77ecf3b367..a4ca309095 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java @@ -164,7 +164,7 @@ public class LsRemoteCommand extends refSpecs.add(new RefSpec("refs/heads/*:refs/remotes/origin/*")); //$NON-NLS-1$ Collection<Ref> refs; Map<String, Ref> refmap = new HashMap<>(); - try (FetchConnection fc = transport.openFetch(refSpecs)) { + try (FetchConnection fc = transport.openFetch()) { refs = fc.getRefs(); if (refSpecs.isEmpty()) for (Ref r : refs) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java index 9887ed8230..b761210e63 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -260,7 +260,6 @@ public class JGitText extends TranslationBundle { /***/ public String downloadCancelledDuringIndexing; /***/ public String duplicateAdvertisementsOf; /***/ public String duplicateRef; - /***/ public String duplicateRefAttribute; /***/ public String duplicateRemoteRefUpdateIsIllegal; /***/ public String duplicateStagesNotAllowed; /***/ public String eitherGitDirOrWorkTreeRequired; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java index c9c6c0c25d..1417faee80 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java @@ -13,12 +13,7 @@ package org.eclipse.jgit.transport; -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.REF_ATTR_PEELED; -import static org.eclipse.jgit.transport.GitProtocolConstants.REF_ATTR_SYMREF_TARGET; -import static org.eclipse.jgit.transport.GitProtocolConstants.VERSION_1; -import static org.eclipse.jgit.transport.GitProtocolConstants.VERSION_2; import java.io.EOFException; import java.io.IOException; @@ -26,28 +21,20 @@ import java.io.InputStream; import java.io.OutputStream; import java.text.MessageFormat; import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; import java.util.Set; -import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.errors.InvalidObjectIdException; import org.eclipse.jgit.errors.NoRemoteRepositoryException; import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.errors.RemoteRepositoryException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdRef; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.util.TemporaryBuffer; import org.eclipse.jgit.util.io.InterruptTimer; import org.eclipse.jgit.util.io.TimeoutInputStream; import org.eclipse.jgit.util.io.TimeoutOutputStream; @@ -99,27 +86,17 @@ abstract class BasePackConnection extends BaseConnection { protected boolean statelessRPC; /** Capability tokens advertised by the remote side. */ - private final Map<String, String> remoteCapabilities = new HashMap<>(); + private final Set<String> remoteCapablities = new HashSet<>(); /** Extra objects the remote has, but which aren't offered as refs. */ protected final Set<ObjectId> additionalHaves = new HashSet<>(); - private TransferConfig.ProtocolVersion protocol = TransferConfig.ProtocolVersion.V0; - BasePackConnection(PackTransport packTransport) { transport = (Transport) packTransport; local = transport.local; uri = transport.uri; } - TransferConfig.ProtocolVersion getProtocolVersion() { - return protocol; - } - - void setProtocolVersion(@NonNull TransferConfig.ProtocolVersion protocol) { - this.protocol = protocol; - } - /** * Configure this connection with the directional pipes. * @@ -164,15 +141,12 @@ abstract class BasePackConnection extends BaseConnection { * {@link #close()} and the exception is wrapped (if necessary) and thrown * as a {@link org.eclipse.jgit.errors.TransportException}. * - * @return {@code true} if the refs were read; {@code false} otherwise - * indicating that {@link #lsRefs} must be called - * * @throws org.eclipse.jgit.errors.TransportException * the reference list could not be scanned. */ - protected boolean readAdvertisedRefs() throws TransportException { + protected void readAdvertisedRefs() throws TransportException { try { - return readAdvertisedRefsImpl(); + readAdvertisedRefsImpl(); } catch (TransportException err) { close(); throw err; @@ -182,66 +156,35 @@ abstract class BasePackConnection extends BaseConnection { } } - private String readLine() throws IOException { - String line = pckIn.readString(); - if (PacketLineIn.isEnd(line)) { - return null; - } - if (line.startsWith("ERR ")) { //$NON-NLS-1$ - // This is a customized remote service error. - // Users should be informed about it. - throw new RemoteRepositoryException(uri, line.substring(4)); - } - return line; - } - - private boolean readAdvertisedRefsImpl() throws IOException { + private void readAdvertisedRefsImpl() throws IOException { final LinkedHashMap<String, Ref> avail = new LinkedHashMap<>(); - for (boolean first = true;; first = false) { + for (;;) { String line; - if (first) { - boolean isV1 = false; - try { - line = readLine(); - } catch (EOFException e) { + try { + line = pckIn.readString(); + } catch (EOFException eof) { + if (avail.isEmpty()) throw noRepository(); - } - if (line != null && VERSION_1.equals(line)) { - // Same as V0, except for this extra line. We shouldn't get - // it since we never request V1. - setProtocolVersion(TransferConfig.ProtocolVersion.V0); - isV1 = true; - line = readLine(); - } - if (line == null) { - break; - } + throw eof; + } + if (PacketLineIn.isEnd(line)) + break; + + if (line.startsWith("ERR ")) { //$NON-NLS-1$ + // This is a customized remote service error. + // Users should be informed about it. + throw new RemoteRepositoryException(uri, line.substring(4)); + } + + if (avail.isEmpty()) { final int nul = line.indexOf('\0'); if (nul >= 0) { - // Protocol V0: The first line (if any) may contain - // "hidden" capability values after a NUL byte. - for (String capability : line.substring(nul + 1) - .split(" ")) { //$NON-NLS-1$ - addCapability(capability); - } + // The first line (if any) may contain "hidden" + // capability values after a NUL byte. + remoteCapablities.addAll( + Arrays.asList(line.substring(nul + 1).split(" "))); //$NON-NLS-1$ line = line.substring(0, nul); - setProtocolVersion(TransferConfig.ProtocolVersion.V0); - } else if (!isV1 && VERSION_2.equals(line)) { - // Protocol V2: remaining lines are capabilities as - // key=value pairs - setProtocolVersion(TransferConfig.ProtocolVersion.V2); - readCapabilitiesV2(); - // Break out here so that stateless RPC transports get a - // chance to set up the output stream. - return false; - } else { - setProtocolVersion(TransferConfig.ProtocolVersion.V0); - } - } else { - line = readLine(); - if (line == null) { - break; } } @@ -250,230 +193,44 @@ abstract class BasePackConnection extends BaseConnection { throw invalidRefAdvertisementLine(line); } String name = line.substring(41, line.length()); - if (first && name.equals("capabilities^{}")) { //$NON-NLS-1$ - // special line from git-receive-pack (protocol V0) to show + if (avail.isEmpty() && name.equals("capabilities^{}")) { //$NON-NLS-1$ + // special line from git-receive-pack to show // capabilities when there are no refs to advertise - // TODO: throw error if protocol version is >= V2? continue; } - final ObjectId id = toId(line, line.substring(0, 40)); + final ObjectId id; + try { + id = ObjectId.fromString(line.substring(0, 40)); + } catch (InvalidObjectIdException e) { + PackProtocolException ppe = invalidRefAdvertisementLine(line); + ppe.initCause(e); + throw ppe; + } if (name.equals(".have")) { //$NON-NLS-1$ additionalHaves.add(id); - } else { - processLineV1(name, id, avail); - } - } - available(avail); - return true; - } + } else if (name.endsWith("^{}")) { //$NON-NLS-1$ + name = name.substring(0, name.length() - 3); + final Ref prior = avail.get(name); + if (prior == null) + throw new PackProtocolException(uri, MessageFormat.format( + JGitText.get().advertisementCameBefore, name, name)); - /** - * Issue a protocol V2 ls-refs command and read its response. - * - * @param refSpecs - * to produce ref prefixes from if the server supports git - * protocol V2 - * @param additionalPatterns - * to use for ref prefixes if the server supports git protocol V2 - * @throws TransportException - * if the command could not be run or its output not be read - */ - protected void lsRefs(Collection<RefSpec> refSpecs, - String... additionalPatterns) throws TransportException { - try { - lsRefsImpl(refSpecs, additionalPatterns); - } catch (TransportException err) { - close(); - throw err; - } catch (IOException | RuntimeException err) { - close(); - throw new TransportException(err.getMessage(), err); - } - } + if (prior.getPeeledObjectId() != null) + throw duplicateAdvertisement(name + "^{}"); //$NON-NLS-1$ - private void lsRefsImpl(Collection<RefSpec> refSpecs, - String... additionalPatterns) throws IOException { - TemporaryBuffer state = null; - PacketLineOut pckState = null; - PacketLineOut output = pckOut; - if (statelessRPC) { - state = new TemporaryBuffer.Heap(Integer.MAX_VALUE); - pckState = new PacketLineOut(state); - output = pckState; - } - output.writeString("command=" + COMMAND_LS_REFS); //$NON-NLS-1$ - // Add the user-agent - String agent = UserAgent.get(); - if (agent != null && isCapableOf(OPTION_AGENT)) { - output.writeString(OPTION_AGENT + '=' + agent); - } - output.writeDelim(); - output.writeString("peel"); //$NON-NLS-1$ - for (String refPrefix : getRefPrefixes(refSpecs, additionalPatterns)) { - output.writeString("ref-prefix " + refPrefix); //$NON-NLS-1$ - } - output.end(); - output.flush(); - if (state != null) { - state.writeTo(out, null); - out.flush(); - state = null; - pckState = null; - } - final LinkedHashMap<String, Ref> avail = new LinkedHashMap<>(); - for (;;) { - String line = readLine(); - if (line == null) { - break; - } - // Expecting to get a line in the form "sha1 refname" - if (line.length() < 41 || line.charAt(40) != ' ') { - throw invalidRefAdvertisementLine(line); - } - String name = line.substring(41, line.length()); - final ObjectId id = toId(line, line.substring(0, 40)); - if (name.equals(".have")) { //$NON-NLS-1$ - additionalHaves.add(id); + avail.put(name, new ObjectIdRef.PeeledTag( + Ref.Storage.NETWORK, name, prior.getObjectId(), id)); } else { - processLineV2(line, id, name, avail); + final Ref prior = avail.put(name, new ObjectIdRef.PeeledNonTag( + Ref.Storage.NETWORK, name, id)); + if (prior != null) + throw duplicateAdvertisement(name); } } available(avail); } - private Collection<String> getRefPrefixes(Collection<RefSpec> refSpecs, - String... additionalPatterns) { - if (refSpecs.isEmpty() && (additionalPatterns == null - || additionalPatterns.length == 0)) { - return Collections.emptyList(); - } - Set<String> patterns = new HashSet<>(); - if (additionalPatterns != null) { - Arrays.stream(additionalPatterns).filter(Objects::nonNull) - .forEach(patterns::add); - } - for (RefSpec spec : refSpecs) { - // TODO: for now we only do protocol V2 for fetch. For push - // RefSpecs, the logic would need to be different. (At the - // minimum, take spec.getDestination().) - String src = spec.getSource(); - if (ObjectId.isId(src)) { - continue; - } - if (spec.isWildcard()) { - patterns.add(src.substring(0, src.indexOf('*'))); - } else { - patterns.add(src); - patterns.add(Constants.R_REFS + src); - patterns.add(Constants.R_HEADS + src); - patterns.add(Constants.R_TAGS + src); - } - } - return patterns; - } - - private void readCapabilitiesV2() throws IOException { - // In git protocol V2, capabilities are different. If it's a key-value - // pair, the key may be a command name, and the value a space-separated - // list of capabilities for that command. We still store it in the same - // map as for protocol v0/v1. Protocol v2 code has to account for this. - for (;;) { - String line = readLine(); - if (line == null) { - break; - } - addCapability(line); - } - } - - private void addCapability(String capability) { - String parts[] = capability.split("=", 2); //$NON-NLS-1$ - if (parts.length == 2) { - remoteCapabilities.put(parts[0], parts[1]); - } - remoteCapabilities.put(capability, null); - } - - private ObjectId toId(String line, String value) - throws PackProtocolException { - try { - return ObjectId.fromString(value); - } catch (InvalidObjectIdException e) { - PackProtocolException ppe = invalidRefAdvertisementLine(line); - ppe.initCause(e); - throw ppe; - } - } - - private void processLineV1(String name, ObjectId id, Map<String, Ref> avail) - throws IOException { - if (name.endsWith("^{}")) { //$NON-NLS-1$ - name = name.substring(0, name.length() - 3); - final Ref prior = avail.get(name); - if (prior == null) { - throw new PackProtocolException(uri, MessageFormat.format( - JGitText.get().advertisementCameBefore, name, name)); - } - if (prior.getPeeledObjectId() != null) { - throw duplicateAdvertisement(name + "^{}"); //$NON-NLS-1$ - } - avail.put(name, new ObjectIdRef.PeeledTag(Ref.Storage.NETWORK, name, - prior.getObjectId(), id)); - } else { - final Ref prior = avail.put(name, new ObjectIdRef.PeeledNonTag( - Ref.Storage.NETWORK, name, id)); - if (prior != null) { - throw duplicateAdvertisement(name); - } - } - } - - private void processLineV2(String line, ObjectId id, String rest, - Map<String, Ref> avail) throws IOException { - String[] parts = rest.split(" "); //$NON-NLS-1$ - String name = parts[0]; - // Two attributes possible, symref-target or peeled - String symRefTarget = null; - String peeled = null; - for (int i = 1; i < parts.length; i++) { - if (parts[i].startsWith(REF_ATTR_SYMREF_TARGET)) { - if (symRefTarget != null) { - throw new PackProtocolException(uri, MessageFormat.format( - JGitText.get().duplicateRefAttribute, line)); - } - symRefTarget = parts[i] - .substring(REF_ATTR_SYMREF_TARGET.length()); - } else if (parts[i].startsWith(REF_ATTR_PEELED)) { - if (peeled != null) { - throw new PackProtocolException(uri, MessageFormat.format( - JGitText.get().duplicateRefAttribute, line)); - } - peeled = parts[i].substring(REF_ATTR_PEELED.length()); - } - if (peeled != null && symRefTarget != null) { - break; - } - } - Ref idRef; - if (peeled != null) { - idRef = new ObjectIdRef.PeeledTag(Ref.Storage.NETWORK, name, id, - toId(line, peeled)); - } else { - idRef = new ObjectIdRef.PeeledNonTag(Ref.Storage.NETWORK, name, id); - } - Ref prior = avail.put(name, idRef); - if (prior != null) { - throw duplicateAdvertisement(name); - } - if (symRefTarget != null) { - // What do we have to do with this information? In protocol V0, this - // info comes in the capability advertisement, but OPTION_SYMREF is - // used only in RefAdvertiser. JGit's client side doesn't make use - // of this information, and actually never requests it. - } - } - /** * Create an exception to indicate problems finding a remote repository. The * caller is expected to throw the returned exception. @@ -495,7 +252,7 @@ abstract class BasePackConnection extends BaseConnection { * @return whether this option is supported */ protected boolean isCapableOf(String option) { - return remoteCapabilities.containsKey(option); + return remoteCapablities.contains(option); } /** @@ -516,17 +273,6 @@ abstract class BasePackConnection extends BaseConnection { } /** - * Return a capability value. - * - * @param option - * to get - * @return the value stored, if any. - */ - protected String getCapability(String option) { - return remoteCapabilities.get(option); - } - - /** * Add user agent capability * * @param b @@ -534,7 +280,7 @@ abstract class BasePackConnection extends BaseConnection { */ protected void addUserAgentCapability(StringBuilder b) { String a = UserAgent.get(); - if (a != null && remoteCapabilities.get(OPTION_AGENT) != null) { + if (a != null && UserAgent.hasAgent(remoteCapablities)) { b.append(' ').append(OPTION_AGENT).append('=').append(a); } } @@ -542,8 +288,7 @@ abstract class BasePackConnection extends BaseConnection { /** {@inheritDoc} */ @Override public String getPeerUserAgent() { - String agent = remoteCapabilities.get(OPTION_AGENT); - return agent != null ? agent : super.getPeerUserAgent(); + return UserAgent.getAgent(remoteCapablities, super.getPeerUserAgent()); } private PackProtocolException duplicateAdvertisement(String name) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java index 2432641ede..a2fb51f46d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java @@ -16,12 +16,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.MessageFormat; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; -import java.util.HashSet; -import java.util.LinkedHashSet; import java.util.Set; import org.eclipse.jgit.errors.PackProtocolException; @@ -215,8 +212,6 @@ public abstract class BasePackFetchConnection extends BasePackConnection private PacketLineOut pckState; - private Set<String> fetchCapabilities = new HashSet<>(); - /** * Either FilterSpec.NO_FILTER for a filter that doesn't filter * anything, or a filter that indicates what and what not to send to the @@ -359,28 +354,6 @@ public abstract class BasePackFetchConnection extends BasePackConnection pckState = new PacketLineOut(state); } - if (TransferConfig.ProtocolVersion.V2 - .equals(getProtocolVersion())) { - sideband = true; - noDone = true; - multiAck = MultiAck.DETAILED; - setFetchOptions(); - PacketLineOut output = statelessRPC ? pckState : pckOut; - output.writeString( - "command=" + GitProtocolConstants.COMMAND_FETCH); //$NON-NLS-1$ - // Capabilities are sent as command arguments in protocol V2 - String agent = UserAgent.get(); - if (agent != null - && isCapableOf(GitProtocolConstants.OPTION_AGENT)) { - output.writeString( - GitProtocolConstants.OPTION_AGENT + '=' + agent); - } - output.writeDelim(); - // Arguments - for (String capability : getCapabilitiesV2()) { - output.writeString(capability); - } - } if (sendWants(want)) { negotiate(monitor); @@ -389,25 +362,6 @@ public abstract class BasePackFetchConnection extends BasePackConnection state = null; pckState = null; - if (TransferConfig.ProtocolVersion.V2 - .equals(getProtocolVersion())) { - String header = pckIn.readString(); - if (PacketLineIn.isEnd(header)) { - // No packfile following. - return; - } - - if (header.startsWith("ERR ")) { //$NON-NLS-1$ - // Protocol V2 may give us an error here (for instance, - // invalid want) - throw new PackProtocolException(header.substring(4)); - } - if (!GitProtocolConstants.SECTION_PACKFILE.equals(header)) { - throw new PackProtocolException(MessageFormat.format( - JGitText.get().expectedGot, - GitProtocolConstants.SECTION_PACKFILE, header)); - } - } receivePack(monitor, outputStream); } } catch (CancelledException ce) { @@ -427,14 +381,6 @@ public abstract class BasePackFetchConnection extends BasePackConnection super.close(); } - private void setFetchOptions() { - String advertised = getCapability(GitProtocolConstants.COMMAND_FETCH); - if (advertised == null) { - return; - } - fetchCapabilities.addAll(Arrays.asList(advertised.split(" "))); //$NON-NLS-1$ - } - FetchConfig getFetchConfig() { return local.getConfig().get(FetchConfig::new); } @@ -533,11 +479,10 @@ public abstract class BasePackFetchConnection extends BasePackConnection final StringBuilder line = new StringBuilder(46); line.append("want "); //$NON-NLS-1$ line.append(objectId.name()); - if (first && TransferConfig.ProtocolVersion.V0 - .equals(getProtocolVersion())) { + if (first) { line.append(enableCapabilities()); + first = false; } - first = false; line.append('\n'); p.writeString(line.toString()); } @@ -547,35 +492,11 @@ public abstract class BasePackFetchConnection extends BasePackConnection if (!filterSpec.isNoOp()) { p.writeString(filterSpec.filterLine()); } - if (TransferConfig.ProtocolVersion.V0.equals(getProtocolVersion())) { - p.end(); - outNeedsEnd = false; - } + p.end(); + outNeedsEnd = false; return true; } - private Set<String> getCapabilitiesV2() throws TransportException { - Set<String> capabilities = new LinkedHashSet<>(); - if (noProgress) { - capabilities.add(OPTION_NO_PROGRESS); - } - if (includeTags) { - capabilities.add(OPTION_INCLUDE_TAG); - } - if (allowOfsDelta) { - capabilities.add(OPTION_OFS_DELTA); - } - if (thinPack) { - capabilities.add(OPTION_THIN_PACK); - } - if (!filterSpec.isNoOp() - && !fetchCapabilities.contains(OPTION_FILTER)) { - throw new PackProtocolException(uri, - JGitText.get().filterRequiresCapability); - } - return capabilities; - } - private String enableCapabilities() throws TransportException { final StringBuilder line = new StringBuilder(); if (noProgress) @@ -629,7 +550,6 @@ public abstract class BasePackFetchConnection extends BasePackConnection boolean receivedContinue = false; boolean receivedAck = false; boolean receivedReady = false; - boolean needsAcknowledgementV2 = true; if (statelessRPC) { state.writeTo(out, null); @@ -643,7 +563,7 @@ public abstract class BasePackFetchConnection extends BasePackConnection } ObjectId o = c.getId(); - pckOut.writeString("have " + o.name() + '\n'); //$NON-NLS-1$ + pckOut.writeString("have " + o.name() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ havesSent++; havesSinceLastContinue++; @@ -660,7 +580,6 @@ public abstract class BasePackFetchConnection extends BasePackConnection } pckOut.end(); - outNeedsEnd = false; resultsPending++; // Each end will cause a result to come back. if (havesSent == 32 && !statelessRPC) { @@ -672,32 +591,9 @@ public abstract class BasePackFetchConnection extends BasePackConnection continue; } - // Read the section header - if (needsAcknowledgementV2 && TransferConfig.ProtocolVersion.V2 - .equals(getProtocolVersion())) { - String header = pckIn.readString(); - if (!GitProtocolConstants.SECTION_ACKNOWLEDGMENTS - .equals(header)) { - throw new PackProtocolException(MessageFormat.format( - JGitText.get().expectedGot, - GitProtocolConstants.SECTION_ACKNOWLEDGMENTS, - header)); - } - needsAcknowledgementV2 = false; - } READ_RESULT: for (;;) { - AckNackResult anr = pckIn.readACKorEOF(ackId); + final AckNackResult anr = pckIn.readACK(ackId); switch (anr) { - case ACK_EOF: - if (TransferConfig.ProtocolVersion.V0 - .equals(getProtocolVersion())) { - throw new PackProtocolException( - JGitText.get().expectedACKNAKFoundEOF); - } - // More lines needed - resultsPending--; - break READ_RESULT; - case NAK: // More have lines are necessary to compute the // pack on the remote side. Keep doing that. @@ -706,24 +602,17 @@ public abstract class BasePackFetchConnection extends BasePackConnection break READ_RESULT; case ACK: - if (TransferConfig.ProtocolVersion.V0 - .equals(getProtocolVersion())) { - // The remote side is happy and knows exactly what - // to send us. There is no further negotiation and - // we can break out immediately. - // - multiAck = MultiAck.OFF; - resultsPending = 0; - receivedAck = true; - if (statelessRPC) { - state.writeTo(out, null); - } - break SEND_HAVES; - } - // Keep on reading ACKs until we get the ACK_READY - markCommon(walk.parseAny(ackId), AckNackResult.ACK_COMMON); + // The remote side is happy and knows exactly what + // to send us. There is no further negotiation and + // we can break out immediately. + // + multiAck = MultiAck.OFF; + resultsPending = 0; receivedAck = true; - break; + if (statelessRPC) { + state.writeTo(out, null); + } + break SEND_HAVES; case ACK_CONTINUE: case ACK_COMMON: @@ -739,12 +628,6 @@ public abstract class BasePackFetchConnection extends BasePackConnection havesSinceLastContinue = 0; if (anr == AckNackResult.ACK_READY) { receivedReady = true; - if (TransferConfig.ProtocolVersion.V2 - .equals(getProtocolVersion())) { - multiAck = MultiAck.OFF; - resultsPending = 0; - break SEND_HAVES; - } } break; } @@ -778,36 +661,15 @@ public abstract class BasePackFetchConnection extends BasePackConnection throw new CancelledException(); } - if (receivedReady && TransferConfig.ProtocolVersion.V2 - .equals(getProtocolVersion())) { - // We'll get the packfile right away. Skip the delimiter. - String delim = pckIn.readString(); - if (!PacketLineIn.isDelimiter(delim)) { - throw new PackProtocolException(MessageFormat - .format(JGitText.get().expectedGot, "0001", delim)); //$NON-NLS-1$ - } - return; - } if (!receivedReady || !noDone) { // When statelessRPC is true we should always leave SEND_HAVES // loop above while in the middle of a request. This allows us // to just write done immediately. // pckOut.writeString("done\n"); //$NON-NLS-1$ - if (TransferConfig.ProtocolVersion.V2 - .equals(getProtocolVersion())) { - pckOut.end(); - outNeedsEnd = false; - pckOut.flush(); - // Protocol V2 will skip acknowledgments completely if we send - // a done. - return; - } pckOut.flush(); } - // Below is protocol V0 only. - if (!receivedAck) { // Apparently if we have never received an ACK earlier // there is one more result expected from the done we @@ -827,14 +689,6 @@ public abstract class BasePackFetchConnection extends BasePackConnection // break; - case ACK_EOF: - if (TransferConfig.ProtocolVersion.V0 - .equals(getProtocolVersion())) { - throw new PackProtocolException( - JGitText.get().expectedACKNAKFoundEOF); - } - break READ_RESULT; - case ACK: // A solitary ACK at this point means the remote won't // speak anymore, but is going to send us a pack now. @@ -843,16 +697,7 @@ public abstract class BasePackFetchConnection extends BasePackConnection case ACK_CONTINUE: case ACK_COMMON: - // We will expect a normal ACK to break out of the loop. - // - multiAck = MultiAck.CONTINUE; - break; - case ACK_READY: - if (TransferConfig.ProtocolVersion.V2 - .equals(getProtocolVersion())) { - break READ_RESULT; - } // We will expect a normal ACK to break out of the loop. // multiAck = MultiAck.CONTINUE; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java index b9b764c9d0..0f1892a97e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java @@ -102,21 +102,7 @@ class FetchProcess { private void executeImp(final ProgressMonitor monitor, final FetchResult result) throws NotSupportedException, TransportException { - final TagOpt tagopt = transport.getTagOpt(); - String getTags = (tagopt == TagOpt.NO_TAGS) ? null : Constants.R_TAGS; - String getHead = null; - try { - // If we don't have a HEAD yet, we're cloning and need to get the - // upstream HEAD, too. - Ref head = transport.local.exactRef(Constants.HEAD); - ObjectId id = head != null ? head.getObjectId() : null; - if (id == null || id.equals(ObjectId.zeroId())) { - getHead = Constants.HEAD; - } - } catch (IOException e) { - // Ignore - } - conn = transport.openFetch(toFetch, getTags, getHead); + conn = transport.openFetch(); try { result.setAdvertisedRefs(transport.getURI(), conn.getRefsMap()); result.peerUserAgent = conn.getPeerUserAgent(); @@ -133,6 +119,7 @@ class FetchProcess { } Collection<Ref> additionalTags = Collections.<Ref> emptyList(); + final TagOpt tagopt = transport.getTagOpt(); if (tagopt == TagOpt.AUTO_FOLLOW) additionalTags = expandAutoFollowTags(); else if (tagopt == TagOpt.FETCH_TAGS) @@ -266,17 +253,7 @@ class FetchProcess { if (conn != null) return; - // Build prefixes - Set<String> prefixes = new HashSet<>(); - for (Ref toGet : askFor.values()) { - String src = toGet.getName(); - prefixes.add(src); - prefixes.add(Constants.R_REFS + src); - prefixes.add(Constants.R_HEADS + src); - prefixes.add(Constants.R_TAGS + src); - } - conn = transport.openFetch(Collections.emptyList(), - prefixes.toArray(new String[0])); + conn = transport.openFetch(); // Since we opened a new connection we cannot be certain // that the system we connected to has the same exact set 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 ea6dec8ee7..35e2978bc4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java @@ -247,74 +247,6 @@ public final class GitProtocolConstants { */ public static final String COMMAND_FETCH = "fetch"; //$NON-NLS-1$ - /** - * HTTP header to set by clients to request a specific git protocol version - * in the HTTP transport. - * - * @since 5.10 - */ - public static final String PROTOCOL_HEADER = "Git-Protocol"; //$NON-NLS-1$ - - /** - * Environment variable to set by clients to request a specific git protocol - * in the file:// and ssh:// transports. - * - * @since 5.10 - */ - public static final String PROTOCOL_ENVIRONMENT_VARIABLE = "GIT_PROTOCOL"; //$NON-NLS-1$ - - /** - * Protocol V2 ref advertisement attribute containing the peeled object id - * for annotated tags. - * - * @since 5.10 - */ - public static final String REF_ATTR_PEELED = "peeled:"; //$NON-NLS-1$ - - /** - * Protocol V2 ref advertisement attribute containing the name of the ref - * for symbolic refs. - * - * @since 5.10 - */ - public static final String REF_ATTR_SYMREF_TARGET = "symref-target:"; //$NON-NLS-1$ - - /** - * Protocol V2 acknowledgments section header. - * - * @since 5.10 - */ - public static final String SECTION_ACKNOWLEDGMENTS = "acknowledgments"; //$NON-NLS-1$ - - /** - * Protocol V2 packfile section header. - * - * @since 5.10 - */ - public static final String SECTION_PACKFILE = "packfile"; //$NON-NLS-1$ - - /** - * Protocol announcement for protocol version 1. This is the same as V0, - * except for this initial line. - * - * @since 5.10 - */ - public static final String VERSION_1 = "version 1"; //$NON-NLS-1$ - - /** - * Protocol announcement for protocol version 2. - * - * @since 5.10 - */ - public static final String VERSION_2 = "version 2"; //$NON-NLS-1$ - - /** - * Protocol request for protocol version 2. - * - * @since 5.10 - */ - public static final String VERSION_2_REQUEST = "version=2"; //$NON-NLS-1$ - enum MultiAck { OFF, CONTINUE, DETAILED; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java index 32046dc434..52a5576e43 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java @@ -72,9 +72,7 @@ public class PacketLineIn { /** ACK + common */ ACK_COMMON, /** ACK + ready */ - ACK_READY, - /** EOF (0000) recieved in protocol V2 when expecting an ACK/NAK */ - ACK_EOF; + ACK_READY; } private final byte[] lineBuffer = new byte[SideBandOutputStream.SMALL_BUF]; @@ -105,26 +103,12 @@ public class PacketLineIn { this.limit = limit; } - AckNackResult readACK(MutableObjectId returnedId) throws IOException { - AckNackResult result = readACKorEOF(returnedId); - if (result == AckNackResult.ACK_EOF) { - throw new PackProtocolException( - JGitText.get().expectedACKNAKFoundEOF); - } - return result; - } - - AckNackResult readACKorEOF(MutableObjectId returnedId) throws IOException { final String line = readString(); if (line.length() == 0) - return AckNackResult.ACK_EOF; + throw new PackProtocolException(JGitText.get().expectedACKNAKFoundEOF); if ("NAK".equals(line)) //$NON-NLS-1$ return AckNackResult.NAK; - if ("ready".equals(line)) { //$NON-NLS-1$ - // Protocol V2 - return AckNackResult.ACK_READY; - } if (line.startsWith("ACK ")) { //$NON-NLS-1$ returnedId.fromString(line.substring(4, 44)); if (line.length() == 44) 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 3f50c57843..3adebba03c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java @@ -13,8 +13,6 @@ package org.eclipse.jgit.transport; import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.Constants.OBJECT_ID_STRING_LENGTH; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SYMREF; -import static org.eclipse.jgit.transport.GitProtocolConstants.REF_ATTR_PEELED; -import static org.eclipse.jgit.transport.GitProtocolConstants.REF_ATTR_SYMREF_TARGET; import java.io.IOException; import java.nio.ByteBuffer; @@ -289,8 +287,7 @@ public abstract class RefAdvertiser { if (useProtocolV2) { String symrefPart = symrefs.containsKey(ref.getName()) - ? (' ' + REF_ATTR_SYMREF_TARGET - + symrefs.get(ref.getName())) + ? (" symref-target:" + symrefs.get(ref.getName())) //$NON-NLS-1$ : ""; //$NON-NLS-1$ String peelPart = ""; //$NON-NLS-1$ if (derefTags) { @@ -299,8 +296,7 @@ public abstract class RefAdvertiser { } ObjectId peeledObjectId = ref.getPeeledObjectId(); if (peeledObjectId != null) { - peelPart = ' ' + REF_ATTR_PEELED - + peeledObjectId.getName(); + peelPart = " peeled:" + peeledObjectId.getName(); //$NON-NLS-1$ } } writeOne(objectId.getName() + " " + ref.getName() + symrefPart //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteSession2.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteSession2.java deleted file mode 100644 index 8119f75aaa..0000000000 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteSession2.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2020, Thomas Wolf <thoams.wolf@paranor.ch> - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Distribution License v. 1.0 which is available at - * https://www.eclipse.org/org/documents/edl-v10.php. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -package org.eclipse.jgit.transport; - -import java.io.IOException; -import java.util.Map; - -/** - * A {@link RemoteSession} that supports passing environment variables to - * commands. - * - * @since 5.10 - */ -public interface RemoteSession2 extends RemoteSession { - - /** - * Creates a new remote {@link Process} to execute the given command. The - * returned process's streams exist and are connected, and execution of the - * process is already started. - * - * @param commandName - * command to execute - * @param environment - * environment variables to pass on - * @param timeout - * timeout value, in seconds, for creating the remote process - * @return a new remote process, already started - * @throws java.io.IOException - * may be thrown in several cases. For example, on problems - * opening input or output streams or on problems connecting or - * communicating with the remote host. For the latter two cases, - * a TransportException may be thrown (a subclass of - * java.io.IOException). - */ - Process exec(String commandName, Map<String, String> environment, - int timeout) throws IOException; -} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java index f0f9e1db68..2ddd0a6128 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java @@ -39,7 +39,6 @@ import java.util.Vector; import java.util.concurrent.CopyOnWriteArrayList; import org.eclipse.jgit.annotations.NonNull; -import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.api.errors.AbortedByHookException; import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.TransportException; @@ -775,10 +774,6 @@ public abstract class Transport implements AutoCloseable { private PrintStream hookOutRedirect; private PrePushHook prePush; - - @Nullable - TransferConfig.ProtocolVersion protocol; - /** * Create a new transport instance. * @@ -794,7 +789,6 @@ public abstract class Transport implements AutoCloseable { final TransferConfig tc = local.getConfig().get(TransferConfig.KEY); this.local = local; this.uri = uri; - this.protocol = tc.protocolVersion; this.objectChecker = tc.newObjectChecker(); this.credentialsProvider = CredentialsProvider.getDefault(); prePush = Hooks.prePush(local, hookOutRedirect); @@ -1459,43 +1453,6 @@ public abstract class Transport implements AutoCloseable { TransportException; /** - * Begins a new connection for fetching from the remote repository. - * <p> - * If the transport has no local repository, the fetch connection can only - * be used for reading remote refs. - * </p> - * <p> - * If the server supports git protocol V2, the {@link RefSpec}s and the - * additional patterns, if any, are used to restrict the server's ref - * advertisement to matching refs only. - * </p> - * <p> - * Transports that want to support git protocol V2 <em>must</em> override - * this; the default implementation ignores its arguments and calls - * {@link #openFetch()}. - * </p> - * - * @param refSpecs - * that will be fetched via - * {@link FetchConnection#fetch(ProgressMonitor, Collection, java.util.Set, OutputStream)} later - * @param additionalPatterns - * that will be set as ref prefixes if the server supports git - * protocol V2; {@code null} values are ignored - * - * @return a fresh connection to fetch from the remote repository. - * @throws org.eclipse.jgit.errors.NotSupportedException - * the implementation does not support fetching. - * @throws org.eclipse.jgit.errors.TransportException - * the remote connection could not be established. - * @since 5.10 - */ - public FetchConnection openFetch(Collection<RefSpec> refSpecs, - String... additionalPatterns) - throws NotSupportedException, TransportException { - return openFetch(); - } - - /** * Begins a new connection for pushing into the remote repository. * * @return a fresh connection to push into the remote repository. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java index 5913aa4e34..820ec1a67a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java @@ -22,7 +22,6 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; -import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.Set; @@ -95,13 +94,6 @@ class TransportGitAnon extends TcpTransport implements PackTransport { return new TcpFetchConnection(); } - @Override - public FetchConnection openFetch(Collection<RefSpec> refSpecs, - String... additionalPatterns) - throws NotSupportedException, TransportException { - return new TcpFetchConnection(refSpecs, additionalPatterns); - } - /** {@inheritDoc} */ @Override public PushConnection openPush() throws TransportException { @@ -138,8 +130,7 @@ class TransportGitAnon extends TcpTransport implements PackTransport { return s; } - void service(String name, PacketLineOut pckOut, - TransferConfig.ProtocolVersion gitProtocol) + void service(String name, PacketLineOut pckOut) throws IOException { final StringBuilder cmd = new StringBuilder(); cmd.append(name); @@ -153,11 +144,6 @@ class TransportGitAnon extends TcpTransport implements PackTransport { cmd.append(uri.getPort()); } cmd.append('\0'); - if (TransferConfig.ProtocolVersion.V2.equals(gitProtocol)) { - cmd.append('\0'); - cmd.append(GitProtocolConstants.VERSION_2_REQUEST); - cmd.append('\0'); - } pckOut.writeString(cmd.toString()); pckOut.flush(); } @@ -166,11 +152,6 @@ class TransportGitAnon extends TcpTransport implements PackTransport { private Socket sock; TcpFetchConnection() throws TransportException { - this(Collections.emptyList()); - } - - TcpFetchConnection(Collection<RefSpec> refSpecs, - String... additionalPatterns) throws TransportException { super(TransportGitAnon.this); sock = openConnection(); try { @@ -181,19 +162,13 @@ class TransportGitAnon extends TcpTransport implements PackTransport { sOut = new BufferedOutputStream(sOut); init(sIn, sOut); - TransferConfig.ProtocolVersion gitProtocol = protocol; - if (gitProtocol == null) { - gitProtocol = TransferConfig.ProtocolVersion.V2; - } - service("git-upload-pack", pckOut, gitProtocol); //$NON-NLS-1$ + service("git-upload-pack", pckOut); //$NON-NLS-1$ } catch (IOException err) { close(); throw new TransportException(uri, JGitText.get().remoteHungUpUnexpectedly, err); } - if (!readAdvertisedRefs()) { - lsRefs(refSpecs, additionalPatterns); - } + readAdvertisedRefs(); } @Override @@ -226,7 +201,7 @@ class TransportGitAnon extends TcpTransport implements PackTransport { sOut = new BufferedOutputStream(sOut); init(sIn, sOut); - service("git-receive-pack", pckOut, null); //$NON-NLS-1$ + service("git-receive-pack", pckOut); //$NON-NLS-1$ } catch (IOException err) { close(); throw new TransportException(uri, diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java index 6aa2e0bedc..b9cb2484d8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java @@ -19,13 +19,11 @@ import java.io.InputStream; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.Set; import org.eclipse.jgit.errors.NoRemoteRepositoryException; @@ -146,13 +144,6 @@ public class TransportGitSsh extends SshTransport implements PackTransport { return new SshFetchConnection(); } - @Override - public FetchConnection openFetch(Collection<RefSpec> refSpecs, - String... additionalPatterns) - throws NotSupportedException, TransportException { - return new SshFetchConnection(refSpecs, additionalPatterns); - } - /** {@inheritDoc} */ @Override public PushConnection openPush() throws TransportException { @@ -205,38 +196,29 @@ public class TransportGitSsh extends SshTransport implements PackTransport { return SystemReader.getInstance().getenv("GIT_SSH") != null; //$NON-NLS-1$ } - private class ExtSession implements RemoteSession2 { - + private class ExtSession implements RemoteSession { @Override public Process exec(String command, int timeout) throws TransportException { - return exec(command, null, timeout); - } - - @Override - public Process exec(String command, Map<String, String> environment, - int timeout) throws TransportException { String ssh = SystemReader.getInstance().getenv("GIT_SSH"); //$NON-NLS-1$ boolean putty = ssh.toLowerCase(Locale.ROOT).contains("plink"); //$NON-NLS-1$ List<String> args = new ArrayList<>(); args.add(ssh); - if (putty && !ssh.toLowerCase(Locale.ROOT) - .contains("tortoiseplink")) {//$NON-NLS-1$ + if (putty + && !ssh.toLowerCase(Locale.ROOT).contains("tortoiseplink")) //$NON-NLS-1$ args.add("-batch"); //$NON-NLS-1$ - } if (0 < getURI().getPort()) { args.add(putty ? "-P" : "-p"); //$NON-NLS-1$ //$NON-NLS-2$ args.add(String.valueOf(getURI().getPort())); } - if (getURI().getUser() != null) { + if (getURI().getUser() != null) args.add(getURI().getUser() + "@" + getURI().getHost()); //$NON-NLS-1$ - } else { + else args.add(getURI().getHost()); - } args.add(command); - ProcessBuilder pb = createProcess(args, environment); + ProcessBuilder pb = createProcess(args); try { return pb.start(); } catch (IOException err) { @@ -244,13 +226,9 @@ public class TransportGitSsh extends SshTransport implements PackTransport { } } - private ProcessBuilder createProcess(List<String> args, - Map<String, String> environment) { + private ProcessBuilder createProcess(List<String> args) { ProcessBuilder pb = new ProcessBuilder(); pb.command(args); - if (environment != null) { - pb.environment().putAll(environment); - } File directory = local != null ? local.getDirectory() : null; if (directory != null) { pb.environment().put(Constants.GIT_DIR_KEY, @@ -271,31 +249,10 @@ public class TransportGitSsh extends SshTransport implements PackTransport { private StreamCopyThread errorThread; SshFetchConnection() throws TransportException { - this(Collections.emptyList()); - } - - SshFetchConnection(Collection<RefSpec> refSpecs, - String... additionalPatterns) throws TransportException { super(TransportGitSsh.this); try { - RemoteSession session = getSession(); - TransferConfig.ProtocolVersion gitProtocol = protocol; - if (gitProtocol == null) { - gitProtocol = TransferConfig.ProtocolVersion.V2; - } - if (session instanceof RemoteSession2 - && TransferConfig.ProtocolVersion.V2 - .equals(gitProtocol)) { - process = ((RemoteSession2) session).exec( - commandFor(getOptionUploadPack()), Collections - .singletonMap( - GitProtocolConstants.PROTOCOL_ENVIRONMENT_VARIABLE, - GitProtocolConstants.VERSION_2_REQUEST), - getTimeout()); - } else { - process = session.exec(commandFor(getOptionUploadPack()), - getTimeout()); - } + process = getSession().exec(commandFor(getOptionUploadPack()), + getTimeout()); final MessageWriter msg = new MessageWriter(); setMessageWriter(msg); @@ -315,9 +272,7 @@ public class TransportGitSsh extends SshTransport implements PackTransport { } try { - if (!readAdvertisedRefs()) { - lsRefs(refSpecs, additionalPatterns); - } + readAdvertisedRefs(); } catch (NoRemoteRepositoryException notFound) { final String msgs = getMessages(); checkExecFailure(process.exitValue(), getOptionUploadPack(), diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java index 77a7a46402..6768387e65 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java @@ -33,8 +33,8 @@ import static org.eclipse.jgit.util.HttpSupport.HDR_WWW_AUTHENTICATE; import static org.eclipse.jgit.util.HttpSupport.METHOD_GET; import static org.eclipse.jgit.util.HttpSupport.METHOD_POST; -import java.io.BufferedInputStream; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -339,15 +339,11 @@ public class TransportHttp extends HttpTransport implements WalkTransport, @SuppressWarnings("resource") // Closed by caller private FetchConnection getConnection(HttpConnection c, InputStream in, - String service, Collection<RefSpec> refSpecs, - String... additionalPatterns) throws IOException { + String service) throws IOException { BaseConnection f; if (isSmartHttp(c, service)) { - InputStream withMark = in.markSupported() ? in - : new BufferedInputStream(in); - readSmartHeaders(withMark, service); - f = new SmartHttpFetchConnection(withMark, refSpecs, - additionalPatterns); + readSmartHeaders(in, service); + f = new SmartHttpFetchConnection(in); } else { // Assume this server doesn't support smart HTTP fetch // and fall back on dumb object walking. @@ -361,23 +357,11 @@ public class TransportHttp extends HttpTransport implements WalkTransport, @Override public FetchConnection openFetch() throws TransportException, NotSupportedException { - return openFetch(Collections.emptyList()); - } - - @Override - public FetchConnection openFetch(Collection<RefSpec> refSpecs, - String... additionalPatterns) - throws NotSupportedException, TransportException { final String service = SVC_UPLOAD_PACK; try { - TransferConfig.ProtocolVersion gitProtocol = protocol; - if (gitProtocol == null) { - gitProtocol = TransferConfig.ProtocolVersion.V2; - } - HttpConnection c = connect(service, gitProtocol); + final HttpConnection c = connect(service); try (InputStream in = openInputStream(c)) { - return getConnection(c, in, service, refSpecs, - additionalPatterns); + return getConnection(c, in, service); } } catch (NotSupportedException | TransportException err) { throw err; @@ -472,9 +456,8 @@ public class TransportHttp extends HttpTransport implements WalkTransport, private PushConnection smartPush(String service, HttpConnection c, InputStream in) throws IOException, TransportException { - BufferedInputStream inBuf = new BufferedInputStream(in); - readSmartHeaders(inBuf, service); - SmartHttpPushConnection p = new SmartHttpPushConnection(inBuf); + readSmartHeaders(in, service); + SmartHttpPushConnection p = new SmartHttpPushConnection(in); p.setPeerUserAgent(c.getHeaderField(HttpSupport.HDR_SERVER)); return p; } @@ -511,12 +494,6 @@ public class TransportHttp extends HttpTransport implements WalkTransport, private HttpConnection connect(String service) throws TransportException, NotSupportedException { - return connect(service, null); - } - - private HttpConnection connect(String service, - TransferConfig.ProtocolVersion protocolVersion) - throws TransportException, NotSupportedException { URL u = getServiceURL(service); int authAttempts = 1; int redirects = 0; @@ -530,11 +507,6 @@ public class TransportHttp extends HttpTransport implements WalkTransport, } else { conn.setRequestProperty(HDR_ACCEPT, "*/*"); //$NON-NLS-1$ } - if (TransferConfig.ProtocolVersion.V2.equals(protocolVersion)) { - conn.setRequestProperty( - GitProtocolConstants.PROTOCOL_HEADER, - GitProtocolConstants.VERSION_2_REQUEST); - } final int status = HttpSupport.response(conn); processResponseCookies(conn); switch (status) { @@ -1176,37 +1148,20 @@ public class TransportHttp extends HttpTransport implements WalkTransport, private void readSmartHeaders(InputStream in, String service) throws IOException { - // A smart protocol V0 reply will have a '#' after the first 4 bytes, - // but a dumb reply cannot contain a '#' until after byte 41. Do a + // A smart reply will have a '#' after the first 4 bytes, but + // a dumb reply cannot contain a '#' until after byte 41. Do a // quick check to make sure its a smart reply before we parse // as a pkt-line stream. // - // There appears to be a confusion about this in protocol V2. Github - // sends the # service line as a git (not http) header also when - // protocol V2 is used. Gitlab also does so. JGit's UploadPack doesn't, - // and thus Gerrit also does not. - final byte[] magic = new byte[14]; - if (!in.markSupported()) { - throw new TransportException(uri, - JGitText.get().inputStreamMustSupportMark); - } - in.mark(14); + final byte[] magic = new byte[5]; IO.readFully(in, magic, 0, magic.length); - // Did we get 000dversion 2 or similar? (Canonical is 000eversion 2\n, - // but JGit and thus Gerrit omits the \n.) - if (Arrays.equals(Arrays.copyOfRange(magic, 4, 11), - "version".getBytes()) && magic[12] >= '1' && magic[12] <= '9') { //$NON-NLS-1$ - // It's a smart server doing version 1 or greater, but not sending - // the # service line header. Don't consume the version line. - in.reset(); - return; - } if (magic[4] != '#') { throw new TransportException(uri, MessageFormat.format( JGitText.get().expectedPktLineWithService, RawParseUtils.decode(magic))); } - in.reset(); - final PacketLineIn pckIn = new PacketLineIn(in); + + final PacketLineIn pckIn = new PacketLineIn(new UnionInputStream( + new ByteArrayInputStream(magic), in)); final String exp = "# service=" + service; //$NON-NLS-1$ final String act = pckIn.readString(); if (!exp.equals(act)) { @@ -1372,24 +1327,12 @@ public class TransportHttp extends HttpTransport implements WalkTransport, SmartHttpFetchConnection(InputStream advertisement) throws TransportException { - this(advertisement, Collections.emptyList()); - } - - SmartHttpFetchConnection(InputStream advertisement, - Collection<RefSpec> refSpecs, String... additionalPatterns) - throws TransportException { super(TransportHttp.this); statelessRPC = true; init(advertisement, DisabledOutputStream.INSTANCE); outNeedsEnd = false; - if (!readAdvertisedRefs()) { - // Must be protocol V2 - LongPollService service = new LongPollService(SVC_UPLOAD_PACK, - getProtocolVersion()); - init(service.getInputStream(), service.getOutputStream()); - lsRefs(refSpecs, additionalPatterns); - } + readAdvertisedRefs(); } @Override @@ -1397,8 +1340,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, final Collection<Ref> want, final Set<ObjectId> have, final OutputStream outputStream) throws TransportException { try { - svc = new MultiRequestService(SVC_UPLOAD_PACK, - getProtocolVersion()); + svc = new MultiRequestService(SVC_UPLOAD_PACK); init(svc.getInputStream(), svc.getOutputStream()); super.doFetch(monitor, want, have, outputStream); } finally { @@ -1427,8 +1369,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, protected void doPush(final ProgressMonitor monitor, final Map<String, RemoteRefUpdate> refUpdates, OutputStream outputStream) throws TransportException { - final Service svc = new MultiRequestService(SVC_RECEIVE_PACK, - getProtocolVersion()); + final Service svc = new MultiRequestService(SVC_RECEIVE_PACK); init(svc.getInputStream(), svc.getOutputStream()); super.doPush(monitor, refUpdates, outputStream); } @@ -1448,14 +1389,10 @@ public class TransportHttp extends HttpTransport implements WalkTransport, protected final HttpExecuteStream execute; - protected final TransferConfig.ProtocolVersion protocolVersion; - final UnionInputStream in; - Service(String serviceName, - TransferConfig.ProtocolVersion protocolVersion) { + Service(String serviceName) { this.serviceName = serviceName; - this.protocolVersion = protocolVersion; this.requestType = "application/x-" + serviceName + "-request"; //$NON-NLS-1$ //$NON-NLS-2$ this.responseType = "application/x-" + serviceName + "-result"; //$NON-NLS-1$ //$NON-NLS-2$ @@ -1471,10 +1408,6 @@ public class TransportHttp extends HttpTransport implements WalkTransport, conn.setDoOutput(true); conn.setRequestProperty(HDR_CONTENT_TYPE, requestType); conn.setRequestProperty(HDR_ACCEPT, responseType); - if (TransferConfig.ProtocolVersion.V2.equals(protocolVersion)) { - conn.setRequestProperty(GitProtocolConstants.PROTOCOL_HEADER, - GitProtocolConstants.VERSION_2_REQUEST); - } } void sendRequest() throws IOException { @@ -1730,9 +1663,8 @@ public class TransportHttp extends HttpTransport implements WalkTransport, class MultiRequestService extends Service { boolean finalRequest; - MultiRequestService(String serviceName, - TransferConfig.ProtocolVersion protocolVersion) { - super(serviceName, protocolVersion); + MultiRequestService(String serviceName) { + super(serviceName); } /** Keep opening send-receive pairs to the given URI. */ @@ -1769,10 +1701,11 @@ public class TransportHttp extends HttpTransport implements WalkTransport, /** Service for maintaining a single long-poll connection. */ class LongPollService extends Service { - - LongPollService(String serviceName, - TransferConfig.ProtocolVersion protocolVersion) { - super(serviceName, protocolVersion); + /** + * @param serviceName + */ + LongPollService(String serviceName) { + super(serviceName); } /** Only open one send-receive request. */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java index 89cb65e9ac..403f98d869 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java @@ -20,7 +20,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Set; @@ -154,17 +153,11 @@ class TransportLocal extends Transport implements PackTransport { /** {@inheritDoc} */ @Override public FetchConnection openFetch() throws TransportException { - return openFetch(Collections.emptyList()); - } - - @Override - public FetchConnection openFetch(Collection<RefSpec> refSpecs, - String... additionalPatterns) throws TransportException { final String up = getOptionUploadPack(); if (!"git-upload-pack".equals(up) //$NON-NLS-1$ - && !"git upload-pack".equals(up)) {//$NON-NLS-1$ - return new ForkLocalFetchConnection(refSpecs, additionalPatterns); - } + && !"git upload-pack".equals(up)) //$NON-NLS-1$ + return new ForkLocalFetchConnection(); + UploadPackFactory<Void> upf = (Void req, Repository db) -> createUploadPack(db); return new InternalFetchConnection<>(this, upf, null, openRepo()); @@ -200,23 +193,6 @@ class TransportLocal extends Transport implements PackTransport { */ protected Process spawn(String cmd) throws TransportException { - return spawn(cmd, null); - } - - /** - * Spawn process - * - * @param cmd - * command - * @param protocolVersion - * to use - * @return a {@link java.lang.Process} object. - * @throws org.eclipse.jgit.errors.TransportException - * if any. - */ - private Process spawn(String cmd, - TransferConfig.ProtocolVersion protocolVersion) - throws TransportException { try { String[] args = { "." }; //$NON-NLS-1$ ProcessBuilder proc = local.getFS().runInShell(cmd, args); @@ -232,10 +208,7 @@ class TransportLocal extends Transport implements PackTransport { env.remove("GIT_GRAFT_FILE"); //$NON-NLS-1$ env.remove("GIT_INDEX_FILE"); //$NON-NLS-1$ env.remove("GIT_NO_REPLACE_OBJECTS"); //$NON-NLS-1$ - if (TransferConfig.ProtocolVersion.V2.equals(protocolVersion)) { - env.put(GitProtocolConstants.PROTOCOL_ENVIRONMENT_VARIABLE, - GitProtocolConstants.VERSION_2_REQUEST); - } + return proc.start(); } catch (IOException err) { throw new TransportException(uri, err.getMessage(), err); @@ -248,21 +221,12 @@ class TransportLocal extends Transport implements PackTransport { private Thread errorReaderThread; ForkLocalFetchConnection() throws TransportException { - this(Collections.emptyList()); - } - - ForkLocalFetchConnection(Collection<RefSpec> refSpecs, - String... additionalPatterns) throws TransportException { super(TransportLocal.this); final MessageWriter msg = new MessageWriter(); setMessageWriter(msg); - TransferConfig.ProtocolVersion gitProtocol = protocol; - if (gitProtocol == null) { - gitProtocol = TransferConfig.ProtocolVersion.V2; - } - uploadPack = spawn(getOptionUploadPack(), gitProtocol); + uploadPack = spawn(getOptionUploadPack()); final InputStream upErr = uploadPack.getErrorStream(); errorReaderThread = new StreamCopyThread(upErr, msg.getRawStream()); @@ -275,9 +239,7 @@ class TransportLocal extends Transport implements PackTransport { upOut = new BufferedOutputStream(upOut); init(upIn, upOut); - if (!readAdvertisedRefs()) { - lsRefs(refSpecs, additionalPatterns); - } + readAdvertisedRefs(); } @Override 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 9eefea0c48..1242ef1b4a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -33,7 +33,6 @@ import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDEBAND_AL import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND_64K; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_THIN_PACK; -import static org.eclipse.jgit.transport.GitProtocolConstants.VERSION_2_REQUEST; import static org.eclipse.jgit.util.RefMap.toRefMap; import java.io.ByteArrayOutputStream; @@ -710,7 +709,7 @@ public class UploadPack { * @since 5.0 */ public void setExtraParameters(Collection<String> params) { - this.clientRequestedV2 = params.contains(VERSION_2_REQUEST); + this.clientRequestedV2 = params.contains("version=2"); //$NON-NLS-1$ } /** @@ -1195,8 +1194,7 @@ public class UploadPack { new PacketLineOut(NullOutputStream.INSTANCE), accumulator); } else { - pckOut.writeString( - GitProtocolConstants.SECTION_ACKNOWLEDGMENTS + '\n'); + pckOut.writeString("acknowledgments\n"); //$NON-NLS-1$ for (ObjectId id : req.getPeerHas()) { if (walk.getObjectReader().has(id)) { pckOut.writeString("ACK " + id.getName() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -1245,8 +1243,7 @@ public class UploadPack { if (!pckOut.isUsingSideband()) { // sendPack will write "packfile\n" for us if sideband-all is used. // But sideband-all is not used, so we have to write it ourselves. - pckOut.writeString( - GitProtocolConstants.SECTION_PACKFILE + '\n'); + pckOut.writeString("packfile\n"); //$NON-NLS-1$ } accumulator.timeNegotiating = Duration @@ -2330,8 +2327,7 @@ public class UploadPack { // for us if provided a PackfileUriConfig. In this case, we // are not providing a PackfileUriConfig, so we have to // write this line ourselves. - pckOut.writeString( - GitProtocolConstants.SECTION_PACKFILE + '\n'); + pckOut.writeString("packfile\n"); //$NON-NLS-1$ } } pw.writePack(pm, NullProgressMonitor.INSTANCE, packOut); |