diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/RepoTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/RepoTest.java
index 72e85fa64..bfff14d9d 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/RepoTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/RepoTest.java
@@ -43,6 +43,7 @@
package org.eclipse.jgit.pgm;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.BufferedReader;
@@ -57,17 +58,47 @@ import org.junit.Before;
import org.junit.Test;
public class RepoTest extends CLIRepositoryTestCase {
- private Repository remoteDb;
+ private Repository defaultDb;
+ private Repository notDefaultDb;
+ private Repository groupADb;
+ private Repository groupBDb;
+
+ private String rootUri;
+ private String defaultUri;
+ private String notDefaultUri;
+ private String groupAUri;
+ private String groupBUri;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
- remoteDb = createWorkRepository();
- Git git = new Git(remoteDb);
- JGitTestUtil.writeTrashFile(remoteDb, "hello.txt", "world");
+
+ defaultDb = createWorkRepository();
+ Git git = new Git(defaultDb);
+ JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "world");
git.add().addFilepattern("hello.txt").call();
git.commit().setMessage("Initial commit").call();
+
+ notDefaultDb = createWorkRepository();
+ git = new Git(notDefaultDb);
+ JGitTestUtil.writeTrashFile(notDefaultDb, "world.txt", "hello");
+ git.add().addFilepattern("world.txt").call();
+ git.commit().setMessage("Initial commit").call();
+
+ groupADb = createWorkRepository();
+ git = new Git(groupADb);
+ JGitTestUtil.writeTrashFile(groupADb, "a.txt", "world");
+ git.add().addFilepattern("a.txt").call();
+ git.commit().setMessage("Initial commit").call();
+
+ groupBDb = createWorkRepository();
+ git = new Git(groupBDb);
+ JGitTestUtil.writeTrashFile(groupBDb, "b.txt", "world");
+ git.add().addFilepattern("b.txt").call();
+ git.commit().setMessage("Initial commit").call();
+
+ resolveRelativeUris();
}
@Test
@@ -77,20 +108,59 @@ public class RepoTest extends CLIRepositoryTestCase {
.append("")
.append("")
.append("")
- .append("")
+ .append("")
+ .append("")
+ .append("")
+ .append("")
.append("");
writeTrashFile("manifest.xml", xmlContent.toString());
StringBuilder cmd = new StringBuilder("git repo --base-uri=\"")
- .append(remoteDb.getDirectory().toURI().toString())
- .append("\" \"")
+ .append(rootUri)
+ .append("\" --groups=\"all,-a\" \"")
.append(db.getWorkTree().getAbsolutePath())
.append("/manifest.xml\"");
execute(cmd.toString());
- File hello = new File(db.getWorkTree(), "foo/hello.txt");
- assertTrue("submodule was checked out.", hello.exists());
- BufferedReader reader = new BufferedReader(new FileReader(hello));
- String content = reader.readLine();
- reader.close();
- assertEquals("submodule content is as expected.", "world", content);
+
+ File file = new File(db.getWorkTree(), "foo/hello.txt");
+ assertFalse("\"all,-a\" doesn't have foo", file.exists());
+ file = new File(db.getWorkTree(), "bar/world.txt");
+ assertTrue("\"all,-a\" has bar", file.exists());
+ file = new File(db.getWorkTree(), "a/a.txt");
+ assertFalse("\"all,-a\" doesn't have a", file.exists());
+ file = new File(db.getWorkTree(), "b/b.txt");
+ assertTrue("\"all,-a\" has have b", file.exists());
+ }
+
+ private void resolveRelativeUris() {
+ // Find the longest common prefix ends with "/" as rootUri.
+ defaultUri = defaultDb.getDirectory().toURI().toString();
+ notDefaultUri = notDefaultDb.getDirectory().toURI().toString();
+ groupAUri = groupADb.getDirectory().toURI().toString();
+ groupBUri = groupBDb.getDirectory().toURI().toString();
+ int start = 0;
+ while (start <= defaultUri.length()) {
+ int newStart = defaultUri.indexOf('/', start + 1);
+ String prefix = defaultUri.substring(0, newStart);
+ if (!notDefaultUri.startsWith(prefix) ||
+ !groupAUri.startsWith(prefix) ||
+ !groupBUri.startsWith(prefix)) {
+ start++;
+ rootUri = defaultUri.substring(0, start);
+ defaultUri = defaultUri.substring(start);
+ notDefaultUri = notDefaultUri.substring(start);
+ groupAUri = groupAUri.substring(start);
+ groupBUri = groupBUri.substring(start);
+ return;
+ }
+ start = newStart;
+ }
}
}
diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
index 9b874c735..7d5b87fdd 100644
--- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
+++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
@@ -278,6 +278,7 @@ usage_forceCheckout=when switching branches, proceed even if the index or the wo
usage_forceCreateBranchEvenExists=force create branch even exists
usage_forceReplacingAnExistingTag=force replacing an existing tag
usage_getAndSetOptions=Get and set repository or global options
+usage_groups=Restrict manifest projects to ones with specified group(s), use "-" for excluding [default|all|G1,G2,G3|G4,-G5,-G6]
usage_hostnameOrIpToListenOn=hostname (or ip) to listen on
usage_indexFileFormatToCreate=index file format to create
usage_ignoreWhitespace=ignore all whitespace
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java
index 9d18cec76..9b191e679 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java
@@ -52,6 +52,9 @@ class Repo extends TextBuiltin {
@Option(name = "--base-uri", aliases = { "-u" }, usage = "usage_baseUri")
private String uri;
+ @Option(name = "--groups", aliases = { "-g" }, usage = "usage_groups")
+ private String groups = "default"; //$NON-NLS-1$
+
@Argument(required = true, usage = "usage_pathToXml")
private String path;
@@ -60,6 +63,7 @@ class Repo extends TextBuiltin {
new RepoCommand(db)
.setURI(uri)
.setPath(path)
+ .setGroups(groups)
.call();
}
}
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 66067fc9a..9fc59c578 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
@@ -43,6 +43,7 @@
package org.eclipse.jgit.gitrepo;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.BufferedReader;
@@ -57,16 +58,45 @@ import org.junit.Test;
public class RepoCommandTest extends RepositoryTestCase {
- private Repository remoteDb;
+ private Repository defaultDb;
+ private Repository notDefaultDb;
+ private Repository groupADb;
+ private Repository groupBDb;
+
+ private String rootUri;
+ private String defaultUri;
+ private String notDefaultUri;
+ private String groupAUri;
+ private String groupBUri;
public void setUp() throws Exception {
super.setUp();
- remoteDb = createWorkRepository();
- Git git = new Git(remoteDb);
- JGitTestUtil.writeTrashFile(remoteDb, "hello.txt", "world");
+ defaultDb = createWorkRepository();
+ Git git = new Git(defaultDb);
+ JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "world");
git.add().addFilepattern("hello.txt").call();
git.commit().setMessage("Initial commit").call();
+
+ notDefaultDb = createWorkRepository();
+ git = new Git(notDefaultDb);
+ JGitTestUtil.writeTrashFile(notDefaultDb, "world.txt", "hello");
+ git.add().addFilepattern("world.txt").call();
+ git.commit().setMessage("Initial commit").call();
+
+ groupADb = createWorkRepository();
+ git = new Git(groupADb);
+ JGitTestUtil.writeTrashFile(groupADb, "a.txt", "world");
+ git.add().addFilepattern("a.txt").call();
+ git.commit().setMessage("Initial commit").call();
+
+ groupBDb = createWorkRepository();
+ git = new Git(groupBDb);
+ JGitTestUtil.writeTrashFile(groupBDb, "b.txt", "world");
+ git.add().addFilepattern("b.txt").call();
+ git.commit().setMessage("Initial commit").call();
+
+ resolveRelativeUris();
}
@Test
@@ -76,12 +106,14 @@ public class RepoCommandTest extends RepositoryTestCase {
.append("")
.append("")
.append("")
- .append("")
+ .append("")
.append("");
writeTrashFile("manifest.xml", xmlContent.toString());
RepoCommand command = new RepoCommand(db);
command.setPath(db.getWorkTree().getAbsolutePath() + "/manifest.xml")
- .setURI(remoteDb.getDirectory().toURI().toString())
+ .setURI(rootUri)
.call();
File hello = new File(db.getWorkTree(), "foo/hello.txt");
assertTrue("submodule was checked out", hello.exists());
@@ -90,4 +122,84 @@ public class RepoCommandTest extends RepositoryTestCase {
reader.close();
assertEquals("submodule content is as expected.", "world", content);
}
+
+ @Test
+ public void testRepoManifestGroups() throws Exception {
+ StringBuilder xmlContent = new StringBuilder();
+ xmlContent.append("\n")
+ .append("")
+ .append("")
+ .append("")
+ .append("")
+ .append("")
+ .append("")
+ .append("")
+ .append("");
+
+ // default should have foo, a & b
+ Repository localDb = createWorkRepository();
+ JGitTestUtil.writeTrashFile(localDb, "manifest.xml", xmlContent.toString());
+ RepoCommand command = new RepoCommand(localDb);
+ command.setPath(localDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
+ .setURI(rootUri)
+ .call();
+ File file = new File(localDb.getWorkTree(), "foo/hello.txt");
+ assertTrue("default has foo", file.exists());
+ file = new File(localDb.getWorkTree(), "bar/world.txt");
+ assertFalse("default doesn't have bar", file.exists());
+ file = new File(localDb.getWorkTree(), "a/a.txt");
+ assertTrue("default has a", file.exists());
+ file = new File(localDb.getWorkTree(), "b/b.txt");
+ assertTrue("default has b", file.exists());
+
+ // all,-a should have bar & b
+ localDb = createWorkRepository();
+ JGitTestUtil.writeTrashFile(localDb, "manifest.xml", xmlContent.toString());
+ command = new RepoCommand(localDb);
+ command.setPath(localDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
+ .setURI(rootUri)
+ .setGroups("all,-a")
+ .call();
+ file = new File(localDb.getWorkTree(), "foo/hello.txt");
+ assertFalse("\"all,-a\" doesn't have foo", file.exists());
+ file = new File(localDb.getWorkTree(), "bar/world.txt");
+ assertTrue("\"all,-a\" has bar", file.exists());
+ file = new File(localDb.getWorkTree(), "a/a.txt");
+ assertFalse("\"all,-a\" doesn't have a", file.exists());
+ file = new File(localDb.getWorkTree(), "b/b.txt");
+ assertTrue("\"all,-a\" has have b", file.exists());
+ }
+
+ private void resolveRelativeUris() {
+ // Find the longest common prefix ends with "/" as rootUri.
+ defaultUri = defaultDb.getDirectory().toURI().toString();
+ notDefaultUri = notDefaultDb.getDirectory().toURI().toString();
+ groupAUri = groupADb.getDirectory().toURI().toString();
+ groupBUri = groupBDb.getDirectory().toURI().toString();
+ int start = 0;
+ while (start <= defaultUri.length()) {
+ int newStart = defaultUri.indexOf('/', start + 1);
+ String prefix = defaultUri.substring(0, newStart);
+ if (!notDefaultUri.startsWith(prefix) ||
+ !groupAUri.startsWith(prefix) ||
+ !groupBUri.startsWith(prefix)) {
+ start++;
+ rootUri = defaultUri.substring(0, start);
+ defaultUri = defaultUri.substring(start);
+ notDefaultUri = notDefaultUri.substring(start);
+ groupAUri = groupAUri.substring(start);
+ groupBUri = groupBUri.substring(start);
+ return;
+ }
+ start = newStart;
+ }
+ }
}
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 5ae134d4f..a7467c83d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
@@ -48,9 +48,12 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.eclipse.jgit.api.GitCommand;
import org.eclipse.jgit.api.SubmoduleAddCommand;
@@ -79,18 +82,22 @@ import org.xml.sax.helpers.XMLReaderFactory;
public class RepoCommand extends GitCommand {
private String path;
-
private String uri;
+ private String groups;
private ProgressMonitor monitor;
private static class Project {
final String name;
final String path;
+ final Set groups;
- Project(String name, String path) {
+ Project(String name, String path, String groups) {
this.name = name;
this.path = path;
+ this.groups = new HashSet();
+ if (groups != null && groups.length() > 0)
+ this.groups.addAll(Arrays.asList(groups.split(","))); //$NON-NLS-1$
}
}
@@ -100,14 +107,29 @@ public class RepoCommand extends GitCommand {
private final String baseUrl;
private final Map remotes;
private final List projects;
+ private final Set plusGroups;
+ private final Set minusGroups;
private String defaultRemote;
- XmlManifest(RepoCommand command, String filename, String baseUrl) {
+ XmlManifest(RepoCommand command, String filename, String baseUrl, String groups) {
this.command = command;
this.filename = filename;
this.baseUrl = baseUrl;
remotes = new HashMap();
projects = new ArrayList();
+ plusGroups = new HashSet();
+ minusGroups = new HashSet();
+ if (groups == null || groups.length() == 0 || groups.equals("default")) { //$NON-NLS-1$
+ // default means "all,-notdefault"
+ minusGroups.add("notdefault"); //$NON-NLS-1$
+ } else {
+ for (String group : groups.split(",")) { //$NON-NLS-1$
+ if (group.startsWith("-")) //$NON-NLS-1$
+ minusGroups.add(group.substring(1));
+ else
+ plusGroups.add(group);
+ }
+ }
}
void read() throws IOException {
@@ -137,13 +159,17 @@ public class RepoCommand extends GitCommand {
String localName,
String qName,
Attributes attributes) throws SAXException {
- if ("project".equals(qName)) //$NON-NLS-1$
- projects.add(new Project(attributes.getValue("name"), attributes.getValue("path"))); //$NON-NLS-1$ //$NON-NLS-2$
- else if ("remote".equals(qName)) //$NON-NLS-1$
- remotes.put(attributes.getValue("name"), attributes.getValue("fetch")); //$NON-NLS-1$ //$NON-NLS-2$
- else if ("default".equals(qName)) //$NON-NLS-1$
+ if ("project".equals(qName)) { //$NON-NLS-1$
+ projects.add(new Project( //$NON-NLS-1$
+ attributes.getValue("name"), //$NON-NLS-1$
+ attributes.getValue("path"), //$NON-NLS-1$
+ attributes.getValue("groups"))); //$NON-NLS-1$
+ } else if ("remote".equals(qName)) { //$NON-NLS-1$
+ remotes.put(attributes.getValue("name"), //$NON-NLS-1$
+ attributes.getValue("fetch")); //$NON-NLS-1$
+ } else if ("default".equals(qName)) { //$NON-NLS-1$
defaultRemote = attributes.getValue("remote"); //$NON-NLS-1$
- else if ("copyfile".equals(qName)) { //$NON-NLS-1$
+ } else if ("copyfile".equals(qName)) { //$NON-NLS-1$
// TODO(fishywang): Handle copyfile. Do nothing for now.
}
}
@@ -162,9 +188,29 @@ public class RepoCommand extends GitCommand {
throw new SAXException(e);
}
for (Project proj : projects) {
- String url = remoteUrl + proj.name;
- command.addSubmodule(url, proj.path);
+ if (inGroups(proj)) {
+ String url = remoteUrl + proj.name;
+ command.addSubmodule(url, proj.path);
+ }
+ }
+ }
+
+ boolean inGroups(Project proj) {
+ for (String group : minusGroups) {
+ if (proj.groups.contains(group)) {
+ // minus groups have highest priority.
+ return false;
+ }
+ }
+ if (plusGroups.isEmpty() || plusGroups.contains("all")) { //$NON-NLS-1$
+ // empty plus groups means "all"
+ return true;
+ }
+ for (String group : plusGroups) {
+ if (proj.groups.contains(group))
+ return true;
}
+ return false;
}
}
@@ -204,6 +250,17 @@ public class RepoCommand extends GitCommand {
return this;
}
+ /**
+ * Set groups to sync
+ *
+ * @param groups groups separated by comma, examples: default|all|G1,-G2,-G3
+ * @return this command
+ */
+ public RepoCommand setGroups(final String groups) {
+ this.groups = groups;
+ return this;
+ }
+
/**
* The progress monitor associated with the clone operation. By default,
* this is set to NullProgressMonitor
@@ -225,7 +282,7 @@ public class RepoCommand extends GitCommand {
if (uri == null || uri.length() == 0)
throw new IllegalArgumentException(JGitText.get().uriNotConfigured);
- XmlManifest manifest = new XmlManifest(this, path, uri);
+ XmlManifest manifest = new XmlManifest(this, path, uri, groups);
try {
manifest.read();
} catch (IOException e) {
@@ -236,11 +293,13 @@ public class RepoCommand extends GitCommand {
}
private void addSubmodule(String url, String name) throws SAXException {
- SubmoduleAddCommand add = new SubmoduleAddCommand(repo);
+ SubmoduleAddCommand add = new SubmoduleAddCommand(repo)
+ .setPath(name)
+ .setURI(url);
if (monitor != null)
add.setProgressMonitor(monitor);
try {
- add.setPath(name).setURI(url).call();
+ add.call();
} catch (GitAPIException e) {
throw new SAXException(e);
}