diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java index 24b5ad7da..6ed2c215e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java @@ -1120,6 +1120,7 @@ public void relative() { testRelative("a/", "a/b", "b"); testRelative("/a/b/c", "/b/c", "../../b/c"); testRelative("/abc", "bcd", "bcd"); + testRelative("abc", "def", "def"); testRelative("abc", "/bcd", "/bcd"); testRelative("http://a", "a/b", "a/b"); testRelative("http://base.com/a/", "http://child.com/a/b", "http://child.com/a/b"); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java index 6669c9cfb..1de8a0be2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java @@ -731,7 +731,9 @@ private void addSubmodule(String url, String path, String revision, * Returns the child if either base or child is not a bare path. This provides a missing feature in * java.net.URI (see http://bugs.java.com/view_bug.do?bug_id=6226081). */ + private static final String SLASH = "/"; //$NON-NLS-1$ static URI relativize(URI current, URI target) { + // We only handle bare paths for now. if (!target.toString().equals(target.getPath())) { return target; @@ -744,37 +746,46 @@ static URI relativize(URI current, URI target) { String dest = target.normalize().getPath(); // TODO(hanwen): maybe (absolute, relative) should throw an exception. - if (cur.startsWith("/") != dest.startsWith("/")) { //$NON-NLS-1$//$NON-NLS-2$ + if (cur.startsWith(SLASH) != dest.startsWith(SLASH)) { return target; } - while (cur.startsWith("/")) { //$NON-NLS-1$ + while (cur.startsWith(SLASH)) { cur = cur.substring(1); } - while (dest.startsWith("/")) { //$NON-NLS-1$ + while (dest.startsWith(SLASH)) { dest = dest.substring(1); } - if (!cur.endsWith("/")) { //$NON-NLS-1$ + if (cur.indexOf('/') == -1 || dest.indexOf('/') == -1) { + // Avoid having to special-casing in the next two ifs. + String prefix = "prefix/"; //$NON-NLS-1$ + cur = prefix + cur; + dest = prefix + dest; + } + + if (!cur.endsWith(SLASH)) { // The current file doesn't matter. - cur = cur.substring(0, cur.lastIndexOf('/')); + int lastSlash = cur.lastIndexOf('/'); + cur = cur.substring(0, lastSlash); } String destFile = ""; //$NON-NLS-1$ - if (!dest.endsWith("/")) { //$NON-NLS-1$ + if (!dest.endsWith(SLASH)) { // We always have to provide the destination file. - destFile = dest.substring(dest.lastIndexOf('/') + 1, dest.length()); + int lastSlash = dest.lastIndexOf('/'); + destFile = dest.substring(lastSlash + 1, dest.length()); dest = dest.substring(0, dest.lastIndexOf('/')); } - String[] cs = cur.split("/"); //$NON-NLS-1$ - String[] ds = dest.split("/"); //$NON-NLS-1$ + String[] cs = cur.split(SLASH); + String[] ds = dest.split(SLASH); int common = 0; while (common < cs.length && common < ds.length && cs[common].equals(ds[common])) { common++; } - StringJoiner j = new StringJoiner("/"); //$NON-NLS-1$ + StringJoiner j = new StringJoiner(SLASH); for (int i = common; i < cs.length; i++) { j.add(".."); //$NON-NLS-1$ }