Support insteadOf and pushInsteadOf URL replacement

Bug: 346873
Change-Id: I4116328f93f411da56a633bc32fd064b2ac083f2
Signed-off-by: Chris Aniszczyk <zx@twitter.com>
This commit is contained in:
Kevin Sawicki 2012-03-01 17:37:41 -08:00 committed by Chris Aniszczyk
parent db29665e64
commit 9908c203a5
2 changed files with 104 additions and 2 deletions

View File

@ -50,6 +50,7 @@
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.List;
import org.eclipse.jgit.errors.ConfigInvalidException;
@ -455,4 +456,66 @@ public void testSaveTimeout() throws Exception {
+ "\tfetch = +refs/heads/*:refs/remotes/origin/*\n"
+ "\ttimeout = 60\n");
}
@Test
public void noInsteadOf() throws Exception {
config.setString("remote", "origin", "url", "short:project.git");
config.setString("url", "https://server/repos/", "name", "short:");
RemoteConfig rc = new RemoteConfig(config, "origin");
assertFalse(rc.getURIs().isEmpty());
assertEquals("short:project.git", rc.getURIs().get(0).toASCIIString());
}
@Test
public void singleInsteadOf() throws Exception {
config.setString("remote", "origin", "url", "short:project.git");
config.setString("url", "https://server/repos/", "insteadOf", "short:");
RemoteConfig rc = new RemoteConfig(config, "origin");
assertFalse(rc.getURIs().isEmpty());
assertEquals("https://server/repos/project.git", rc.getURIs().get(0)
.toASCIIString());
}
@Test
public void multipleInsteadOf() throws Exception {
config.setString("remote", "origin", "url", "prefixproject.git");
config.setStringList("url", "https://server/repos/", "insteadOf",
Arrays.asList("pre", "prefix", "pref", "perf"));
RemoteConfig rc = new RemoteConfig(config, "origin");
assertFalse(rc.getURIs().isEmpty());
assertEquals("https://server/repos/project.git", rc.getURIs().get(0)
.toASCIIString());
}
@Test
public void noPushInsteadOf() throws Exception {
config.setString("remote", "origin", "pushurl", "short:project.git");
config.setString("url", "https://server/repos/", "name", "short:");
RemoteConfig rc = new RemoteConfig(config, "origin");
assertFalse(rc.getPushURIs().isEmpty());
assertEquals("short:project.git", rc.getPushURIs().get(0)
.toASCIIString());
}
@Test
public void singlePushInsteadOf() throws Exception {
config.setString("remote", "origin", "pushurl", "short:project.git");
config.setString("url", "https://server/repos/", "pushInsteadOf",
"short:");
RemoteConfig rc = new RemoteConfig(config, "origin");
assertFalse(rc.getPushURIs().isEmpty());
assertEquals("https://server/repos/project.git", rc.getPushURIs()
.get(0).toASCIIString());
}
@Test
public void multiplePushInsteadOf() throws Exception {
config.setString("remote", "origin", "pushurl", "prefixproject.git");
config.setStringList("url", "https://server/repos/", "pushInsteadOf",
Arrays.asList("pre", "prefix", "pref", "perf"));
RemoteConfig rc = new RemoteConfig(config, "origin");
assertFalse(rc.getPushURIs().isEmpty());
assertEquals("https://server/repos/project.git", rc.getPushURIs()
.get(0).toASCIIString());
}
}

View File

@ -49,7 +49,10 @@
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.jgit.lib.Config;
@ -84,6 +87,10 @@ public class RemoteConfig implements Serializable {
private static final String KEY_TIMEOUT = "timeout";
private static final String KEY_INSTEADOF = "insteadof";
private static final String KEY_PUSHINSTEADOF = "pushinsteadof";
private static final boolean DEFAULT_MIRROR = false;
/** Default value for {@link #getUploadPack()} if not specified. */
@ -161,14 +168,17 @@ public RemoteConfig(final Config rc, final String remoteName)
String val;
vlst = rc.getStringList(SECTION, name, KEY_URL);
Map<String, String> insteadOf = getReplacements(rc, KEY_INSTEADOF);
uris = new ArrayList<URIish>(vlst.length);
for (final String s : vlst)
uris.add(new URIish(s));
uris.add(new URIish(replaceUri(s, insteadOf)));
Map<String, String> pushInsteadOf = getReplacements(rc,
KEY_PUSHINSTEADOF);
vlst = rc.getStringList(SECTION, name, KEY_PUSHURL);
pushURIs = new ArrayList<URIish>(vlst.length);
for (final String s : vlst)
pushURIs.add(new URIish(s));
pushURIs.add(new URIish(replaceUri(s, pushInsteadOf)));
vlst = rc.getStringList(SECTION, name, KEY_FETCH);
fetch = new ArrayList<RefSpec>(vlst.length);
@ -260,6 +270,35 @@ private void unset(final Config rc, final String key) {
rc.unset(SECTION, getName(), key);
}
private Map<String, String> getReplacements(final Config config,
final String keyName) {
final Map<String, String> replacements = new HashMap<String, String>();
for (String url : config.getSubsections(KEY_URL))
for (String insteadOf : config.getStringList(KEY_URL, url, keyName))
replacements.put(insteadOf, url);
return replacements;
}
private String replaceUri(final String uri,
final Map<String, String> replacements) {
if (replacements.isEmpty())
return uri;
Entry<String, String> match = null;
for (Entry<String, String> replacement : replacements.entrySet()) {
// Ignore current entry if not longer than previous match
if (match != null
&& match.getKey().length() > replacement.getKey().length())
continue;
if (!uri.startsWith(replacement.getKey()))
continue;
match = replacement;
}
if (match != null)
return match.getValue() + uri.substring(match.getKey().length());
else
return uri;
}
/**
* Get the local name this remote configuration is recognized as.
*