Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDariusz Luksza2011-08-06 23:18:31 +0000
committerMatthias Sohn2011-08-06 23:18:31 +0000
commitbb5fa3c34dd48e596a426ed0ab27fbe6fa2c1402 (patch)
tree5584593239eab116b21a7b39ddeb5ffa4ef8d72a
parenteb454a243857ab130029a24b3d12e5572237e790 (diff)
downloadegit-bb5fa3c34dd48e596a426ed0ab27fbe6fa2c1402.tar.gz
egit-bb5fa3c34dd48e596a426ed0ab27fbe6fa2c1402.tar.xz
egit-bb5fa3c34dd48e596a426ed0ab27fbe6fa2c1402.zip
[sync] Allow synchronize on folder level
When synchronization is launched from folder level, results will only show changes inside this folder. When it is launched from project level it will show changes in whole repository (same as before). Folder level synchronization will always use Workspace presentation model. Change-Id: I937cb2bf870f47e4c3000ae89cd1eb83d0c2d918 Signed-off-by: Dariusz Luksza <dariusz@luksza.org> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTree.java7
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriber.java21
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeData.java38
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeDataSet.java15
-rw-r--r--org.eclipse.egit.ui/plugin.xml48
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ResourcePropertyTester.java3
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithMenu.java29
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWorkspaceActionHandler.java45
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronizeParticipant.java20
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizard.java53
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCache.java36
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommit.java23
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepository.java19
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingTree.java24
14 files changed, 322 insertions, 59 deletions
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTree.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTree.java
index e814acf0cb..584db4b836 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTree.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTree.java
@@ -20,6 +20,7 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
@@ -54,7 +55,11 @@ abstract class GitResourceVariantTree extends ResourceVariantTree {
public IResource[] roots() {
Set<IResource> roots = new HashSet<IResource>();
for (GitSynchronizeData gsd : gsds)
- roots.addAll(gsd.getProjects());
+ if (gsd.getPathFilter() == null)
+ roots.addAll(gsd.getProjects());
+ else
+ for (IContainer container : gsd.getIncludedPaths())
+ roots.add(container.getProject());
return roots.toArray(new IResource[roots.size()]);
}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriber.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriber.java
index 39932209b6..b2696270d5 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriber.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriber.java
@@ -23,6 +23,7 @@ import java.util.Set;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.egit.core.CoreText;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
@@ -67,16 +68,18 @@ public class GitResourceVariantTreeSubscriber extends
@Override
public boolean isSupervised(IResource res) throws TeamException {
return IResource.FILE == res.getType()
- && gsds.contains(res.getProject()) && !isIgnoredHint(res);
+ && gsds.contains(res.getProject()) && !isIgnoredHint(res)
+ && shouldBeIncluded(res);
}
@Override
public IResource[] members(IResource res) throws TeamException {
- if(res.getType() == IResource.FILE)
+ if(res.getType() == IResource.FILE || !shouldBeIncluded(res))
return new IResource[0];
GitSynchronizeData gsd = gsds.getData(res.getProject());
Repository repo = gsd.getRepository();
+
String path = stripWorkDir(repo.getWorkTree(), res.getLocation()
.toFile());
@@ -178,4 +181,18 @@ public class GitResourceVariantTreeSubscriber extends
}
}
+ private boolean shouldBeIncluded(IResource res) {
+ Set<IContainer> includedPaths = gsds.getData(res.getProject())
+ .getIncludedPaths();
+ if (includedPaths == null)
+ return true;
+
+ IPath path = res.getLocation();
+ for (IContainer container : includedPaths)
+ if (container.getLocation().isPrefixOf(path))
+ return true;
+
+ return false;
+ }
+
} \ No newline at end of file
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeData.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeData.java
index 4f8e0a712a..ae8e4de732 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeData.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeData.java
@@ -23,6 +23,7 @@ import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
+import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
@@ -32,6 +33,8 @@ import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.ObjectWalk;
import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
/**
* Simple data transfer object containing all necessary information for
@@ -70,6 +73,10 @@ public class GitSynchronizeData {
private final String dstRev;
+ private TreeFilter pathFilter;
+
+ private Set<IContainer> includedPaths;
+
private static class RemoteConfig {
final String remote;
final String merge;
@@ -219,6 +226,37 @@ public class GitSynchronizeData {
return ancestorRevCommit;
}
+ /**
+ * @param includedPaths
+ * list of containers to be synchronized
+ */
+ public void setIncludedPaths(Set<IContainer> includedPaths) {
+ this.includedPaths = includedPaths;
+ Set<String> paths = new HashSet<String>();
+ RepositoryMapping rm = RepositoryMapping.findRepositoryMapping(repo);
+ for (IContainer container : includedPaths)
+ paths.add(rm.getRepoRelativePath(container));
+
+ if (!paths.isEmpty())
+ pathFilter = PathFilterGroup.createFromStrings(paths);
+ }
+
+ /**
+ * @return set of included paths or {@code null} when all paths should be
+ * included
+ */
+ public Set<IContainer> getIncludedPaths() {
+ return includedPaths;
+ }
+
+ /**
+ * @return instance of {@link TreeFilter} when synchronization was launched
+ * from nested node (like folder) or {@code null} otherwise
+ */
+ public TreeFilter getPathFilter() {
+ return pathFilter;
+ }
+
private RemoteConfig extractRemoteName(String rev) {
if (rev.contains(R_REMOTES)) {
String remoteWithBranchName = rev.replaceAll(R_REMOTES, ""); //$NON-NLS-1$
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeDataSet.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeDataSet.java
index a300beb9ac..ee3abf5830 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeDataSet.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeDataSet.java
@@ -21,6 +21,8 @@ import org.eclipse.core.resources.IProject;
*/
public class GitSynchronizeDataSet implements Iterable<GitSynchronizeData> {
+ private boolean containsFolderLevelSynchronizationRequest = false;
+
private final Set<GitSynchronizeData> gsd;
private final Map<String, GitSynchronizeData> projectMapping;
@@ -48,6 +50,10 @@ public class GitSynchronizeDataSet implements Iterable<GitSynchronizeData> {
*/
public void add(GitSynchronizeData data) {
gsd.add(data);
+ if (data.getIncludedPaths() != null
+ && data.getIncludedPaths().size() > 0)
+ containsFolderLevelSynchronizationRequest = true;
+
for (IProject proj : data.getProjects()) {
projectMapping.put(proj.getName(), data);
}
@@ -62,6 +68,15 @@ public class GitSynchronizeDataSet implements Iterable<GitSynchronizeData> {
}
/**
+ * @return {@code true} when at least one {@link GitSynchronizeData} is
+ * configured to include changes only for particular folder,
+ * {@code false} otherwise
+ */
+ public boolean containsFolderLevelSynchronizationRequest() {
+ return containsFolderLevelSynchronizationRequest;
+ }
+
+ /**
* @return number of {@link GitSynchronizeData} that are included in this
* set
*/
diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml
index 9288d88a0f..dee806b40d 100644
--- a/org.eclipse.egit.ui/plugin.xml
+++ b/org.eclipse.egit.ui/plugin.xml
@@ -48,12 +48,6 @@
menubarPath="team.main/group5">
</action>
<action
- class="org.eclipse.egit.ui.internal.actions.SynchronizeWorkspaceAction"
- id="org.eclipse.egit.ui.internal.actions.SynchronizeWorkspace"
- icon="$nl$/icons/obj16/remotespec.gif"
- label="%SynchronizeWorkspace_label"
- menubarPath="team.main/group3"/>
- <action
class="org.eclipse.egit.ui.internal.actions.MergeAction"
definitionId="org.eclipse.egit.ui.team.Merge"
icon="$nl$/icons/obj16/merge.gif"
@@ -85,6 +79,19 @@
menubarPath="team.main/group1">
</action>
</objectContribution>
+ <objectContribution id="org.eclipse.egit.ui.containerContributions"
+ objectClass="org.eclipse.core.resources.IContainer"
+ adaptable="true">
+ <filter name="projectPersistentProperty"
+ value="org.eclipse.team.core.repository=org.eclipse.egit.core.GitProvider">
+ </filter>
+ <action
+ class="org.eclipse.egit.ui.internal.actions.SynchronizeWorkspaceAction"
+ id="org.eclipse.egit.ui.internal.actions.SynchronizeWorkspace"
+ icon="$nl$/icons/obj16/remotespec.gif"
+ label="%SynchronizeWorkspace_label"
+ menubarPath="team.main/group3"/>
+ </objectContribution>
<objectContribution
adaptable="true"
id="org.eclipse.egit.ui.resourceContributions"
@@ -2683,7 +2690,7 @@
</visibleWhen>
</command>
<separator
- name="org.eclipse.egit.ui.SynchronizeWitchSeparator"
+ name="org.eclipse.egit.ui.SynchronizeWithSeparator"
visible="true" />
<menu
label="%SynchronizeWith_label"
@@ -2693,17 +2700,20 @@
id="org.eclipse.egit.ui.synchronize">
</dynamic>
<visibleWhen checkEnabled="false">
- <and>
- <count value="1" />
- <iterate>
- <and>
- <adapt type="org.eclipse.core.resources.IProject">
- <test property="GitResource.isShared" />
- </adapt>
- </and>
- </iterate>
- </and>
- </visibleWhen>
+ <and>
+ <count value="1" />
+ <iterate>
+ <and>
+ <adapt type="org.eclipse.core.resources.IResource">
+ <and>
+ <test property="GitResource.isShared" />
+ <test property="GitResource.isContainer" />
+ </and>
+ </adapt>
+ </and>
+ </iterate>
+ </and>
+ </visibleWhen>
</menu>
<separator
name="org.eclipse.egit.ui.separator1"
@@ -3321,7 +3331,7 @@
class="org.eclipse.egit.ui.internal.ResourcePropertyTester"
id="org.eclipse.egit.ui.ResourceTester"
namespace="GitResource"
- properties="isShared,isSafe"
+ properties="isShared,isSafe,isContainer"
type="org.eclipse.core.resources.IResource">
</propertyTester>
</extension>
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ResourcePropertyTester.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ResourcePropertyTester.java
index f25227961a..7aaa55d4b4 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ResourcePropertyTester.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ResourcePropertyTester.java
@@ -36,6 +36,9 @@ public class ResourcePropertyTester extends PropertyTester {
.getProject());
return mapping != null
&& SAFE == mapping.getRepository().getRepositoryState();
+ } else if ("isContainer".equals(property)) { //$NON-NLS-1$
+ int type = res.getType();
+ return type == IResource.FOLDER || type == IResource.PROJECT;
}
return false;
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithMenu.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithMenu.java
index 5d66de702c..01ddfd223f 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithMenu.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithMenu.java
@@ -14,9 +14,11 @@ import static org.eclipse.jgit.lib.Constants.R_TAGS;
import java.io.IOException;
import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
@@ -86,12 +88,12 @@ public class SynchronizeWithMenu extends ContributionItem implements
public void fill(final Menu menu, int index) {
if (srv == null)
return;
- final IProject selectedProject = getSelection();
- if (selectedProject == null)
+ final IResource selectedResource = getSelection();
+ if (selectedResource == null)
return;
RepositoryMapping mapping = RepositoryMapping
- .getMapping(selectedProject);
+ .getMapping(selectedResource.getProject());
if (mapping == null)
return;
@@ -145,7 +147,13 @@ public class SynchronizeWithMenu extends ContributionItem implements
GitSynchronizeData data;
try {
data = new GitSynchronizeData(repo, HEAD, name, true);
- GitModelSynchronize.launch(data, new IResource[] { selectedProject });
+ if (!(selectedResource instanceof IProject)) {
+ HashSet<IContainer> containers = new HashSet<IContainer>();
+ containers.add((IContainer) selectedResource);
+ data.setIncludedPaths(containers);
+ }
+
+ GitModelSynchronize.launch(data, new IResource[] { selectedResource });
} catch (IOException e) {
Activator.logError(e.getMessage(), e);
}
@@ -176,7 +184,7 @@ public class SynchronizeWithMenu extends ContributionItem implements
public void initialize(IServiceLocator serviceLocator) {
srv = (ISelectionService) serviceLocator
- .getService(ISelectionService.class);
+ .getService(ISelectionService.class);
}
@Override
@@ -189,7 +197,7 @@ public class SynchronizeWithMenu extends ContributionItem implements
branchImage.dispose();
}
- private IProject getSelection() {
+ private IResource getSelection() {
ISelection sel = srv.getSelection();
if (!(sel instanceof IStructuredSelection))
@@ -197,10 +205,11 @@ public class SynchronizeWithMenu extends ContributionItem implements
Object selected = ((IStructuredSelection) sel).getFirstElement();
if (selected instanceof IAdaptable)
- return (IProject) ((IAdaptable) selected)
- .getAdapter(IProject.class);
- if (selected instanceof IProject)
- return (IProject) selected;
+ return (IResource) ((IAdaptable) selected)
+ .getAdapter(IResource.class);
+
+ if (selected instanceof IResource)
+ return (IResource) selected;
return null;
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWorkspaceActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWorkspaceActionHandler.java
index 19b33470e1..9d035e192c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWorkspaceActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWorkspaceActionHandler.java
@@ -11,9 +11,18 @@ package org.eclipse.egit.ui.internal.actions;
import static org.eclipse.jgit.lib.Constants.HEAD;
import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
import org.eclipse.egit.ui.Activator;
@@ -31,15 +40,21 @@ public class SynchronizeWorkspaceActionHandler extends RepositoryActionHandler {
}
public Object execute(ExecutionEvent event) throws ExecutionException {
- Repository[] repos = getRepositories(event);
+ IResource[] resources = getSelectedResources(event);
+ Map<Repository, Set<IContainer>> containerMap = mapContainerResources(resources);
- if (repos.length == 0)
+ if (containerMap.isEmpty())
return null;
GitSynchronizeDataSet gsdSet = new GitSynchronizeDataSet();
- for (Repository repo : repos)
+ for (Entry<Repository, Set<IContainer>> entry : containerMap.entrySet())
try {
- gsdSet.add(new GitSynchronizeData(repo, HEAD, HEAD, true));
+ GitSynchronizeData data = new GitSynchronizeData(entry.getKey(), HEAD, HEAD, true);
+ Set<IContainer> containers = entry.getValue();
+ if (!containers.isEmpty())
+ data.setIncludedPaths(containers);
+
+ gsdSet.add(data);
} catch (IOException e) {
Activator.handleError(e.getMessage(), e, true);
}
@@ -49,4 +64,26 @@ public class SynchronizeWorkspaceActionHandler extends RepositoryActionHandler {
return null;
}
+ private Map<Repository, Set<IContainer>> mapContainerResources(
+ IResource[] resources) {
+ Map<Repository, Set<IContainer>> result = new HashMap<Repository, Set<IContainer>>();
+
+ for (IResource resource : resources) {
+ RepositoryMapping rm = RepositoryMapping.getMapping(resource);
+ if (resource instanceof IProject)
+ result.put(rm.getRepository(), new HashSet<IContainer>());
+ else if (resource instanceof IContainer) {
+ Set<IContainer> containers = result.get(rm.getRepository());
+ if (containers == null) {
+ containers = new HashSet<IContainer>();
+ result.put(rm.getRepository(), containers);
+ containers.add((IContainer) resource);
+ } else if (containers.size() > 0)
+ containers.add((IContainer) resource);
+ }
+ }
+
+ return result;
+ }
+
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronizeParticipant.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronizeParticipant.java
index fd705a6fbb..aca1eb3cd1 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronizeParticipant.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronizeParticipant.java
@@ -85,18 +85,18 @@ public class GitModelSynchronizeParticipant extends ModelSynchronizeParticipant
ISynchronizePageConfiguration configuration) {
configuration.setProperty(ISynchronizePageConfiguration.P_VIEWER_ID,
VIEWER_ID);
- String modelProvider;
+ String modelProvider = WORKSPACE_MODEL_PROVIDER_ID;
final IPreferenceStore preferenceStore = Activator.getDefault()
.getPreferenceStore();
- if (preferenceStore
- .getBoolean(UIPreferences.SYNC_VIEW_ALWAYS_SHOW_CHANGESET_MODEL)) {
- modelProvider = GitChangeSetModelProvider.ID;
- } else {
- String lastSelectedModel = preferenceStore.getString(UIPreferences.SYNC_VIEW_LAST_SELECTED_MODEL);
- if (!"".equals(lastSelectedModel)) //$NON-NLS-1$
- modelProvider = lastSelectedModel;
- else
- modelProvider = WORKSPACE_MODEL_PROVIDER_ID;
+ if (!gsds.containsFolderLevelSynchronizationRequest()) {
+ if (preferenceStore
+ .getBoolean(UIPreferences.SYNC_VIEW_ALWAYS_SHOW_CHANGESET_MODEL)) {
+ modelProvider = GitChangeSetModelProvider.ID;
+ } else {
+ String lastSelectedModel = preferenceStore.getString(UIPreferences.SYNC_VIEW_LAST_SELECTED_MODEL);
+ if (!"".equals(lastSelectedModel)) //$NON-NLS-1$
+ modelProvider = lastSelectedModel;
+ }
}
configuration.setProperty(
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizard.java
index 854dd64e14..61ad9d0112 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizard.java
@@ -13,19 +13,28 @@ package org.eclipse.egit.ui.internal.synchronize;
import static org.eclipse.jgit.lib.Constants.HEAD;
+import java.io.File;
import java.io.IOException;
+import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
import org.eclipse.egit.ui.UIText;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.ui.ISelectionService;
+import org.eclipse.ui.PlatformUI;
/**
* Synchronization wizard for Git repositories
@@ -56,8 +65,14 @@ public class GitSynchronizeWizard extends Wizard {
boolean shouldIncludeLocal = page.shouldIncludeLocal();
for (Entry<Repository, String> branchesEntry : branches.entrySet())
try {
- gsdSet.add(new GitSynchronizeData(branchesEntry.getKey(), HEAD,
- branchesEntry.getValue(), shouldIncludeLocal));
+ Repository repo = branchesEntry.getKey();
+ GitSynchronizeData data = new GitSynchronizeData(
+ repo, HEAD, branchesEntry.getValue(),
+ shouldIncludeLocal);
+ Set<IContainer> containers = getSelectedContainers(repo);
+ if (containers != null)
+ data.setIncludedPaths(containers);
+ gsdSet.add(data);
} catch (IOException e) {
Activator.logError(e.getMessage(), e);
}
@@ -71,4 +86,38 @@ public class GitSynchronizeWizard extends Wizard {
return true;
}
+ private Set<IContainer> getSelectedContainers(Repository repo) {
+ ISelectionService selectionService = PlatformUI.getWorkbench()
+ .getActiveWorkbenchWindow().getSelectionService();
+ ISelection selection = selectionService.getSelection();
+ if (selection instanceof IStructuredSelection) {
+ Set<IContainer> result = new HashSet<IContainer>();
+ IStructuredSelection sel = (IStructuredSelection) selection;
+ if (sel.size() == 0)
+ return null;
+
+ File workTree = repo.getWorkTree();
+ for (Object o : sel.toArray()) {
+ if (!(o instanceof IAdaptable))
+ continue;
+
+ IResource res = (IResource) ((IAdaptable) o)
+ .getAdapter(IResource.class);
+ if (res == null)
+ continue;
+
+ int type = res.getType();
+ if (type == IResource.FOLDER || type == IResource.PROJECT) {
+ Repository selRepo = RepositoryMapping.getMapping(res)
+ .getRepository();
+ if (workTree.equals(selRepo.getWorkTree()))
+ result.add((IContainer) res);
+ }
+ }
+
+ return result;
+ }
+ return null;
+ }
+
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCache.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCache.java
index 50ff106a8c..1af2f2a191 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCache.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCache.java
@@ -30,6 +30,7 @@ import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
/**
* Git cache representation in EGit Change Set
@@ -47,6 +48,12 @@ public class GitModelCache extends GitModelObjectContainer {
private static final int REMOTE_NTH = 1;
/**
+ * list of paths that needs to be included, {@code null} when all paths
+ * should be included
+ */
+ protected final TreeFilter pathFilter;
+
+ /**
* This interface enables creating proper instance of {@link GitModelBlob}
* for cached and working files. In case of working files the left side
* content of Compare View is loaded from local hard drive.
@@ -89,11 +96,14 @@ public class GitModelCache extends GitModelObjectContainer {
* parent object
* @param baseCommit
* last {@link RevCommit} in repository
+ * @param pathFilter
+ * list of paths that needs to be included, {@code null} when all
+ * paths should be included
* @throws IOException
*/
- public GitModelCache(GitModelObject parent, RevCommit baseCommit)
+ public GitModelCache(GitModelObject parent, RevCommit baseCommit, TreeFilter pathFilter)
throws IOException {
- this(parent, baseCommit, new FileModelFactory() {
+ this(parent, baseCommit, pathFilter, new FileModelFactory() {
public GitModelBlob createFileModel(
GitModelObjectContainer modelParent, RevCommit commit,
@@ -107,18 +117,35 @@ public class GitModelCache extends GitModelObjectContainer {
return false;
}
});
+
+ }
+
+ /**
+ * Constructor used by JUnits
+ *
+ * @param parent
+ * @param baseCommit
+ * @throws IOException
+ */
+ GitModelCache(GitModelObject parent, RevCommit baseCommit)
+ throws IOException {
+ this(parent, baseCommit, null);
}
/**
* @param parent
* @param baseCommit
+ * @param pathFilter
+ * list of paths that needs to be included, {@code null} when all
+ * paths should be included
* @param fileFactory
* @throws IOException
*/
protected GitModelCache(GitModelObject parent, RevCommit baseCommit,
- FileModelFactory fileFactory) throws IOException {
+ TreeFilter pathFilter, FileModelFactory fileFactory) throws IOException {
super(parent, baseCommit, RIGHT);
this.fileFactory = fileFactory;
+ this.pathFilter = pathFilter;
cacheTreeMap = new HashMap<String, GitModelCacheTree>();
location = new Path(getRepository().getWorkTree().toString());
}
@@ -192,6 +219,9 @@ public class GitModelCache extends GitModelObjectContainer {
tw.addTree(new RevWalk(repo).parseTree(headId));
tw.addTree(new DirCacheIterator(index));
+ if (pathFilter != null)
+ tw.setFilter(pathFilter);
+
return tw;
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommit.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommit.java
index b33fca0485..2977b7d1f2 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommit.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommit.java
@@ -22,6 +22,7 @@ import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.revwalk.filter.RevFilter;
import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.team.ui.mapping.ISynchronizationCompareInput;
/**
@@ -34,6 +35,7 @@ public class GitModelCommit extends GitModelObjectContainer implements
* Common ancestor commit for wrapped commit object
*/
protected final RevCommit ancestorCommit;
+ private final TreeFilter pathFilter;
/**
* @param parent
@@ -43,11 +45,13 @@ public class GitModelCommit extends GitModelObjectContainer implements
* instance of commit that will be associated with this model
* object
* @param direction
+ * @param pathFilter
* @throws IOException
*/
public GitModelCommit(GitModelRepository parent, RevCommit commit,
- int direction) throws IOException {
+ int direction, TreeFilter pathFilter) throws IOException {
super(parent, commit, direction);
+ this.pathFilter = pathFilter;
this.ancestorCommit = calculateAncestor(commit);
}
@@ -72,9 +76,23 @@ public class GitModelCommit extends GitModelObjectContainer implements
RevCommit ancestorCommit, int direction) throws IOException {
super(parent, commit, direction);
+ pathFilter = null;
this.ancestorCommit = ancestorCommit;
}
+ /**
+ * Constructor used by JUnits
+ *
+ * @param parent
+ * @param commit
+ * @param direction
+ * @throws IOException
+ */
+ GitModelCommit(GitModelRepository parent, RevCommit commit,
+ int direction) throws IOException {
+ this(parent, commit, direction, null);
+ }
+
@Override
public IPath getLocation() {
return new Path(getRepository().getWorkTree().toString());
@@ -138,6 +156,9 @@ public class GitModelCommit extends GitModelObjectContainer implements
RevWalk rw = new RevWalk(getRepository());
rw.setRevFilter(RevFilter.MERGE_BASE);
+ if (pathFilter != null)
+ rw.setTreeFilter(pathFilter);
+
for (RevCommit parent : actual.getParents()) {
RevCommit parentCommit = rw.parseCommit(parent.getId());
rw.markStart(parentCommit);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepository.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepository.java
index 9eb6cbc6d4..2cd4c993d3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepository.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepository.java
@@ -30,6 +30,7 @@ import org.eclipse.jgit.revwalk.RevFlag;
import org.eclipse.jgit.revwalk.RevFlagSet;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
/**
* Representation of Git repository in Git ChangeSet model.
@@ -44,6 +45,8 @@ public class GitModelRepository extends GitModelObject {
private final Set<IProject> projects;
+ private final TreeFilter pathFilter;
+
private final boolean includeLocal;
private IPath location;
@@ -60,6 +63,7 @@ public class GitModelRepository extends GitModelObject {
repo = data.getRepository();
includeLocal = data.shouldIncludeLocal();
projects = data.getProjects();
+ pathFilter = data.getPathFilter();
srcRev = data.getSrcRevCommit();
dstRev = data.getDstRevCommit();
@@ -152,11 +156,15 @@ public class GitModelRepository extends GitModelObject {
RevWalk rw = new RevWalk(repo);
rw.setRetainBody(true);
+ if (pathFilter != null)
+ rw.setTreeFilter(pathFilter);
+
try {
RevCommit srcCommit = rw.parseCommit(srcRev);
if (includeLocal) {
- GitModelCache gitModelCache = new GitModelCache(this, srcCommit);
+ GitModelCache gitModelCache = new GitModelCache(this,
+ srcCommit, pathFilter);
if (gitModelCache.getChildren().length > 0)
result.add(gitModelCache);
@@ -187,9 +195,11 @@ public class GitModelRepository extends GitModelObject {
break;
if (nextCommit.has(localFlag))
- result.add(new GitModelCommit(this, nextCommit, RIGHT));
+ result.add(new GitModelCommit(this, nextCommit, RIGHT,
+ pathFilter));
else if (nextCommit.has(remoteFlag))
- result.add(new GitModelCommit(this, nextCommit, LEFT));
+ result.add(new GitModelCommit(this, nextCommit, LEFT,
+ pathFilter));
}
} catch (IOException e) {
Activator.logError(e.getMessage(), e);
@@ -200,7 +210,8 @@ public class GitModelRepository extends GitModelObject {
private GitModelWorkingTree getLocaWorkingTreeChanges() {
try {
- GitModelWorkingTree gitModelWorkingTree = new GitModelWorkingTree(this);
+ GitModelWorkingTree gitModelWorkingTree = new GitModelWorkingTree(
+ this, pathFilter);
if (gitModelWorkingTree.getChildren().length > 0)
return gitModelWorkingTree;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingTree.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingTree.java
index 699cbf85b8..85bb90c94f 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingTree.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingTree.java
@@ -21,7 +21,9 @@ import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
import org.eclipse.jgit.treewalk.filter.IndexDiffFilter;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
/**
* Representation of working tree in EGit ChangeSet model
@@ -29,13 +31,25 @@ import org.eclipse.jgit.treewalk.filter.IndexDiffFilter;
public class GitModelWorkingTree extends GitModelCache {
/**
+ * Constructor used by JUnits
+ *
* @param parent
* parent of working tree instance
* @throws IOException
*/
- public GitModelWorkingTree(GitModelObject parent)
+ GitModelWorkingTree(GitModelObject parent) throws IOException {
+ this(parent, null);
+ }
+
+ /**
+ * @param parent
+ * parent of working tree instance
+ * @param pathFilter synchronize configuration
+ * @throws IOException
+ */
+ public GitModelWorkingTree(GitModelObject parent, TreeFilter pathFilter)
throws IOException {
- super(parent, null, new FileModelFactory() {
+ super(parent, null, pathFilter, new FileModelFactory() {
public GitModelBlob createFileModel(
GitModelObjectContainer modelParent, RevCommit modelCommit,
ObjectId repoId, ObjectId cacheId, IPath location)
@@ -96,7 +110,11 @@ public class GitModelWorkingTree extends GitModelCache {
ResourcesPlugin.getWorkspace().getRoot()));
int dirCacheIteratorNth = tw.addTree(new DirCacheIterator(repo.readDirCache()));
IndexDiffFilter idf = new IndexDiffFilter(dirCacheIteratorNth, ftIndex, true);
- tw.setFilter(idf);
+
+ if (pathFilter != null)
+ tw.setFilter(AndTreeFilter.create(pathFilter, idf));
+ else
+ tw.setFilter(idf);
return tw;
}

Back to the top