diff options
author | Yuxuan 'fishy' Wang <fishywang@google.com> | 2014-05-02 11:15:34 -0700 |
---|---|---|
committer | Yuxuan 'fishy' Wang <fishywang@google.com> | 2014-05-09 17:25:41 -0700 |
commit | d998bc938a21cb3871b442a3bb54b5807b6e4ed2 (patch) | |
tree | 481a69866328f2b90cd60b20314f57548a44fc3d /org.eclipse.jgit | |
parent | 056135a1482a9d56ee5055d6bc2df5bea032b5e5 (diff) | |
download | jgit-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.java | 98 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java | 22 |
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; + } } |