Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Halstrick2014-10-21 08:55:36 +0000
committerMatthias Sohn2015-02-02 19:15:54 +0000
commitfd9695bf5cbca704bab51ff27b8716dbb0f5b729 (patch)
tree6a93486968c454608239df0c8b53b27eaa735a41
parent7d00a85840fd35ba98a66a373f0fb915991ea962 (diff)
downloadegit-fd9695bf5cbca704bab51ff27b8716dbb0f5b729.tar.gz
egit-fd9695bf5cbca704bab51ff27b8716dbb0f5b729.tar.xz
egit-fd9695bf5cbca704bab51ff27b8716dbb0f5b729.zip
Let staging view use submodule repos
If the staging view is linked to the selected resource and if that resource belongs to a submodule then staging view should also run in the context of the submodule repo. This allows to work with submodules in a similar manner than with native git. If I want to do a commit in a submodule repo then select a resource in that submodule repo and you can use Staging view to prepare the commit in the submodule repo. In native git you would "cd" to a folder containing a file from the submodule to switch context from the containing repo to the submodule repo. In EGit you have to select a resource from the submodule to achieve the same. RepositoryMapping is enhanced by one method which can return a submodule repository. In future RepositoryMapping could be further enhanced to support git submodules in general. Bug: 382093 Bug: 446344 Change-Id: Ie61c597c87a68da16a92cd52fea0bc5a4ff5ec28 Also-By: Stefan Lay <stefan.lay@sap.com> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CoreText.java3
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties1
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryMapping.java50
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java40
4 files changed, 88 insertions, 6 deletions
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CoreText.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CoreText.java
index 3b3885614b..e92b70be61 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CoreText.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CoreText.java
@@ -178,6 +178,9 @@ public class CoreText extends NLS {
public static String RepositoryFinder_finding;
/** */
+ public static String RepositoryMapping_ExceptionSubmoduleWalk;
+
+ /** */
public static String RepositoryUtil_DirectoryIsNotGitDirectory;
/** */
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties
index 3a480e05fa..003a867d02 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties
@@ -67,6 +67,7 @@ GitProjectData_saveFailed=Saving Git team provider data to {0} failed.
RebaseInteractivePlan_WriteRebaseTodoFailed=Error writing Rebase-Todo-File
RepositoryFinder_finding=Searching for associated repositories.
+RepositoryMapping_ExceptionSubmoduleWalk=Caught exception while walking submodules
RepositoryUtil_DirectoryIsNotGitDirectory=Repository directory to configure does not look like a Git directory: {0}
RepositoryUtil_noHead=NO-HEAD
ResetOperation_performingReset=Performing {0} reset to {1}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryMapping.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryMapping.java
index 4e4a278da3..dbafbe1b1f 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryMapping.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryMapping.java
@@ -27,8 +27,12 @@ import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.GitProvider;
+import org.eclipse.egit.core.RepositoryCache;
+import org.eclipse.egit.core.internal.CoreText;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.submodule.SubmoduleWalk;
import org.eclipse.team.core.RepositoryProvider;
/**
@@ -55,6 +59,9 @@ public class RepositoryMapping {
private IContainer container;
+ private final RepositoryCache repositoryCache = org.eclipse.egit.core.Activator
+ .getDefault().getRepositoryCache();
+
/**
* Construct a {@link RepositoryMapping} for a previously connected project.
*
@@ -143,6 +150,49 @@ public class RepositoryMapping {
return db;
}
+ /**
+ * @param res
+ * a resource
+ * @return the submodule repository if the resource is contained in a git
+ * submodule otherwise return {@code null}. The returned repository
+ * instance will always be taken from the {@link RepositoryCache}
+ * and the caller should not call close() on it.
+ *
+ * TODO add support for multiple nesting levels of submodules
+ */
+ public synchronized Repository getSubmoduleRepository(IResource res) {
+ IPath projectRelativePath = res.getProjectRelativePath();
+ if (projectRelativePath == null)
+ return null;
+
+ String projectRelativePathStr = res.getProjectRelativePath().toString();
+ try {
+ if (SubmoduleWalk.containsGitModulesFile(db)) {
+ SubmoduleWalk sw = SubmoduleWalk.forIndex(db);
+ while (sw.next()) {
+ if (projectRelativePathStr.startsWith(sw.getPath())) {
+ Repository subRepo = sw.getRepository();
+ if (subRepo == null)
+ return null;
+
+ Repository cachedRepo = null;
+ try {
+ cachedRepo = repositoryCache
+ .lookupRepository(subRepo.getDirectory());
+ } finally {
+ subRepo.close();
+ }
+ return cachedRepo;
+ }
+ }
+ }
+ } catch (IOException e) {
+ Activator.logWarning(
+ CoreText.RepositoryMapping_ExceptionSubmoduleWalk, e);
+ }
+ return db;
+ }
+
synchronized void setRepository(final Repository r) {
db = r;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java
index 8cefb091ac..b6489dcb42 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java
@@ -11,6 +11,7 @@ package org.eclipse.egit.ui.internal.staging;
import static org.eclipse.egit.ui.internal.CommonUtils.runCommand;
import java.io.File;
+import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
@@ -32,6 +33,7 @@ import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
@@ -93,6 +95,8 @@ import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.operation.ModalContext;
import org.eclipse.jface.preference.IPersistentPreferenceStore;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
@@ -1873,12 +1877,34 @@ public class StagingView extends ViewPart implements IShowInSource {
}
private void showResource(final IResource resource) {
- IProject project = resource.getProject();
- RepositoryMapping mapping = RepositoryMapping.getMapping(project);
- if (mapping == null)
- return;
- if (mapping.getRepository() != currentRepository)
- reload(mapping.getRepository());
+ Repository newRep = getRepositoryOrNestedSubmoduleRepository(resource);
+ if (newRep != null && newRep != currentRepository)
+ reload(newRep);
+ }
+
+ private Repository getRepositoryOrNestedSubmoduleRepository(
+ final IResource resource) {
+ final Repository[] repo = new Repository[1];
+ try {
+ ModalContext.run(new IRunnableWithProgress() {
+
+ public void run(IProgressMonitor monitor) {
+ IProject project = resource.getProject();
+ RepositoryMapping mapping = RepositoryMapping
+ .getMapping(project);
+ if (mapping == null)
+ return;
+ repo[0] = mapping.getSubmoduleRepository(resource);
+ if (repo[0] == null)
+ repo[0] = mapping.getRepository();
+ }
+ }, true, new NullProgressMonitor(), Display.getDefault());
+ } catch (InvocationTargetException e) {
+ // ignore
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ return repo[0];
}
private void stage(IStructuredSelection selection) {
@@ -1906,6 +1932,8 @@ public class StagingView extends ViewPart implements IShowInSource {
IResource resource = AdapterUtils.adapt(element, IResource.class);
if (resource != null) {
RepositoryMapping mapping = RepositoryMapping.getMapping(resource);
+ // doesn't do anything if the current repository is a
+ // submodule of the mapped repo
if (mapping != null && mapping.getRepository() == currentRepository) {
String path = mapping.getRepoRelativePath(resource);
// If resource corresponds to root of working directory

Back to the top