# This patch file was generated by NetBeans IDE # Following Index: paths are relative to: /home/ondra/netbeans/cdev # This patch can be applied using context Tools: Patch action on respective folder. # It uses platform neutral UTF-8 encoding and \n newlines. # Above lines and this line are ignored by the patching process. Index: libs.git/apichanges.xml --- libs.git/apichanges.xml +++ libs.git/apichanges.xml @@ -112,6 +112,24 @@ The log command returns also branches containing the commits from the result. + + + + + +
    +
  • Adding new methods to GitClient allowing users to check a submodule's status, initialize them + after a clone and update them to a commit relevant to the state in the parent repository.
  • +
  • Adding a new class GitSubmoduleStatus wrapping information about a submodule.
  • +
+
+ + + +
+ + + The log command returns also branches containing the commits from the result. Index: libs.git/manifest.mf --- libs.git/manifest.mf +++ libs.git/manifest.mf @@ -1,4 +1,4 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.libs.git/1 OpenIDE-Module-Localizing-Bundle: org/netbeans/libs/git/Bundle.properties -OpenIDE-Module-Specification-Version: 1.15 +OpenIDE-Module-Specification-Version: 1.16 Index: libs.git/src/org/netbeans/libs/git/GitClassFactoryImpl.java --- libs.git/src/org/netbeans/libs/git/GitClassFactoryImpl.java +++ libs.git/src/org/netbeans/libs/git/GitClassFactoryImpl.java @@ -54,6 +54,7 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevTag; +import org.eclipse.jgit.submodule.SubmoduleStatus; import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.jgit.transport.RemoteRefUpdate; import org.eclipse.jgit.transport.TrackingRefUpdate; @@ -185,4 +186,9 @@ branch.setTrackedBranch(trackedBranch); } + @Override + public GitSubmoduleStatus createSubmoduleStatus (SubmoduleStatus status, File folder) { + return new GitSubmoduleStatus(status, folder); + } + } Index: libs.git/src/org/netbeans/libs/git/GitClient.java --- libs.git/src/org/netbeans/libs/git/GitClient.java +++ libs.git/src/org/netbeans/libs/git/GitClient.java @@ -98,6 +98,9 @@ import org.netbeans.libs.git.jgit.commands.StatusCommand; import org.netbeans.libs.git.jgit.commands.UnignoreCommand; import org.netbeans.libs.git.jgit.commands.SetUpstreamBranchCommand; +import org.netbeans.libs.git.jgit.commands.SubmoduleInitializeCommand; +import org.netbeans.libs.git.jgit.commands.SubmoduleStatusCommand; +import org.netbeans.libs.git.jgit.commands.SubmoduleUpdateCommand; import org.netbeans.libs.git.progress.FileListener; import org.netbeans.libs.git.progress.NotificationListener; import org.netbeans.libs.git.progress.ProgressMonitor; @@ -655,6 +658,24 @@ cmd.execute(); return cmd.getFileDifferences(); } + + /** + * Scans for any submodules under given roots or in the whole repository and + * returns their status. + * + * @param roots files to search for submodules. If empty all submodules will + * be returned + * @param monitor command progress monitor + * @return status map of repository's submodules + * @throws GitException an unexpected error occurs + * @since 1.16 + */ + public Map getSubmoduleStatus (File[] roots, ProgressMonitor monitor) throws GitException { + Repository repository = gitRepository.getRepository(); + SubmoduleStatusCommand cmd = new SubmoduleStatusCommand(repository, getClassFactory(), roots, monitor); + cmd.execute(); + return cmd.getStatuses(); + } /** * Returns remote configuration set up for this repository identified by a given remoteName @@ -730,6 +751,23 @@ } /** + * Initializes submodules and registers them in .git/config file. + * + * @param roots modules to initialize + * @param monitor progress monitor + * @return initialized submodule statuses + * @throws GitException an unexpected error occurs + * @since 1.16 + */ + public Map initializeSubmodules (File[] roots, ProgressMonitor monitor) throws GitException { + Repository repository = gitRepository.getRepository(); + SubmoduleInitializeCommand cmd = new SubmoduleInitializeCommand(repository, getClassFactory(), + roots, monitor); + cmd.execute(); + return cmd.getStatuses(); + } + + /** * Returns files that are marked as modified between the HEAD and Index. * @param roots files or folders to search for modified files. * @param monitor progress monitor @@ -1065,6 +1103,23 @@ return cmd.getModifiedIgnoreFiles(); } + /** + * Updates submodules. An equivalent to submodule update command. + * + * @param roots modules to update + * @param monitor progress monitor + * @return submodule statuses + * @throws GitException an unexpected error occurs + * @since 1.16 + */ + public Map updateSubmodules (File[] roots, ProgressMonitor monitor) throws GitException { + Repository repository = gitRepository.getRepository(); + SubmoduleUpdateCommand cmd = new SubmoduleUpdateCommand(repository, getClassFactory(), + roots, monitor); + cmd.execute(); + return cmd.getStatuses(); + } + private GitClassFactory getClassFactory () { if (gitFactory == null) { gitFactory = GitClassFactoryImpl.getInstance(); Index: libs.git/src/org/netbeans/libs/git/GitSubmoduleStatus.java --- libs.git/src/org/netbeans/libs/git/GitSubmoduleStatus.java +++ libs.git/src/org/netbeans/libs/git/GitSubmoduleStatus.java @@ -0,0 +1,125 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ +package org.netbeans.libs.git; + +import java.io.File; +import org.eclipse.jgit.submodule.SubmoduleStatus; +import org.eclipse.jgit.submodule.SubmoduleStatusType; + +/** + * Describes current status of a repository's submodule + * + * @author Ondrej Vrabec + * @since 1.16 + */ +public final class GitSubmoduleStatus { + + private final SubmoduleStatus delegate; + private final StatusType statusType; + private final File folder; + + /** + * Submodule's status + */ + public enum StatusType { + + /** + * Submodule's configuration is missing + */ + MISSING, + /** + * Submodule's Git repository is not initialized + */ + UNINITIALIZED, + /** + * Submodule's Git repository is initialized + */ + INITIALIZED, + /** + * Submodule checked out commit is different than the commit referenced + * in the index tree + */ + REV_CHECKED_OUT; + } + + GitSubmoduleStatus (SubmoduleStatus delegate, File folder) { + this.delegate = delegate; + this.folder = folder; + this.statusType = parseStatus(delegate.getType()); + } + + /** + * Returns status of the submodule + * @return submodule's status + */ + public StatusType getStatus () { + return statusType; + } + + /** + * Returns the submodule's root folder. + * @return submodule's root folder. + */ + public File getSubmoduleFolder () { + return folder; + } + + /** + * Returns the commit id of the currently checked-out commit. + * @return submodule's commit id. + */ + public String getHeadId () { + return delegate.getHeadId().getName(); + } + + /** + * Returns the state of the index in the submodule. + * @return submodule's index tree id. + */ + public String getIndexId () { + return delegate.getIndexId().getName(); + } + + static StatusType parseStatus (SubmoduleStatusType status) { + return StatusType.valueOf(status.name()); + } +} Index: libs.git/src/org/netbeans/libs/git/jgit/GitClassFactory.java --- libs.git/src/org/netbeans/libs/git/jgit/GitClassFactory.java +++ libs.git/src/org/netbeans/libs/git/jgit/GitClassFactory.java @@ -55,6 +55,7 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevTag; +import org.eclipse.jgit.submodule.SubmoduleStatus; import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.jgit.transport.RemoteRefUpdate; import org.eclipse.jgit.transport.TrackingRefUpdate; @@ -73,6 +74,7 @@ import org.netbeans.libs.git.GitRevisionInfo.GitFileInfo; import org.netbeans.libs.git.GitStatus; import org.netbeans.libs.git.GitStatus.Status; +import org.netbeans.libs.git.GitSubmoduleStatus; import org.netbeans.libs.git.GitTag; import org.netbeans.libs.git.GitTransportUpdate; import org.netbeans.libs.git.GitUser; @@ -113,6 +115,8 @@ public abstract GitStatus createStatus (boolean tracked, String path, String workTreePath, File file, Status statusHeadIndex, Status statusIndexWC, Status statusHeadWC, GitConflictDescriptor conflictDescriptor, boolean folder, DiffEntry diffEntry); + + public abstract GitSubmoduleStatus createSubmoduleStatus (SubmoduleStatus status, File folder); public abstract GitTag createTag (RevTag revTag); Index: libs.git/src/org/netbeans/libs/git/jgit/commands/SubmoduleInitializeCommand.java --- libs.git/src/org/netbeans/libs/git/jgit/commands/SubmoduleInitializeCommand.java +++ libs.git/src/org/netbeans/libs/git/jgit/commands/SubmoduleInitializeCommand.java @@ -0,0 +1,104 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ + +package org.netbeans.libs.git.jgit.commands; + +import java.io.File; +import java.util.Map; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.lib.Repository; +import org.netbeans.libs.git.GitException; +import org.netbeans.libs.git.GitSubmoduleStatus; +import org.netbeans.libs.git.jgit.DelegatingGitProgressMonitor; +import org.netbeans.libs.git.jgit.GitClassFactory; +import org.netbeans.libs.git.jgit.Utils; +import org.netbeans.libs.git.progress.ProgressMonitor; + +/** + * + * @author Ondrej Vrabec + */ +public class SubmoduleInitializeCommand extends GitCommand { + + private final File[] roots; + private final SubmoduleStatusCommand statusCmd; + + public SubmoduleInitializeCommand (Repository repository, GitClassFactory classFactory, + File[] roots, ProgressMonitor monitor) { + super(repository, classFactory, monitor); + this.roots = roots; + this.statusCmd = new SubmoduleStatusCommand(repository, + getClassFactory(), roots, new DelegatingGitProgressMonitor(monitor)); + } + + @Override + protected void run () throws GitException { + Repository repository = getRepository(); + File workTree = repository.getWorkTree(); + org.eclipse.jgit.api.SubmoduleInitCommand cmd = new Git(repository).submoduleInit(); + for (String path : Utils.getRelativePaths(workTree, roots)) { + cmd.addPath(path); + } + try { + cmd.call(); + statusCmd.run(); + } catch (GitAPIException | JGitInternalException ex) { + throw new GitException(ex); + } + } + + @Override + protected String getCommandDescription () { + StringBuilder sb = new StringBuilder("git submodule initialize"); //NOI18N + for (File root : roots) { + sb.append(" ").append(root.getAbsolutePath()); + } + return sb.toString(); + } + + public Map getStatuses () { + return statusCmd.getStatuses(); + } + +} Index: libs.git/src/org/netbeans/libs/git/jgit/commands/SubmoduleStatusCommand.java --- libs.git/src/org/netbeans/libs/git/jgit/commands/SubmoduleStatusCommand.java +++ libs.git/src/org/netbeans/libs/git/jgit/commands/SubmoduleStatusCommand.java @@ -0,0 +1,108 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ + +package org.netbeans.libs.git.jgit.commands; + +import java.io.File; +import java.util.LinkedHashMap; +import java.util.Map; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.submodule.SubmoduleStatus; +import org.netbeans.libs.git.GitException; +import org.netbeans.libs.git.GitSubmoduleStatus; +import org.netbeans.libs.git.jgit.GitClassFactory; +import org.netbeans.libs.git.jgit.Utils; +import org.netbeans.libs.git.progress.ProgressMonitor; + +/** + * + * @author Ondrej Vrabec + */ +public class SubmoduleStatusCommand extends GitCommand { + + private final File[] roots; + private final LinkedHashMap statuses; + + public SubmoduleStatusCommand (Repository repository, GitClassFactory classFactory, + File[] roots, ProgressMonitor monitor) { + super(repository, classFactory, monitor); + this.roots = roots; + statuses = new LinkedHashMap<>(); + } + + @Override + protected void run () throws GitException { + Repository repository = getRepository(); + File workTree = repository.getWorkTree(); + org.eclipse.jgit.api.SubmoduleStatusCommand cmd = new Git(repository).submoduleStatus(); + for (String path : Utils.getRelativePaths(workTree, roots)) { + cmd.addPath(path); + } + try { + Map result = cmd.call(); + GitClassFactory fac = getClassFactory(); + for (Map.Entry e : result.entrySet()) { + File root = new File(workTree, e.getKey()); + statuses.put(root, fac.createSubmoduleStatus(e.getValue(), root)); + } + } catch (GitAPIException | JGitInternalException ex) { + throw new GitException(ex); + } + } + + @Override + protected String getCommandDescription () { + StringBuilder sb = new StringBuilder("git submodule status"); //NOI18N + for (File root : roots) { + sb.append(" ").append(root.getAbsolutePath()); + } + return sb.toString(); + } + + public Map getStatuses () { + return statuses; + } + +} Index: libs.git/src/org/netbeans/libs/git/jgit/commands/SubmoduleUpdateCommand.java --- libs.git/src/org/netbeans/libs/git/jgit/commands/SubmoduleUpdateCommand.java +++ libs.git/src/org/netbeans/libs/git/jgit/commands/SubmoduleUpdateCommand.java @@ -0,0 +1,108 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ + +package org.netbeans.libs.git.jgit.commands; + +import java.io.File; +import java.util.Map; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.lib.Repository; +import org.netbeans.libs.git.GitException; +import org.netbeans.libs.git.GitSubmoduleStatus; +import org.netbeans.libs.git.jgit.DelegatingGitProgressMonitor; +import org.netbeans.libs.git.jgit.DelegatingProgressMonitor; +import org.netbeans.libs.git.jgit.GitClassFactory; +import org.netbeans.libs.git.jgit.Utils; +import org.netbeans.libs.git.progress.ProgressMonitor; + +/** + * + * @author Ondrej Vrabec + */ +public class SubmoduleUpdateCommand extends GitCommand { + + private final File[] roots; + private final SubmoduleStatusCommand statusCmd; + private final ProgressMonitor monitor; + + public SubmoduleUpdateCommand (Repository repository, GitClassFactory classFactory, + File[] roots, ProgressMonitor monitor) { + super(repository, classFactory, monitor); + this.monitor = monitor; + this.roots = roots; + this.statusCmd = new SubmoduleStatusCommand(repository, + getClassFactory(), roots, new DelegatingGitProgressMonitor(monitor)); + } + + @Override + protected void run () throws GitException { + Repository repository = getRepository(); + File workTree = repository.getWorkTree(); + org.eclipse.jgit.api.SubmoduleUpdateCommand cmd = new Git(repository).submoduleUpdate(); + for (String path : Utils.getRelativePaths(workTree, roots)) { + cmd.addPath(path); + } + try { + cmd.setProgressMonitor(new DelegatingProgressMonitor(monitor)); + cmd.call(); + statusCmd.run(); + } catch (GitAPIException | JGitInternalException ex) { + throw new GitException(ex); + } + } + + @Override + protected String getCommandDescription () { + StringBuilder sb = new StringBuilder("git submodule initialize"); //NOI18N + for (File root : roots) { + sb.append(" ").append(root.getAbsolutePath()); + } + return sb.toString(); + } + + public Map getStatuses () { + return statusCmd.getStatuses(); + } + +} Index: libs.git/test/unit/src/org/netbeans/libs/git/GitEnumsStateTest.java --- libs.git/test/unit/src/org/netbeans/libs/git/GitEnumsStateTest.java +++ libs.git/test/unit/src/org/netbeans/libs/git/GitEnumsStateTest.java @@ -47,6 +47,7 @@ import org.eclipse.jgit.api.RebaseResult; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.RepositoryState; +import org.eclipse.jgit.submodule.SubmoduleStatusType; import org.eclipse.jgit.transport.RemoteRefUpdate; import org.netbeans.libs.git.jgit.AbstractGitTestCase; @@ -89,4 +90,10 @@ assertNotNull(GitRebaseResult.parseRebaseStatus(status)); } } + + public void testSubmoduleStatus () { + for (SubmoduleStatusType status : SubmoduleStatusType.values()) { + assertNotNull(GitSubmoduleStatus.parseStatus(status)); + } + } } Index: libs.git/test/unit/src/org/netbeans/libs/git/jgit/CommandsTestSuite.java --- libs.git/test/unit/src/org/netbeans/libs/git/jgit/CommandsTestSuite.java +++ libs.git/test/unit/src/org/netbeans/libs/git/jgit/CommandsTestSuite.java @@ -76,6 +76,7 @@ import org.netbeans.libs.git.jgit.commands.RevertTest; import org.netbeans.libs.git.jgit.commands.SetUpstreamBranchTest; import org.netbeans.libs.git.jgit.commands.StatusTest; +import org.netbeans.libs.git.jgit.commands.SubmoduleTest; import org.netbeans.libs.git.jgit.commands.TagTest; import org.netbeans.libs.git.jgit.commands.UnignoreTest; @@ -122,6 +123,7 @@ suite.addTestSuite(ResetTest.class); suite.addTestSuite(SetUpstreamBranchTest.class); suite.addTestSuite(StatusTest.class); + suite.addTestSuite(SubmoduleTest.class); suite.addTestSuite(TagTest.class); suite.addTestSuite(UnignoreTest.class); return suite; Index: libs.git/test/unit/src/org/netbeans/libs/git/jgit/commands/SubmoduleTest.java --- libs.git/test/unit/src/org/netbeans/libs/git/jgit/commands/SubmoduleTest.java +++ libs.git/test/unit/src/org/netbeans/libs/git/jgit/commands/SubmoduleTest.java @@ -0,0 +1,230 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ + +package org.netbeans.libs.git.jgit.commands; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.transport.RemoteConfig; +import org.eclipse.jgit.transport.URIish; +import org.netbeans.libs.git.GitClient; +import org.netbeans.libs.git.GitSubmoduleStatus; +import org.netbeans.libs.git.jgit.AbstractGitTestCase; +import org.netbeans.libs.git.jgit.Utils; + +/** + * + * @author Ondrej Vrabec + */ +public class SubmoduleTest extends AbstractGitTestCase { + + private Repository repository; + private Repository repositorySM1; + private Repository repositorySM2; + private File workDir; + private File moduleRepo; + private File submoduleRepo1; + private File submoduleRepo2; + private File submoduleFolder1; + private File submoduleFolder2; + private File f1; + private File f2; + private File f; + + public SubmoduleTest (String testName) throws IOException { + super(testName); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + workDir = getWorkingDirectory(); + repository = getRepository(getLocalGitRepository()); + + moduleRepo = new File(workDir.getParentFile(), "module"); + GitClient client = getClient(moduleRepo); + client.init(NULL_PROGRESS_MONITOR); + submoduleRepo1 = new File(workDir.getParentFile(), "submodule1"); + client = getClient(submoduleRepo1); + client.init(NULL_PROGRESS_MONITOR); + submoduleRepo2 = new File(workDir.getParentFile(), "submodule2"); + client = getClient(submoduleRepo2); + client.init(NULL_PROGRESS_MONITOR); + + client = getClient(workDir); + f = new File(workDir, "f"); + write(f, "init"); + client.add(new File[] { f }, NULL_PROGRESS_MONITOR); + client.commit(new File[] { f }, "init commit", null, null, NULL_PROGRESS_MONITOR); + RemoteConfig cfg = new RemoteConfig(repository.getConfig(), "origin"); + cfg.addURI(new URIish(moduleRepo.toURI().toURL().toString())); + cfg.update(repository.getConfig()); + repository.getConfig().save(); + client.push("origin", Arrays.asList("refs/heads/master:refs/heads/master"), + Arrays.asList("+refs/heads/master:refs/remotes/origin/master"), NULL_PROGRESS_MONITOR); + + File submodules = new File(workDir, "submodules"); + + submoduleFolder1 = new File(submodules, "submodule1"); + submoduleFolder1.mkdirs(); + getClient(submoduleFolder1).init(NULL_PROGRESS_MONITOR); + f1 = new File(submoduleFolder1, "file"); + write(f1, "init"); + getClient(submoduleFolder1).add(new File[] { f1 }, NULL_PROGRESS_MONITOR); + getClient(submoduleFolder1).commit(new File[] { f1 }, "init SM1 commit", null, null, NULL_PROGRESS_MONITOR); + repositorySM1 = getRepository(getClient(submoduleFolder1)); + cfg = new RemoteConfig(repositorySM1.getConfig(), "origin"); + cfg.addURI(new URIish(submoduleRepo1.toURI().toURL().toString())); + cfg.update(repositorySM1.getConfig()); + repositorySM1.getConfig().save(); + getClient(submoduleFolder1).push("origin", Arrays.asList("refs/heads/master:refs/heads/master"), + Arrays.asList("+refs/heads/master:refs/remotes/origin/master"), NULL_PROGRESS_MONITOR); + + + submoduleFolder2 = new File(submodules, "submodule2"); + submoduleFolder2.mkdirs(); + getClient(submoduleFolder2).init(NULL_PROGRESS_MONITOR); + f2 = new File(submoduleFolder2, "file"); + write(f2, "init"); + getClient(submoduleFolder2).add(new File[] { f2 }, NULL_PROGRESS_MONITOR); + getClient(submoduleFolder2).commit(new File[] { f2 }, "init SM1 commit", null, null, NULL_PROGRESS_MONITOR); + repositorySM2 = getRepository(getClient(submoduleFolder2)); + cfg = new RemoteConfig(repositorySM2.getConfig(), "origin"); + cfg.addURI(new URIish(submoduleRepo2.toURI().toURL().toString())); + cfg.update(repositorySM2.getConfig()); + repositorySM2.getConfig().save(); + getClient(submoduleFolder2).push("origin", Arrays.asList("refs/heads/master:refs/heads/master"), + Arrays.asList("+refs/heads/master:refs/remotes/origin/master"), NULL_PROGRESS_MONITOR); + } + + public void testStatusEmpty () throws Exception { + GitClient client = getClient(workDir); + assertEquals(0, client.getSubmoduleStatus(new File[0], NULL_PROGRESS_MONITOR).size()); + } + + public void testStatusUninitialized () throws Exception { + prepareUninitializedWorkdir(); + + GitClient client = getClient(workDir); + Map status = client.getSubmoduleStatus(new File[] { f } , NULL_PROGRESS_MONITOR); + assertEquals(0, status.size()); + + status = client.getSubmoduleStatus(new File[] { submoduleFolder1 } , NULL_PROGRESS_MONITOR); + assertStatus(status.get(submoduleFolder1), GitSubmoduleStatus.StatusType.UNINITIALIZED, + submoduleFolder1); + + status = client.getSubmoduleStatus(new File[] { submoduleFolder2 } , NULL_PROGRESS_MONITOR); + assertStatus(status.get(submoduleFolder2), GitSubmoduleStatus.StatusType.UNINITIALIZED, + submoduleFolder2); + + status = client.getSubmoduleStatus(new File[0], NULL_PROGRESS_MONITOR); + assertStatus(status.get(submoduleFolder1), GitSubmoduleStatus.StatusType.UNINITIALIZED, + submoduleFolder1); + assertStatus(status.get(submoduleFolder2), GitSubmoduleStatus.StatusType.UNINITIALIZED, + submoduleFolder2); + } + + public void testInitialize () throws Exception { + prepareUninitializedWorkdir(); + + GitClient client = getClient(workDir); + Map status = client.getSubmoduleStatus(new File[] { f } , NULL_PROGRESS_MONITOR); + assertEquals(0, status.size()); + + status = client.getSubmoduleStatus(new File[] { submoduleFolder1 }, NULL_PROGRESS_MONITOR); + assertStatus(status.get(submoduleFolder1), GitSubmoduleStatus.StatusType.UNINITIALIZED, + submoduleFolder1); + + status = client.initializeSubmodules(new File[] { submoduleFolder1 }, NULL_PROGRESS_MONITOR); + assertStatus(status.get(submoduleFolder1), GitSubmoduleStatus.StatusType.UNINITIALIZED, + submoduleFolder1); + } + + public void testUpdate () throws Exception { + prepareUninitializedWorkdir(); + + GitClient client = getClient(workDir); + Map status = client.getSubmoduleStatus(new File[] { f } , NULL_PROGRESS_MONITOR); + assertEquals(0, status.size()); + + status = client.initializeSubmodules(new File[] { submoduleFolder1 }, NULL_PROGRESS_MONITOR); + assertStatus(status.get(submoduleFolder1), GitSubmoduleStatus.StatusType.UNINITIALIZED, + submoduleFolder1); + status = client.updateSubmodules(new File[] { submoduleFolder1 }, NULL_PROGRESS_MONITOR); + assertStatus(status.get(submoduleFolder1), GitSubmoduleStatus.StatusType.INITIALIZED, + submoduleFolder1); + } + + private void prepareUninitializedWorkdir () throws Exception { + File gmFile = new File(workDir, ".gitmodules"); + gmFile.createNewFile(); + write(gmFile, "[submodule \"submodules/submodule1\"]\n" + +" path = submodules/submodule1\n" + +" url = " + submoduleRepo1.toURI().toURL().toString() + "\n" + +"[submodule \"submodules/submodule2\"]\n" + +" path = submodules/submodule2\n" + +" url = " + submoduleRepo2.toURI().toURL().toString() + "\n"); + + GitClient client = getClient(workDir); + client.add(new File[] { gmFile, submoduleFolder1, submoduleFolder2 }, NULL_PROGRESS_MONITOR); + client.commit(new File[0], "adding modules", null, null, NULL_PROGRESS_MONITOR); + client.push("origin", Arrays.asList("refs/heads/master:refs/heads/master"), + Arrays.asList("+refs/heads/master:refs/remotes/origin/master"), NULL_PROGRESS_MONITOR); + + Utils.deleteRecursively(submoduleFolder1); + Utils.deleteRecursively(submoduleFolder2); + assertFalse(submoduleFolder1.exists()); + assertFalse(submoduleFolder2.exists()); + client.reset("master", GitClient.ResetType.HARD, NULL_PROGRESS_MONITOR); + assertTrue(submoduleFolder1.exists()); + assertTrue(submoduleFolder2.exists()); + } + + private void assertStatus (GitSubmoduleStatus status, GitSubmoduleStatus.StatusType statusKind, + File submoduleRoot) { + assertEquals(statusKind, status.getStatus()); + assertEquals(submoduleRoot, status.getSubmoduleFolder()); + } +}