]> source.dussan.org Git - jgit.git/commitdiff
Support insteadOf and pushInsteadOf URL replacement 18/5218/3
authorKevin Sawicki <kevin@github.com>
Fri, 2 Mar 2012 01:37:41 +0000 (17:37 -0800)
committerChris Aniszczyk <zx@twitter.com>
Tue, 6 Mar 2012 04:46:26 +0000 (20:46 -0800)
Bug: 346873
Change-Id: I4116328f93f411da56a633bc32fd064b2ac083f2
Signed-off-by: Chris Aniszczyk <zx@twitter.com>
org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RemoteConfigTest.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java

index 03a6c019ed7136150860a85b0f9f7da10001575f..0cada5c7ee0c3a88e7775571c48a341f3ee17aca 100644 (file)
@@ -50,6 +50,7 @@ import static org.junit.Assert.assertNotNull;
 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 class RemoteConfigTest {
                                + "\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());
+       }
 }
index 3df56c696d624970109edbc62494ffaeba22a8f5..f75ac703a3c3fdc6989d5ab9092600d8429e8b45 100644 (file)
@@ -49,7 +49,10 @@ import java.io.Serializable;
 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 class RemoteConfig implements Serializable {
                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 @@ public class RemoteConfig implements Serializable {
                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.
         *