aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorYuxuan 'fishy' Wang <fishywang@google.com>2014-05-02 11:15:34 -0700
committerYuxuan 'fishy' Wang <fishywang@google.com>2014-05-09 17:25:41 -0700
commitd998bc938a21cb3871b442a3bb54b5807b6e4ed2 (patch)
tree481a69866328f2b90cd60b20314f57548a44fc3d /org.eclipse.jgit
parent056135a1482a9d56ee5055d6bc2df5bea032b5e5 (diff)
downloadjgit-d998bc938a21cb3871b442a3bb54b5807b6e4ed2.tar.gz
jgit-d998bc938a21cb3871b442a3bb54b5807b6e4ed2.zip
Handle the revision attribute in repo manifest.
Change-Id: I77fe073aeb13c58029551b7d6e1451a9b62dc766 Signed-off-by: Yuxuan 'fishy' Wang <fishywang@google.com>
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java98
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java22
2 files changed, 94 insertions, 26 deletions
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 2766d7531e..b09129adb8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
@@ -81,6 +81,7 @@ import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
@@ -108,6 +109,7 @@ public class RepoCommand extends GitCommand<RevCommit> {
private String path;
private String uri;
private String groups;
+ private String branch;
private PersonIdent author;
private RemoteReader callback;
@@ -116,7 +118,7 @@ public class RepoCommand extends GitCommand<RevCommit> {
private ProgressMonitor monitor;
/**
- * A callback to get head sha1 of a repository from its uri.
+ * A callback to get ref sha1 of a repository from its uri.
*
* We provided a default implementation {@link DefaultRemoteReader} to
* use ls-remote command to read the sha1 from the repository. Callers may
@@ -124,27 +126,32 @@ public class RepoCommand extends GitCommand<RevCommit> {
*/
public interface RemoteReader {
/**
- * Read a remote repository's HEAD sha1.
+ * Read a remote ref sha1.
*
* @param uri
* The URI of the remote repository
- * @return the sha1 of the HEAD of the remote repository
+ * @param ref
+ * The ref (branch/tag/etc.) to read
+ * @return the sha1 of the remote repository
*/
- public ObjectId sha1(String uri) throws GitAPIException;
+ public ObjectId sha1(String uri, String ref) throws GitAPIException;
}
/** A default implementation of {@link RemoteReader} callback. */
public static class DefaultRemoteReader implements RemoteReader {
- public ObjectId sha1(String uri) throws GitAPIException {
+ public ObjectId sha1(String uri, String ref) throws GitAPIException {
Collection<Ref> refs = Git
.lsRemoteRepository()
.setRemote(uri)
.call();
- for (Ref ref : refs) {
- if (Constants.HEAD.equals(ref.getName()))
- return ref.getObjectId();
- }
- return null;
+ // Since LsRemoteCommand.call() only returned Map.values() to us, we
+ // have to rebuild the map here.
+ Map<String, Ref> map = new HashMap<String, Ref>(refs.size());
+ for (Ref r : refs)
+ map.put(r.getName(), r);
+
+ Ref r = RefDatabase.findRef(map, ref);
+ return r != null ? r.getObjectId() : null;
}
}
@@ -180,10 +187,12 @@ public class RepoCommand extends GitCommand<RevCommit> {
final String path;
final Set<String> groups;
final List<CopyFile> copyfiles;
+ String revision;
- Project(String name, String path, String groups) {
+ Project(String name, String path, String revision, String groups) {
this.name = name;
this.path = path;
+ this.revision = revision;
this.groups = new HashSet<String>();
if (groups != null && groups.length() > 0)
this.groups.addAll(Arrays.asList(groups.split(","))); //$NON-NLS-1$
@@ -204,6 +213,7 @@ public class RepoCommand extends GitCommand<RevCommit> {
private final Set<String> plusGroups;
private final Set<String> minusGroups;
private String defaultRemote;
+ private String defaultRevision;
private Project currentProject;
XmlManifest(RepoCommand command, String filename, String baseUrl, String groups) {
@@ -258,12 +268,16 @@ public class RepoCommand extends GitCommand<RevCommit> {
currentProject = new Project( //$NON-NLS-1$
attributes.getValue("name"), //$NON-NLS-1$
attributes.getValue("path"), //$NON-NLS-1$
+ attributes.getValue("revision"), //$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$
+ defaultRevision = attributes.getValue("revision"); //$NON-NLS-1$
+ if (defaultRevision == null)
+ defaultRevision = command.branch;
} else if ("copyfile".equals(qName)) { //$NON-NLS-1$
if (currentProject == null)
throw new SAXException(RepoText.get().invalidManifest);
@@ -301,8 +315,10 @@ public class RepoCommand extends GitCommand<RevCommit> {
}
for (Project proj : projects) {
if (inGroups(proj)) {
+ if (proj.revision == null)
+ proj.revision = defaultRevision;
String url = remoteUrl + proj.name;
- command.addSubmodule(url, proj.path);
+ command.addSubmodule(url, proj.path, proj.revision);
for (CopyFile copyfile : proj.copyfiles) {
try {
copyfile.copy();
@@ -349,8 +365,8 @@ public class RepoCommand extends GitCommand<RevCommit> {
}
private static class RemoteUnavailableException extends GitAPIException {
- RemoteUnavailableException(String uri, Throwable cause) {
- super(MessageFormat.format(RepoText.get().errorRemoteUnavailable, uri), cause);
+ RemoteUnavailableException(String uri) {
+ super(MessageFormat.format(RepoText.get().errorRemoteUnavailable, uri));
}
}
@@ -396,6 +412,21 @@ public class RepoCommand extends GitCommand<RevCommit> {
}
/**
+ * Set default branch.
+ *
+ * This is generally the name of the branch the manifest file was in. If
+ * there's no default revision (branch) specified in manifest and no
+ * revision specified in project, this branch will be used.
+ *
+ * @param branch
+ * @return this command
+ */
+ public RepoCommand setBranch(final String branch) {
+ this.branch = branch;
+ return this;
+ }
+
+ /**
* The progress monitor associated with the clone operation. By default,
* this is set to <code>NullProgressMonitor</code>
*
@@ -474,17 +505,13 @@ public class RepoCommand extends GitCommand<RevCommit> {
// create gitlink
final DirCacheEntry dcEntry = new DirCacheEntry(name);
ObjectId objectId;
- try {
- objectId = callback.sha1(uri);
- } catch (GitAPIException e) {
- // Something wrong getting the head sha1
- throw new RemoteUnavailableException(uri, e);
- } catch (IllegalArgumentException e) {
- // The revision from the manifest is malformed.
- throw new ManifestErrorException(e);
+ if (ObjectId.isId(proj.revision))
+ objectId = ObjectId.fromString(proj.revision);
+ else {
+ objectId = callback.sha1(uri, proj.revision);
}
if (objectId == null)
- throw new RemoteUnavailableException(uri, null);
+ throw new RemoteUnavailableException(uri);
dcEntry.setObjectId(objectId);
dcEntry.setFileMode(FileMode.GITLINK);
builder.add(dcEntry);
@@ -551,9 +578,9 @@ public class RepoCommand extends GitCommand<RevCommit> {
}
}
- private void addSubmodule(String url, String name) throws SAXException {
+ private void addSubmodule(String url, String name, String revision) throws SAXException {
if (repo.isBare()) {
- Project proj = new Project(url, name, null);
+ Project proj = new Project(url, name, revision, null);
bareProjects.add(proj);
} else {
SubmoduleAddCommand add = git
@@ -562,11 +589,30 @@ public class RepoCommand extends GitCommand<RevCommit> {
.setURI(url);
if (monitor != null)
add.setProgressMonitor(monitor);
+
try {
- add.call();
+ Repository subRepo = add.call();
+ if (revision != null) {
+ Git sub = new Git(subRepo);
+ sub.checkout().setName(findRef(revision, subRepo)).call();
+ git.add().addFilepattern(name).call();
+ }
} catch (GitAPIException e) {
throw new SAXException(e);
+ } catch (IOException e) {
+ throw new SAXException(e);
}
}
}
+
+ private static String findRef(String ref, Repository repo)
+ throws IOException {
+ if (!ObjectId.isId(ref)) {
+ Ref r = repo.getRef(
+ Constants.DEFAULT_REMOTE_NAME + "/" + ref);
+ if (r != null)
+ return r.getName();
+ }
+ return ref;
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
index 2ee63f18ea..682cac162c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
@@ -271,4 +271,26 @@ public abstract class RefDatabase {
public void refresh() {
// nothing
}
+
+ /**
+ * Try to find the specified name in the ref map using {@link #SEARCH_PATH}.
+ *
+ * @param map
+ * map of refs to search within. Names should be fully qualified,
+ * e.g. "refs/heads/master".
+ * @param name
+ * short name of ref to find, e.g. "master" to find
+ * "refs/heads/master" in map.
+ * @return The first ref matching the name, or null if not found.
+ * @since 3.4
+ */
+ public static Ref findRef(Map<String, Ref> map, String name) {
+ for (String prefix : SEARCH_PATH) {
+ String fullname = prefix + name;
+ Ref ref = map.get(fullname);
+ if (ref != null)
+ return ref;
+ }
+ return null;
+ }
}