Fix handling of pushInsteadOf

According to [1], pushInsteadOf is

1. applied to the uris, not to the pushUris
2. ignored if a remote has an explicit pushUri

JGit applied it only to the pushUris. As a result, pushInsteadOf was
ignored for remotes having only a uri, but no pushUri.

This commit implements (1) if there are no pushUris. I did not dare
implement (2) because:

* there are explicit tests for it that expect that pushInsteadOf gets
  applied to existing pushUrls, and
* people may actually use and rely on this JGit behavior.

[1] https://git-scm.com/docs/git-config

Bug: 393170
Change-Id: I6dacbf1768a105190c2a8c5272e7880c1c9c943a
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RemoteConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RemoteConfigTest.java
index 0cada5c..b64c134 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RemoteConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RemoteConfigTest.java
@@ -51,6 +51,7 @@
 import static org.junit.Assert.assertTrue;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -518,4 +519,17 @@
 		assertEquals("https://server/repos/project.git", rc.getPushURIs()
 				.get(0).toASCIIString());
 	}
+
+	@Test
+	public void pushInsteadOfNoPushUrl() throws Exception {
+		config.setString("remote", "origin", "url",
+				"http://git.eclipse.org/gitroot/jgit/jgit");
+		config.setStringList("url", "ssh://someone@git.eclipse.org:29418/",
+				"pushInsteadOf",
+				Collections.singletonList("http://git.eclipse.org/gitroot/"));
+		RemoteConfig rc = new RemoteConfig(config, "origin");
+		assertFalse(rc.getPushURIs().isEmpty());
+		assertEquals("ssh://someone@git.eclipse.org:29418/jgit/jgit",
+				rc.getPushURIs().get(0).toASCIIString());
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
index d91684e..f192be1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
@@ -170,16 +170,26 @@
 		vlst = rc.getStringList(SECTION, name, KEY_URL);
 		Map<String, String> insteadOf = getReplacements(rc, KEY_INSTEADOF);
 		uris = new ArrayList<>(vlst.length);
-		for (final String s : vlst)
+		for (final String s : vlst) {
 			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<>(vlst.length);
-		for (final String s : vlst)
+		String[] plst = rc.getStringList(SECTION, name, KEY_PUSHURL);
+		pushURIs = new ArrayList<>(plst.length);
+		for (final String s : plst) {
 			pushURIs.add(new URIish(replaceUri(s, pushInsteadOf)));
-
+		}
+		if (pushURIs.isEmpty() && !pushInsteadOf.isEmpty()) {
+			// Would default to the uris. If we have pushinsteadof, we must
+			// supply rewritten push uris.
+			for (String s : vlst) {
+				String replaced = replaceUri(s, pushInsteadOf);
+				if (!s.equals(replaced)) {
+					pushURIs.add(new URIish(replaced));
+				}
+			}
+		}
 		vlst = rc.getStringList(SECTION, name, KEY_FETCH);
 		fetch = new ArrayList<>(vlst.length);
 		for (final String s : vlst)