aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDariusz Luksza2010-07-24 16:26:58 (EDT)
committerDariusz Luksza2010-08-10 13:22:00 (EDT)
commitc5e296c4ef629c948958b0f03b11e1e97af1bb30 (patch)
tree74115735eb5118c50bc7b848be572a2c05ca8495
parent96faaecf12d7e42fb2058b583472b4b733e08594 (diff)
downloadegit-c5e296c4ef629c948958b0f03b11e1e97af1bb30.zip
egit-c5e296c4ef629c948958b0f03b11e1e97af1bb30.tar.gz
egit-c5e296c4ef629c948958b0f03b11e1e97af1bb30.tar.bz2
Preliminary support for ChangeSetsrefs/changes/47/1247/7
Adds proper representation of git changes that occurs between two ref's. Changes are displayed as Team ChangeSet instance. All commits are listed as a child's of node that represent repository. Every commit node contains tree-list of all changed, added or deleted resources. Bug: 318473 CQ: 4400 Change-Id: I198bb3859463ee7e0e230e22cf06761391436cd8 Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com> Signed-off-by: Dariusz Luksza <dariusz@luksza.org>
-rw-r--r--org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparatorTest.java10
-rw-r--r--org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest.java3
-rw-r--r--org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest1.java3
-rw-r--r--org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest2.java3
-rw-r--r--org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeTest.java13
-rw-r--r--org.eclipse.egit.core/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.egit.core/plugin.xml2
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/RevUtils.java55
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitBaseResourceVariantTree.java24
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitBlobResourceVariant.java2
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitFolderResourceVariant.java10
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteResourceVariantTree.java2
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariant.java27
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparator.java4
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberMergeContext.java65
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberResourceMappingContext.java37
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeData.java17
-rw-r--r--org.eclipse.egit.ui/icons/obj16/changelog_obj.gifbin0 -> 596 bytes
-rw-r--r--org.eclipse.egit.ui/plugin.properties2
-rw-r--r--org.eclipse.egit.ui/plugin.xml101
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithActionHandler.java101
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java43
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SynchronizeCommand.java14
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitChangeSetModelProvider.java83
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronizeParticipant.java82
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizard.java8
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitBlobMapping.java47
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetContentProvider.java90
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetLabelProvider.java86
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitCommitChangeSetSorter.java33
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitCommitMapping.java93
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitModelWorkbenchAdapter.java57
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitObjectMapping.java77
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitRepositoryMapping.java48
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitTreeMapping.java60
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitTreeTraversal.java80
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelBlob.java148
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommit.java216
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelObject.java113
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepository.java161
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRoot.java56
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelTree.java150
42 files changed, 2171 insertions, 56 deletions
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparatorTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparatorTest.java
index 4fdcca3..904333a 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparatorTest.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparatorTest.java
@@ -172,15 +172,15 @@ public class GitResourceVariantComparatorTest extends GitTestCase {
+ "keep");
RevCommit commit = testRepo.addAndCommit(iProject, file,
"initial commit");
- String path = Repository.stripWorkDir(repo.getWorkTree(), file);
- IPath iPath = new Path(path);
+ String path = Repository.stripWorkDir(repo.getWorkTree(), file.getParentFile());
+ IPath iPath = new Path(File.separator + path);
IContainer local = createMock(IContainer.class);
- expect(local.exists()).andReturn(true);
- expect(local.getFullPath()).andReturn(iPath);
+ expect(local.exists()).andReturn(true).anyTimes();
+ expect(local.getFullPath()).andReturn(iPath).anyTimes();
replay(local);
- GitFolderResourceVariant remote = new GitFolderResourceVariant(repo,
+ GitFolderResourceVariant remote = new GitFolderResourceVariant(repo,
commit, path);
// then
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest.java
index 32ef364..4c889f5 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest.java
@@ -13,6 +13,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
+import java.io.IOException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
@@ -177,7 +178,7 @@ public class GitResourceVariantTreeSubscriberTest extends GitTestCase {
}
private GitResourceVariantTreeSubscriber createGitResourceVariantTreeSubscriber(
- String src, String dst) {
+ String src, String dst) throws IOException {
GitSynchronizeData gsd = new GitSynchronizeData(repo, src, dst, false);
GitSynchronizeDataSet gsds = new GitSynchronizeDataSet(gsd);
new GitResourceVariantTreeSubscriber(gsds);
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest1.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest1.java
index dd4cb7d..7010d67 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest1.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest1.java
@@ -13,6 +13,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
+import java.io.IOException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
@@ -93,7 +94,7 @@ public class GitResourceVariantTreeSubscriberTest1 extends GitTestCase {
}
private GitResourceVariantTreeSubscriber createGitResourceVariantTreeSubscriber(
- String src, String dst) {
+ String src, String dst) throws IOException {
GitSynchronizeData gsd = new GitSynchronizeData(repo, src, dst, false);
GitSynchronizeDataSet gsds = new GitSynchronizeDataSet(gsd);
new GitResourceVariantTreeSubscriber(gsds);
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest2.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest2.java
index 4a12d33..b00c0cb 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest2.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest2.java
@@ -13,6 +13,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
+import java.io.IOException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
@@ -104,7 +105,7 @@ public class GitResourceVariantTreeSubscriberTest2 extends GitTestCase {
}
private GitResourceVariantTreeSubscriber createGitResourceVariantTreeSubscriber(
- String src, String dst) {
+ String src, String dst) throws IOException {
GitSynchronizeData gsd = new GitSynchronizeData(repo, src, dst, false);
GitSynchronizeDataSet gsds = new GitSynchronizeDataSet(gsd);
new GitResourceVariantTreeSubscriber(gsds);
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeTest.java
index f18972b..073117a 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeTest.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeTest.java
@@ -16,6 +16,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
@@ -70,9 +71,11 @@ public class GitResourceVariantTreeTest extends GitTestCase {
* roots() method should return list of projects that are associated with
* given repository. In this case there is only one project associated with
* this repository therefore only one root should be returned.
+ *
+ * @throws IOException
*/
@Test
- public void shouldReturnOneRoot() {
+ public void shouldReturnOneRoot() throws IOException {
// when
GitSynchronizeData data = new GitSynchronizeData(repo, "", "", false);
GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
@@ -214,8 +217,10 @@ public class GitResourceVariantTreeTest extends GitTestCase {
"initial commit");
IFile mainJava = testRepo.getIFile(iProject, file);
- testRepo.createAndCheckoutBranch(Constants.R_HEADS + Constants.MASTER, Constants.R_HEADS + "test");
- testRepo.appendContentAndCommit(iProject, file, "// test", "first commit");
+ testRepo.createAndCheckoutBranch(Constants.R_HEADS + Constants.MASTER,
+ Constants.R_HEADS + "test");
+ testRepo.appendContentAndCommit(iProject, file, "// test",
+ "first commit");
GitSynchronizeData data = new GitSynchronizeData(repo, Constants.HEAD,
Constants.MASTER, false);
GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
@@ -229,7 +234,7 @@ public class GitResourceVariantTreeTest extends GitTestCase {
assertEquals(fileName, actual.getName());
InputStream actualIn = actual.getStorage(new NullProgressMonitor())
- .getContents();
+ .getContents();
byte[] actualByte = getBytesAndCloseStream(actualIn);
InputStream expectedIn = mainJava.getContents();
byte[] expectedByte = getBytesAndCloseStream(expectedIn);
diff --git a/org.eclipse.egit.core/META-INF/MANIFEST.MF b/org.eclipse.egit.core/META-INF/MANIFEST.MF
index a42ebcb..6b4b26d 100644
--- a/org.eclipse.egit.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.core/META-INF/MANIFEST.MF
@@ -12,7 +12,6 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
org.eclipse.core.filesystem;bundle-version="[1.2.0,2.0.0)"
Export-Package: org.eclipse.egit.core;version="0.9.0",
org.eclipse.egit.core.internal;version="0.9.0";x-internal:=true,
- org.eclipse.egit.core.internal;version="0.9.0";x-internal:=true,
org.eclipse.egit.core.internal.storage;version="0.9.0";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.core.test",
org.eclipse.egit.core.internal.trace;version="0.9.0";x-internal:=true,
org.eclipse.egit.core.internal.util;version="0.9.0";x-friends:="org.eclipse.egit.ui",
diff --git a/org.eclipse.egit.core/plugin.xml b/org.eclipse.egit.core/plugin.xml
index 9b9b1f7..2d23a5a 100644
--- a/org.eclipse.egit.core/plugin.xml
+++ b/org.eclipse.egit.core/plugin.xml
@@ -16,5 +16,5 @@
<ignore
enabled="true"
pattern=".git"/>
- </extension>
+ </extension>
</plugin>
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/RevUtils.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/RevUtils.java
new file mode 100644
index 0000000..1af9163
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/RevUtils.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core;
+
+import java.io.IOException;
+
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.revwalk.filter.RevFilter;
+
+/**
+ * Utility class for obtaining Rev object instances.
+ */
+public class RevUtils {
+
+ private RevUtils() {
+ // non instanciable utility class
+ }
+
+ /**
+ * Finds and returns instance of common ancestor commit for given to
+ * commit's
+ *
+ * @param repo
+ * @param commit1
+ * @param commit2
+ * @return common ancestor for commit1 and commit2 parameters
+ * @throws IOException
+ */
+ public static RevCommit getCommonAncestor(Repository repo,
+ AnyObjectId commit1, AnyObjectId commit2) throws IOException {
+ RevWalk rw = new RevWalk(repo);
+ rw.setRevFilter(RevFilter.MERGE_BASE);
+
+ RevCommit srcRev = rw.parseCommit(commit1);
+ RevCommit dstRev = rw.parseCommit(commit2);
+
+ rw.markStart(dstRev);
+ rw.markStart(srcRev);
+
+ RevCommit result;
+ result = rw.next();
+
+ return result != null ? result : null;
+ }
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitBaseResourceVariantTree.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitBaseResourceVariantTree.java
index 3439028..a2736d6 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitBaseResourceVariantTree.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitBaseResourceVariantTree.java
@@ -13,13 +13,10 @@ package org.eclipse.egit.core.synchronize;
import java.io.IOException;
+import org.eclipse.egit.core.RevUtils;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.revwalk.filter.RevFilter;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.variants.SessionResourceVariantByteStore;
@@ -32,27 +29,12 @@ class GitBaseResourceVariantTree extends GitResourceVariantTree {
@Override
protected RevCommit getRevCommit(GitSynchronizeData gsd)
throws TeamException {
- RevCommit result;
- Repository repo = gsd.getRepository();
- RevWalk rw = new RevWalk(repo);
- rw.setRevFilter(RevFilter.MERGE_BASE);
-
try {
- Ref srcRef = repo.getRef(gsd.getSrcRev());
- Ref dstRef = repo.getRef(gsd.getDstRev());
-
- RevCommit srcRev = rw.parseCommit(srcRef.getObjectId());
- RevCommit dstRev = rw.parseCommit(dstRef.getObjectId());
-
- rw.markStart(dstRev);
- rw.markStart(srcRev);
-
- result = rw.next();
+ return RevUtils.getCommonAncestor(gsd.getRepository(), gsd
+ .getSrcRev().getObjectId(), gsd.getDstRev().getObjectId());
} catch (IOException e) {
throw new TeamException(e.getMessage(), e);
}
-
- return result != null ? result : null;
}
}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitBlobResourceVariant.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitBlobResourceVariant.java
index ff25e50..e8fe895 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitBlobResourceVariant.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitBlobResourceVariant.java
@@ -37,7 +37,7 @@ import org.eclipse.team.core.TeamException;
/**
* This is a representation of a file's blob in some branch.
*/
-class GitBlobResourceVariant extends GitResourceVariant {
+public class GitBlobResourceVariant extends GitResourceVariant {
private IStorage storage;
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitFolderResourceVariant.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitFolderResourceVariant.java
index 2d408e1..f1b406f 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitFolderResourceVariant.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitFolderResourceVariant.java
@@ -28,7 +28,10 @@ import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.variants.IResourceVariant;
-class GitFolderResourceVariant extends GitResourceVariant {
+/**
+ *
+ */
+public class GitFolderResourceVariant extends GitResourceVariant {
private TreeWalk tw;
@@ -51,6 +54,11 @@ class GitFolderResourceVariant extends GitResourceVariant {
return getName().getBytes();
}
+ /**
+ * @param progress
+ * @return members
+ * @throws IOException
+ */
public IResourceVariant[] getMembers(IProgressMonitor progress)
throws IOException {
if (members != null)
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteResourceVariantTree.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteResourceVariantTree.java
index ae90e15..abcfdb8 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteResourceVariantTree.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteResourceVariantTree.java
@@ -37,7 +37,7 @@ class GitRemoteResourceVariantTree extends GitResourceVariantTree {
rw.setRevFilter(RevFilter.MERGE_BASE);
try {
- Ref dstRef = repo.getRef(gsd.getDstRev());
+ Ref dstRef = gsd.getDstRev();
if (dstRef == null)
result = null;
else
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariant.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariant.java
index fa32e27..8ddfc96 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariant.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariant.java
@@ -11,8 +11,12 @@
*******************************************************************************/
package org.eclipse.egit.core.synchronize;
+import java.io.File;
import java.io.IOException;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jgit.lib.ObjectId;
@@ -32,10 +36,15 @@ abstract class GitResourceVariant implements IResourceVariant {
private final RevCommit revCommit;
+ private final String path;
+
private String name;
private IPath fullPath;
+ private static final IWorkspaceRoot workspaceRoot = ResourcesPlugin
+ .getWorkspace().getRoot();
+
/**
* Construct Git representation of {@link IResourceVariant}.
*
@@ -49,6 +58,7 @@ abstract class GitResourceVariant implements IResourceVariant {
throws IOException {
this.repo = repo;
this.revCommit = revCommit;
+ this.path = path;
TreeWalk tw = getTreeWalk(repo, revCommit.getTree(), path);
if (tw == null) {
objectId = null;
@@ -125,8 +135,21 @@ abstract class GitResourceVariant implements IResourceVariant {
}
protected IPath getFullPath() {
- if (fullPath == null)
- fullPath = new Path(variantPath);
+ if (fullPath == null) {
+ IResource resource;
+ IPath location = new Path(repo.getWorkTree() + File.separator
+ + path);
+
+ if (isContainer())
+ resource = workspaceRoot.getContainerForLocation(location);
+ else
+ resource = workspaceRoot.getFileForLocation(location);
+
+ if (resource != null)
+ fullPath = resource.getFullPath();
+ else
+ fullPath = new Path(path);
+ }
return fullPath;
}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparator.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparator.java
index ae8cf69..9270382 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparator.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparator.java
@@ -99,7 +99,9 @@ class GitResourceVariantComparator implements IResourceVariantComparator {
GitResourceVariant gitRemote = (GitResourceVariant) remote;
boolean exists = gitBase.exists() && gitRemote.exists();
- return exists && gitBase.getObjectId().equals(gitRemote.getObjectId());
+ boolean equalType = !(gitBase.isContainer() ^ gitRemote.isContainer());
+ return equalType && exists
+ && gitBase.getObjectId().equals(gitRemote.getObjectId());
}
public boolean isThreeWay() {
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberMergeContext.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberMergeContext.java
new file mode 100644
index 0000000..2482232
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberMergeContext.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.synchronize;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.team.core.diff.IDiff;
+import org.eclipse.team.core.mapping.ISynchronizationScopeManager;
+import org.eclipse.team.core.subscribers.Subscriber;
+import org.eclipse.team.core.subscribers.SubscriberMergeContext;
+
+/**
+ *
+ */
+public class GitSubscriberMergeContext extends SubscriberMergeContext {
+
+ private final GitSynchronizeDataSet gsds;
+
+ /**
+ * @param subscriber
+ * @param manager
+ * @param gsds
+ */
+ public GitSubscriberMergeContext(Subscriber subscriber,
+ ISynchronizationScopeManager manager, GitSynchronizeDataSet gsds) {
+ super(subscriber, manager);
+ this.gsds = gsds;
+
+ initialize();
+ }
+
+ public void markAsMerged(IDiff node, boolean inSyncHint,
+ IProgressMonitor monitor) throws CoreException {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void reject(IDiff diff, IProgressMonitor monitor)
+ throws CoreException {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * @return git synchronization data
+ */
+ public GitSynchronizeDataSet getSyncData() {
+ return gsds;
+ }
+
+ @Override
+ protected void makeInSync(IDiff diff, IProgressMonitor monitor)
+ throws CoreException {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberResourceMappingContext.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberResourceMappingContext.java
new file mode 100644
index 0000000..f24a189
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberResourceMappingContext.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.synchronize;
+
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.team.core.subscribers.SubscriberResourceMappingContext;
+
+/**
+ *
+ */
+public class GitSubscriberResourceMappingContext extends
+ SubscriberResourceMappingContext {
+
+ private final GitSynchronizeDataSet data;
+
+ /**
+ * @param data
+ */
+ public GitSubscriberResourceMappingContext(GitSynchronizeDataSet data) {
+ super(new GitResourceVariantTreeSubscriber(data), true);
+ this.data = data;
+ }
+
+ /**
+ * @return git synchronize data set
+ */
+ public GitSynchronizeDataSet getSyncData() {
+ return data;
+ }
+
+}
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 e1296b3..10d1e06 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
@@ -9,6 +9,7 @@
package org.eclipse.egit.core.synchronize.dto;
import java.io.File;
+import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -16,6 +17,7 @@ import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
/**
@@ -28,9 +30,9 @@ public class GitSynchronizeData {
private final Repository repo;
- private final String srcRev;
+ private final Ref srcRev;
- private final String dstRev;
+ private final Ref dstRev;
private final Set<IProject> projects;
@@ -45,12 +47,13 @@ public class GitSynchronizeData {
* @param includeLocal
* <code>true</code> if local changes should be included in
* comparison
+ * @throws IOException
*/
public GitSynchronizeData(Repository repository, String srcRev,
- String dstRev, boolean includeLocal) {
+ String dstRev, boolean includeLocal) throws IOException {
repo = repository;
- this.srcRev = srcRev;
- this.dstRev = dstRev;
+ this.srcRev = repo.getRef(srcRev);
+ this.dstRev = repo.getRef(dstRev);
this.includeLocal = includeLocal;
repoParentPath = repo.getDirectory().getParentFile().getAbsolutePath();
@@ -75,14 +78,14 @@ public class GitSynchronizeData {
/**
* @return synchronize source rev name
*/
- public String getSrcRev() {
+ public Ref getSrcRev() {
return srcRev;
}
/**
* @return synchronize destination rev name
*/
- public String getDstRev() {
+ public Ref getDstRev() {
return dstRev;
}
diff --git a/org.eclipse.egit.ui/icons/obj16/changelog_obj.gif b/org.eclipse.egit.ui/icons/obj16/changelog_obj.gif
new file mode 100644
index 0000000..f988003
--- /dev/null
+++ b/org.eclipse.egit.ui/icons/obj16/changelog_obj.gif
Binary files differ
diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties
index ce920a1..26665be 100644
--- a/org.eclipse.egit.ui/plugin.properties
+++ b/org.eclipse.egit.ui/plugin.properties
@@ -126,6 +126,8 @@ GitRepositoriesView_name = Git Repositories
GitCategory_name = Git
GitRepositoryPerspective_name = Git Repository Exploring
Synchronize_Name=Git
+Synchronize_ModelName=Git model participant
+Synchronize_ChangeSet=Git Change Sets
ApplyPatchAction_label=Appl&y Patch...
GitRepositoriesContentName = Git Repositories
diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml
index c2cf8f1..e8f48ad 100644
--- a/org.eclipse.egit.ui/plugin.xml
+++ b/org.eclipse.egit.ui/plugin.xml
@@ -212,6 +212,64 @@
type="org.eclipse.team.ui.history.IHistoryPageSource">
</adapter>
</factory>
+ <factory
+ adaptableType="org.eclipse.egit.ui.internal.synchronize.model.GitModelRoot"
+ class="org.eclipse.egit.ui.internal.factories.GitAdapterFactory">
+ <adapter
+ type="org.eclipse.ui.model.IWorkbenchAdapter"/>
+ </factory>
+ <factory
+ adaptableType="org.eclipse.egit.ui.internal.synchronize.model.GitModelRepository"
+ class="org.eclipse.egit.ui.internal.factories.GitAdapterFactory">
+ <adapter
+ type="org.eclipse.ui.model.IWorkbenchAdapter"/>
+ </factory>
+ <factory
+ adaptableType="org.eclipse.egit.ui.internal.synchronize.model.GitModelCommit"
+ class="org.eclipse.egit.ui.internal.factories.GitAdapterFactory">
+ <adapter
+ type="org.eclipse.ui.model.IWorkbenchAdapter"/>
+ </factory>
+ <factory
+ adaptableType="org.eclipse.egit.ui.internal.synchronize.model.GitModelTree"
+ class="org.eclipse.egit.ui.internal.factories.GitAdapterFactory">
+ <adapter
+ type="org.eclipse.ui.model.IWorkbenchAdapter"/>
+ </factory>
+ <factory
+ adaptableType="org.eclipse.egit.ui.internal.synchronize.model.GitModelBlob"
+ class="org.eclipse.egit.ui.internal.factories.GitAdapterFactory">
+ <adapter
+ type="org.eclipse.ui.model.IWorkbenchAdapter"/>
+ </factory>
+ <factory
+ adaptableType="org.eclipse.egit.ui.internal.synchronize.model.GitModelObject"
+ class="org.eclipse.egit.ui.internal.factories.GitAdapterFactory">
+ <adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/>
+ <adapter type="org.eclipse.core.resources.IResource"/>
+ </factory>
+ <factory
+ adaptableType="org.eclipse.egit.ui.internal.synchronize.model.GitModelRepository"
+ class="org.eclipse.egit.ui.internal.factories.GitAdapterFactory">
+ <adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/>
+ </factory>
+ <factory
+ adaptableType="org.eclipse.egit.ui.internal.synchronize.model.GitModelCommit"
+ class="org.eclipse.egit.ui.internal.factories.GitAdapterFactory">
+ <adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/>
+ </factory>
+ <factory
+ adaptableType="org.eclipse.egit.ui.internal.synchronize.model.GitModelTree"
+ class="org.eclipse.egit.ui.internal.factories.GitAdapterFactory">
+ <adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/>
+ <adapter type="org.eclipse.core.resources.IResource"/>
+ </factory>
+ <factory
+ adaptableType="org.eclipse.egit.ui.internal.synchronize.model.GitModelBlob"
+ class="org.eclipse.egit.ui.internal.factories.GitAdapterFactory">
+ <adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/>
+ <adapter type="org.eclipse.core.resources.IResource"/>
+ </factory>
</extension>
<extension point="org.eclipse.ui.preferencePages">
@@ -1586,6 +1644,18 @@
</linkHelper>
</extension>
<extension
+ id="changeSetModel"
+ name="Git Change Set"
+ point="org.eclipse.core.resources.modelProviders">
+ <modelProvider
+ class="org.eclipse.egit.ui.internal.synchronize.GitChangeSetModelProvider"/>
+ <enablement>
+ <instanceof
+ value="org.eclipse.core.resources.IResource" />
+ </enablement>
+ <extends-model id="org.eclipse.core.resources.modelProvider"/>
+ </extension>
+ <extension
point="org.eclipse.team.ui.synchronizeWizards">
<wizard
class="org.eclipse.egit.ui.internal.synchronize.GitSynchronizeWizard"
@@ -1604,6 +1674,37 @@
name="%Synchronize_Name"
persistent="false">
</participant>
+ <participant
+ class="org.eclipse.egit.ui.internal.synchronize.GitModelSynchronizeParticipant"
+ id="org.eclipse.egit.ui.modelCompareParticipant"
+ name="%Synchronize_ModelName"
+ persistent="false"/>
+ </extension>
+ <extension
+ point="org.eclipse.ui.navigator.navigatorContent">
+ <navigatorContent
+ activeByDefault="true"
+ contentProvider="org.eclipse.egit.ui.internal.synchronize.mapping.GitChangeSetContentProvider"
+ icon="$nl$/icons/obj16/changelog_obj.gif"
+ id="org.eclipse.egit.ui.changeSetContent"
+ labelProvider="org.eclipse.egit.ui.internal.synchronize.mapping.GitChangeSetLabelProvider"
+ name="%Synchronize_ChangeSet"
+ priority="normal">
+ <enablement>
+ <or>
+ <instanceof value="org.eclipse.egit.ui.internal.synchronize.GitChangeSetModelProvider"/>
+ </or>
+ </enablement>
+ <commonSorter
+ class="org.eclipse.egit.ui.internal.synchronize.mapping.GitCommitChangeSetSorter"/>
+ </navigatorContent>
+ </extension>
+ <extension
+ point="org.eclipse.team.ui.teamContentProviders">
+ <teamContentProvider
+ contentExtensionId="org.eclipse.egit.ui.changeSetContent"
+ icon="$nl$/icons/obj16/changelog_obj.gif"
+ modelProviderId="org.eclipse.egit.ui.changeSetModel"/>
</extension>
<extension
name="%TeamMenuCommandsLabel"
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithActionHandler.java
index 80e94f2..f869539 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithActionHandler.java
@@ -17,11 +17,18 @@ import java.util.Set;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.mapping.RemoteResourceMappingContext;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.egit.core.synchronize.GitResourceVariantTreeSubscriber;
+import org.eclipse.egit.core.synchronize.GitSubscriberMergeContext;
+import org.eclipse.egit.core.synchronize.GitSubscriberResourceMappingContext;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIText;
-import org.eclipse.egit.ui.internal.synchronize.GitSynchronize;
+import org.eclipse.egit.ui.internal.synchronize.GitModelSynchronizeParticipant;
import org.eclipse.egit.ui.internal.synchronize.SelectSynchronizeResourceDialog;
import org.eclipse.egit.ui.internal.synchronize.SyncRepoEntity;
import org.eclipse.egit.ui.internal.synchronize.SyncRepoEntity.SyncRefEntity;
@@ -31,6 +38,16 @@ import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.RemoteConfig;
+import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.team.core.mapping.provider.SynchronizationContext;
+import org.eclipse.team.core.subscribers.SubscriberScopeManager;
+import org.eclipse.team.internal.ui.TeamUIPlugin;
+import org.eclipse.team.internal.ui.Utils;
+import org.eclipse.team.internal.ui.actions.TeamAction;
+import org.eclipse.team.ui.TeamUI;
+import org.eclipse.team.ui.synchronize.ISynchronizeParticipant;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
/**
* An action that launch synchronization with selected repository
@@ -67,7 +84,19 @@ public class SynchronizeWithActionHandler extends RepositoryActionHandler {
}
}
- new GitSynchronize(gsdSet);
+ GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(
+ gsdSet);
+ ResourceMapping[] mappings = getSelectedResourceMappings(event);
+ RemoteResourceMappingContext remoteContext = new GitSubscriberResourceMappingContext(gsdSet);
+ SubscriberScopeManager manager = new SubscriberScopeManager(
+ subscriber.getName(), mappings, subscriber, remoteContext, true);
+ SynchronizationContext context = new GitSubscriberMergeContext(
+ subscriber, manager, gsdSet);
+ GitModelSynchronizeParticipant participant = new GitModelSynchronizeParticipant(context);
+ TeamUI.getSynchronizeManager().addSynchronizeParticipants(
+ new ISynchronizeParticipant[] { participant });
+ participant.run(getTargetPart());
+
return null;
}
@@ -121,4 +150,72 @@ public class SynchronizeWithActionHandler extends RepositoryActionHandler {
return refDb.getRefs(Constants.R_REMOTES + remoteName + "/").values(); //$NON-NLS-1$
}
+
+ /**
+ * Based on {@link TeamAction#getSelectedResourceMappings}
+ *
+ * @param event
+ * @return the resource mappings that contain resources associated with the given provider
+ * @throws ExecutionException
+ */
+ private ResourceMapping[] getSelectedResourceMappings(ExecutionEvent event) throws ExecutionException {
+ Object[] elements = getSelectedResources(event);
+ ArrayList providerMappings = new ArrayList();
+ for (int i = 0; i < elements.length; i++) {
+ Object object = elements[i];
+ Object adapted = getResourceMapping(object);
+ if (adapted instanceof ResourceMapping) {
+ ResourceMapping mapping = (ResourceMapping) adapted;
+ if (isMappedToProvider(mapping, "org.eclipse.egit.core.GitProvider")) { //$NON-NLS-1$
+ providerMappings.add(mapping);
+ }
+ }
+ }
+ return (ResourceMapping[]) providerMappings.toArray(new ResourceMapping[providerMappings.size()]);
+ }
+
+ /**
+ * Copied from TeamAction#getResourceMapping(Object)
+ *
+ * @param object
+ * @return resource mapping
+ */
+ private Object getResourceMapping(Object object) {
+ if (object instanceof ResourceMapping)
+ return object;
+
+ if (object instanceof IAdaptable)
+ return ((IAdaptable) object).getAdapter(ResourceMapping.class);
+
+ return Utils.getResourceMapping(object);
+ }
+
+ /**
+ * Copied from TeamAction#isMappedToProvider(ResourceMapping, String)
+ *
+ * @param element
+ * @param providerId
+ * @return TODO
+ */
+ private boolean isMappedToProvider(ResourceMapping element, String providerId) {
+ IProject[] projects = element.getProjects();
+ for (int k = 0; k < projects.length; k++) {
+ IProject project = projects[k];
+ RepositoryProvider provider = RepositoryProvider.getProvider(project);
+ if (provider != null && provider.getID().equals(providerId)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private IWorkbenchPart getTargetPart() {
+ IWorkbenchPart targetPart = null;
+ IWorkbenchPage page = TeamUIPlugin.getActivePage();
+ if (page != null) {
+ targetPart = page.getActivePart();
+ }
+ return targetPart;
+ }
+
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java
index 5df0448..36ac91a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/factories/GitAdapterFactory.java
@@ -1,6 +1,7 @@
/*******************************************************************************
* Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -9,9 +10,20 @@
*******************************************************************************/
package org.eclipse.egit.ui.internal.factories;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.egit.ui.GitHistoryPageSource;
+import org.eclipse.egit.ui.internal.synchronize.mapping.GitModelWorkbenchAdapter;
+import org.eclipse.egit.ui.internal.synchronize.mapping.GitObjectMapping;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelBlob;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelObject;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelTree;
import org.eclipse.team.ui.history.IHistoryPageSource;
+import org.eclipse.team.ui.mapping.ISynchronizationCompareAdapter;
+import org.eclipse.ui.model.IWorkbenchAdapter;
/**
* This class is an intelligent "cast" operation for getting
@@ -21,18 +33,45 @@ import org.eclipse.team.ui.history.IHistoryPageSource;
public class GitAdapterFactory implements IAdapterFactory {
private Object historyPageSource = new GitHistoryPageSource();
+ private GitModelWorkbenchAdapter gitModelWorkbenchAdapter;
+
+ private static final IWorkspaceRoot root = ResourcesPlugin.getWorkspace()
+ .getRoot();
@SuppressWarnings("unchecked")
public Object getAdapter(Object adaptableObject, Class adapterType) {
if (adapterType.isAssignableFrom(IHistoryPageSource.class)) {
return historyPageSource;
}
+
+ if (IWorkbenchAdapter.class == adapterType) {
+ if (gitModelWorkbenchAdapter == null)
+ gitModelWorkbenchAdapter = new GitModelWorkbenchAdapter();
+ return gitModelWorkbenchAdapter;
+ }
+
+ if (adaptableObject instanceof GitModelObject
+ && adapterType == ResourceMapping.class)
+ return GitObjectMapping.create((GitModelObject) adaptableObject);
+
+ if (adaptableObject instanceof GitModelObject
+ && adapterType == IResource.class) {
+ GitModelObject obj = (GitModelObject) adaptableObject;
+
+ if (obj instanceof GitModelBlob)
+ return root.getFileForLocation(obj.getLocation());
+
+ if (obj instanceof GitModelTree)
+ return root.getContainerForLocation(obj.getLocation());
+ }
+
return null;
}
public Class[] getAdapterList() {
- // TODO Auto-generated method stub
- return null;
+ return new Class[] { IHistoryPageSource.class,
+ ISynchronizationCompareAdapter.class, ResourceMapping.class,
+ IResource.class };
}
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SynchronizeCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SynchronizeCommand.java
index ff7f79d..e447452 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SynchronizeCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SynchronizeCommand.java
@@ -11,12 +11,15 @@
*******************************************************************************/
package org.eclipse.egit.ui.internal.repository.tree.command;
+import java.io.IOException;
+
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
import org.eclipse.egit.ui.UIText;
import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
@@ -46,10 +49,15 @@ public class SynchronizeCommand extends
@Override
protected IStatus run(IProgressMonitor monitor) {
- GitSynchronizeData data = new GitSynchronizeData(node
- .getRepository(), Constants.HEAD, ref.getName(), false);
+ GitSynchronizeData data;
+ try {
+ data = new GitSynchronizeData(node
+ .getRepository(), Constants.HEAD, ref.getName(), false);
- new GitSynchronize(data);
+ new GitSynchronize(data);
+ } catch (IOException e) {
+ Activator.logError(e.getMessage(), e);
+ }
return Status.OK_STATUS;
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitChangeSetModelProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitChangeSetModelProvider.java
new file mode 100644
index 0000000..6ce5725
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitChangeSetModelProvider.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.mapping.ModelProvider;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.resources.mapping.ResourceMappingContext;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.synchronize.GitSubscriberResourceMappingContext;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelObject;
+
+/**
+ * Represents the provider of Git logical model.
+ */
+public class GitChangeSetModelProvider extends ModelProvider {
+
+ /**
+ * Id of model provider
+ */
+ public static final String ID = "org.eclipse.egit.ui.changeSetModel"; //$NON-NLS-1$
+
+ private static GitChangeSetModelProvider provider;
+
+ /**
+ * @return provider instance or <code>null</code> if provider was not
+ * initialized
+ */
+ public static GitChangeSetModelProvider getProvider() {
+ if (provider == null) {
+ ModelProvider modelProvider;
+ try {
+ modelProvider = ModelProvider.getModelProviderDescriptor(ID)
+ .getModelProvider();
+ provider = (GitChangeSetModelProvider) modelProvider;
+ } catch (CoreException e) {
+ Activator.logError(e.getMessage(), e);
+ }
+ }
+
+ return provider;
+ }
+
+ @Override
+ public ResourceMapping[] getMappings(IResource resource,
+ ResourceMappingContext context, IProgressMonitor monitor)
+ throws CoreException {
+ if (context instanceof GitSubscriberResourceMappingContext) {
+ GitSubscriberResourceMappingContext gitContext = (GitSubscriberResourceMappingContext) context;
+ GitSynchronizeDataSet gsds = gitContext.getSyncData();
+ GitSynchronizeData data = gsds.getData(resource.getProject());
+
+ if (data != null) {
+ GitModelObject object = null;
+ try {
+ object = GitModelObject.createRoot(data);
+ } catch (IOException e) {
+ Activator.logError(e.getMessage(), e);
+ }
+
+ if (object != null) {
+ ResourceMapping rm = (ResourceMapping) object
+ .getAdapter(ResourceMapping.class);
+ return new ResourceMapping[] { rm };
+ }
+ }
+ }
+
+ return super.getMappings(resource, context, monitor);
+ }
+}
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
new file mode 100644
index 0000000..f7204b3
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronizeParticipant.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize;
+
+import org.eclipse.core.resources.mapping.ModelProvider;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.egit.core.Activator;
+import org.eclipse.team.core.mapping.provider.SynchronizationContext;
+import org.eclipse.team.ui.TeamUI;
+import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
+import org.eclipse.team.ui.synchronize.ModelSynchronizeParticipant;
+
+/**
+ * Git model synchronization participant
+ */
+public class GitModelSynchronizeParticipant extends ModelSynchronizeParticipant {
+
+ /**
+ * Id of model compare participant
+ */
+ public static final String ID = "org.eclipse.egit.ui.modelCompareParticipant"; //$NON-NLS-1$
+
+ /**
+ * Id of model synchronization participant
+ */
+ public static final String VIEWER_ID = "org.eclipse.egit.ui.compareSynchronization"; //$NON-NLS-1$
+
+ /**
+ * Creates {@link GitModelSynchronizeParticipant} for given context
+ *
+ * @param context
+ */
+ public GitModelSynchronizeParticipant(SynchronizationContext context) {
+ super(context);
+ try {
+ setInitializationData(TeamUI.getSynchronizeManager()
+ .getParticipantDescriptor(ID));
+ } catch (CoreException e) {
+ Activator.logError(e.getMessage(), e);
+ }
+
+ setSecondaryId(Long.toString(System.currentTimeMillis()));
+ }
+
+ protected void initializeConfiguration(
+ ISynchronizePageConfiguration configuration) {
+ configuration.setProperty(ISynchronizePageConfiguration.P_VIEWER_ID,
+ VIEWER_ID);
+ super.initializeConfiguration(configuration);
+ }
+
+ @Override
+ public ModelProvider[] getEnabledModelProviders() {
+ ModelProvider[] enabledProviders = super.getEnabledModelProviders();
+ for (int i = 0; i < enabledProviders.length; i++) {
+ ModelProvider provider = enabledProviders[i];
+ if (provider.getId().equals(GitChangeSetModelProvider.ID))
+ return enabledProviders;
+ }
+
+ ModelProvider[] extended = new ModelProvider[enabledProviders.length + 1];
+ for (int i = 0; i < enabledProviders.length; i++) {
+ extended[i] = enabledProviders[i];
+ }
+
+ GitChangeSetModelProvider provider = GitChangeSetModelProvider
+ .getProvider();
+
+ if (provider == null)
+ return enabledProviders;
+
+ extended[extended.length - 1] = provider;
+ return extended;
+ }
+
+}
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 42e418c..5cdd0b8 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
@@ -11,8 +11,10 @@
*******************************************************************************/
package org.eclipse.egit.ui.internal.synchronize;
+import java.io.IOException;
import java.util.Map;
+import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
import org.eclipse.egit.ui.UIText;
@@ -47,7 +49,11 @@ public class GitSynchronizeWizard extends Wizard {
Map<Repository, String> branches = page.getSelectedBranches();
for (Repository repo : branches.keySet())
- gsdSet.add(new GitSynchronizeData(repo, Constants.HEAD, branches.get(repo), false));
+ try {
+ gsdSet.add(new GitSynchronizeData(repo, Constants.HEAD, branches.get(repo), false));
+ } catch (IOException e) {
+ Activator.logError(e.getMessage(), e);
+ }
new GitSynchronize(gsdSet);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitBlobMapping.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitBlobMapping.java
new file mode 100644
index 0000000..e8c59d9
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitBlobMapping.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.mapping;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.mapping.ResourceMappingContext;
+import org.eclipse.core.resources.mapping.ResourceTraversal;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelBlob;
+
+class GitBlobMapping extends GitObjectMapping {
+
+ private final GitModelBlob gitBlob;
+
+ private final static IWorkspaceRoot workspaceRoot = ResourcesPlugin
+ .getWorkspace().getRoot();
+
+ GitBlobMapping(GitModelBlob gitBlob) {
+ super(gitBlob);
+ this.gitBlob = gitBlob;
+ }
+
+ @Override
+ public ResourceTraversal[] getTraversals(ResourceMappingContext context,
+ IProgressMonitor monitor) throws CoreException {
+ IPath path = gitBlob.getLocation();
+ IResource file = workspaceRoot.getFileForLocation(path);
+
+ if (file != null)
+ return new ResourceTraversal[] { new ResourceTraversal(
+ new IResource[] { file }, IResource.DEPTH_ZERO,
+ IResource.ALLOW_MISSING_LOCAL) };
+
+ return new ResourceTraversal[0];
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetContentProvider.java
new file mode 100644
index 0000000..db1119a
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetContentProvider.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.mapping;
+
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.resources.mapping.ResourceMappingContext;
+import org.eclipse.core.resources.mapping.ResourceTraversal;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.synchronize.GitSubscriberMergeContext;
+import org.eclipse.egit.core.synchronize.GitSubscriberResourceMappingContext;
+import org.eclipse.egit.ui.internal.synchronize.GitChangeSetModelProvider;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelRoot;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.team.core.mapping.ISynchronizationContext;
+import org.eclipse.team.ui.mapping.SynchronizationContentProvider;
+import org.eclipse.ui.model.WorkbenchContentProvider;
+
+/**
+ * Git's variant of {@link SynchronizationContentProvider}. This class creates
+ * model root of change set and base {@link ResourceTraversal}'s.
+ */
+public class GitChangeSetContentProvider extends SynchronizationContentProvider {
+
+ private ITreeContentProvider provider;
+
+ private GitModelRoot modelRoot;
+
+ @Override
+ protected ITreeContentProvider getDelegateContentProvider() {
+ if (provider == null)
+ provider = new WorkbenchContentProvider();
+
+ return provider;
+ }
+
+ @Override
+ protected String getModelProviderId() {
+ return GitChangeSetModelProvider.ID;
+ }
+
+ @Override
+ protected Object getModelRoot() {
+ if (modelRoot == null) {
+ GitSubscriberMergeContext context = (GitSubscriberMergeContext) getContext();
+ modelRoot = new GitModelRoot(context.getSyncData());
+ }
+
+ return modelRoot;
+ }
+
+ @Override
+ protected ResourceTraversal[] getTraversals(
+ ISynchronizationContext context, Object object) {
+ if (object instanceof IAdaptable) {
+ ResourceMapping rm = getResourceMapping(object);
+ GitSubscriberMergeContext ctx = (GitSubscriberMergeContext) getContext();
+ ResourceMappingContext rmCtx = new GitSubscriberResourceMappingContext(
+ ctx.getSyncData());
+ try {
+ return rm.getTraversals(rmCtx, new NullProgressMonitor());
+ } catch (CoreException e) {
+ Activator.logError(e.getMessage(), e);
+ }
+ }
+ return null;
+ }
+
+ private ResourceMapping getResourceMapping(Object object) {
+ return (ResourceMapping) ((IAdaptable) object)
+ .getAdapter(ResourceMapping.class);
+ }
+
+ @Override
+ public void dispose() {
+ if (provider != null)
+ provider.dispose();
+
+ super.dispose();
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetLabelProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetLabelProvider.java
new file mode 100644
index 0000000..11da2ae
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetLabelProvider.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.mapping;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.egit.ui.UIIcons;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelBlob;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelCommit;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelObject;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelRepository;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelTree;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.team.ui.mapping.SynchronizationLabelProvider;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+
+/**
+ * Label provider for Git ChangeSet model.
+ */
+public class GitChangeSetLabelProvider extends SynchronizationLabelProvider {
+
+ private static final ILabelProvider workbenchLabelProvider = WorkbenchLabelProvider
+ .getDecoratingWorkbenchLabelProvider();
+
+ private LabelProvider delegateLabelProvider;
+
+ @Override
+ protected ILabelProvider getDelegateLabelProvider() {
+ if (delegateLabelProvider == null)
+ delegateLabelProvider = new DelegateLabelProvider();
+
+ return delegateLabelProvider;
+ }
+
+ private static class DelegateLabelProvider extends LabelProvider {
+
+ private final ResourceManager fImageCache = new LocalResourceManager(
+ JFaceResources.getResources());
+
+ public String getText(Object element) {
+ if (element instanceof GitModelObject)
+ return ((GitModelObject) element).getName();
+
+ return null;
+ }
+
+ public Image getImage(Object element) {
+ if (element instanceof GitModelBlob) {
+ Object adapter = ((GitModelBlob) element)
+ .getAdapter(IResource.class);
+ return workbenchLabelProvider.getImage(adapter);
+ }
+
+ if (element instanceof GitModelTree) {
+ Object adapter = ((GitModelTree) element)
+ .getAdapter(IResource.class);
+ return workbenchLabelProvider.getImage(adapter);
+ }
+
+ if (element instanceof GitModelCommit)
+ return fImageCache.createImage(UIIcons.PUSH);
+
+ if (element instanceof GitModelRepository)
+ return fImageCache.createImage(UIIcons.REPOSITORY);
+
+ return super.getImage(element);
+ }
+
+ @Override
+ public void dispose() {
+ fImageCache.dispose();
+ super.dispose();
+ }
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitCommitChangeSetSorter.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitCommitChangeSetSorter.java
new file mode 100644
index 0000000..2e15581
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitCommitChangeSetSorter.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.mapping;
+
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelCommit;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.jgit.revwalk.RevCommit;
+
+/**
+ * Sorter that order commits in Git Change Set by commit time;
+ */
+public class GitCommitChangeSetSorter extends ViewerSorter {
+
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ if (e1 instanceof GitModelCommit && e2 instanceof GitModelCommit) {
+ RevCommit rc1 = ((GitModelCommit) e1).getRemoteCommit();
+ RevCommit rc2 = ((GitModelCommit) e2).getRemoteCommit();
+
+ return rc2.getCommitTime() - rc1.getCommitTime();
+ }
+
+ return super.compare(viewer, e1, e2);
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitCommitMapping.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitCommitMapping.java
new file mode 100644
index 0000000..77fb2ef
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitCommitMapping.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.mapping;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.mapping.ResourceMappingContext;
+import org.eclipse.core.resources.mapping.ResourceTraversal;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelCommit;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+
+class GitCommitMapping extends GitObjectMapping {
+
+ private final GitModelCommit gitCommit;
+
+ public GitCommitMapping(GitModelCommit gitCommit) {
+ super(gitCommit);
+ this.gitCommit = gitCommit;
+ }
+
+ @Override
+ public ResourceTraversal[] getTraversals(ResourceMappingContext context,
+ IProgressMonitor monitor) throws CoreException {
+ Repository repo = gitCommit.getRepository();
+ TreeWalk tw = new TreeWalk(repo);
+ List<ResourceTraversal> result = new ArrayList<ResourceTraversal>();
+ IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+
+ tw.reset();
+ tw.setRecursive(false);
+ tw.setFilter(TreeFilter.ANY_DIFF);
+ try {
+ RevCommit commit = gitCommit.getRemoteCommit();
+ tw.addTree(commit.getParent(0).getTree());
+ int nth = tw.addTree(commit.getTree());
+
+ while (tw.next()) {
+ ResourceTraversal traversal = getTraversal(tw, workspaceRoot,
+ nth);
+
+ if (traversal != null)
+ result.add(traversal);
+ }
+ } catch (IOException e) {
+ Activator.logError(e.getMessage(), e);
+ }
+
+ return result.toArray(new ResourceTraversal[result.size()]);
+ }
+
+ private ResourceTraversal getTraversal(TreeWalk tw,
+ IWorkspaceRoot workspaceRoot, int nth) {
+ IPath path = gitCommit.getLocation().append(tw.getPathString());
+ int objectType = tw.getFileMode(nth).getObjectType();
+
+ ResourceTraversal traversal = null;
+ if (objectType == Constants.OBJ_BLOB) {
+ IFile file = workspaceRoot.getFileForLocation(path);
+ if (file != null)
+ traversal = new ResourceTraversal(new IResource[] { file },
+ IResource.DEPTH_ZERO, IResource.ALLOW_MISSING_LOCAL);
+ } else if (objectType == Constants.OBJ_TREE) {
+ IContainer folder = workspaceRoot.getContainerForLocation(path);
+ if (folder != null)
+ traversal = new ResourceTraversal(new IResource[] { folder },
+ IResource.DEPTH_INFINITE, IResource.ALLOW_MISSING_LOCAL);
+ }
+
+ return traversal;
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitModelWorkbenchAdapter.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitModelWorkbenchAdapter.java
new file mode 100644
index 0000000..55fd9d0
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitModelWorkbenchAdapter.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.mapping;
+
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelObject;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelRoot;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+
+/**
+ * Adapts Git ChangeSet model into workbench
+ */
+public class GitModelWorkbenchAdapter implements IWorkbenchAdapter {
+
+ private GitChangeSetLabelProvider gitLabelProvider;
+
+ public Object[] getChildren(Object o) {
+ if (o instanceof GitModelObject)
+ return ((GitModelObject) o).getChildren();
+
+ if (o instanceof GitModelRoot)
+ return ((GitModelRoot) o).getChildren();
+
+ return null;
+ }
+
+ public ImageDescriptor getImageDescriptor(Object object) {
+ if (gitLabelProvider == null)
+ gitLabelProvider = new GitChangeSetLabelProvider();
+
+ Image image = gitLabelProvider.getImage(object);
+
+ return ImageDescriptor.createFromImage(image);
+ }
+
+ public String getLabel(Object o) {
+ if (o instanceof GitModelObject)
+ return ((GitModelObject) o).getName();
+
+ return null;
+ }
+
+ public Object getParent(Object o) {
+ if (o instanceof GitModelObject)
+ return ((GitModelObject) o).getParent();
+
+ return null;
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitObjectMapping.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitObjectMapping.java
new file mode 100644
index 0000000..808ab7b
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitObjectMapping.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.mapping;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.egit.ui.internal.synchronize.GitChangeSetModelProvider;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelBlob;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelCommit;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelObject;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelRepository;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelTree;
+
+/**
+ * Maps Git's objects onto proper {@link ResourceMapping} instants. It allows
+ * traverse over repository content provides resources for Git ChangeSet.
+ */
+public abstract class GitObjectMapping extends ResourceMapping {
+
+ private final GitModelObject object;
+
+ /**
+ * @param object
+ * @return resource mapping
+ */
+ public static ResourceMapping create(GitModelObject object) {
+ if (object instanceof GitModelBlob)
+ return new GitBlobMapping((GitModelBlob) object);
+ if (object instanceof GitModelTree)
+ return new GitTreeMapping((GitModelTree) object);
+ if (object instanceof GitModelCommit)
+ return new GitCommitMapping((GitModelCommit) object);
+ if (object instanceof GitModelRepository)
+ return new GitRepositoryMapping((GitModelRepository) object);
+
+ return null;
+ }
+
+ /**
+ * @param parent instance of parent object
+ */
+ protected GitObjectMapping(GitModelObject parent) {
+ this.object = parent;
+ }
+
+ @Override
+ public boolean contains(ResourceMapping mapping) {
+ if (mapping.getModelProviderId().equals(getModelProviderId())) {
+ GitModelObject obj = (GitModelObject) mapping.getModelObject();
+ return obj.getRepository().equals(object.getRepository());
+ }
+
+ return false;
+ }
+
+ @Override
+ public Object getModelObject() {
+ return object;
+ }
+
+ @Override
+ public String getModelProviderId() {
+ return GitChangeSetModelProvider.ID;
+ }
+
+ @Override
+ public IProject[] getProjects() {
+ return object.getProjects();
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitRepositoryMapping.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitRepositoryMapping.java
new file mode 100644
index 0000000..f86a738
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitRepositoryMapping.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.mapping;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.mapping.ResourceMappingContext;
+import org.eclipse.core.resources.mapping.ResourceTraversal;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelCommit;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelObject;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelRepository;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+
+class GitRepositoryMapping extends GitObjectMapping {
+
+ private final GitModelRepository gitRepo;
+
+ protected GitRepositoryMapping(GitModelRepository gitRepo) {
+ super(gitRepo);
+ this.gitRepo = gitRepo;
+ }
+
+ @Override
+ public ResourceTraversal[] getTraversals(ResourceMappingContext context,
+ IProgressMonitor monitor) throws CoreException {
+ Repository repo = gitRepo.getRepository();
+ List<ResourceTraversal> result = new ArrayList<ResourceTraversal>();
+
+ for (GitModelObject obj : gitRepo.getChildren())
+ if (obj instanceof GitModelCommit) {
+ RevCommit revCommit = ((GitModelCommit) obj).getRemoteCommit();
+ result.add(new GitTreeTraversal(repo, revCommit));
+ }
+
+ return result.toArray(new ResourceTraversal[result.size()]);
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitTreeMapping.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitTreeMapping.java
new file mode 100644
index 0000000..8ecc716
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitTreeMapping.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.mapping;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.mapping.ResourceMappingContext;
+import org.eclipse.core.resources.mapping.ResourceTraversal;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelBlob;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelObject;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelTree;
+
+class GitTreeMapping extends GitObjectMapping {
+
+ private final GitModelTree tree;
+
+ private static final IWorkspaceRoot root = ResourcesPlugin.getWorkspace()
+ .getRoot();
+
+ protected GitTreeMapping(GitModelTree object) {
+ super(object);
+ tree = object;
+ }
+
+ @Override
+ public ResourceTraversal[] getTraversals(ResourceMappingContext context,
+ IProgressMonitor monitor) throws CoreException {
+ GitModelObject[] objects = tree.getChildren();
+ ResourceTraversal[] result = new ResourceTraversal[objects.length];
+
+ for (int i = 0; i < objects.length; i++) {
+ if (objects[i] instanceof GitModelTree)
+ result[i] = new GitTreeTraversal((GitModelTree) objects[i]);
+ else {
+ IResource[] resources = getResources((GitModelBlob) objects[i]);
+ result[i] = new ResourceTraversal(resources,
+ IResource.DEPTH_ZERO, IResource.ALLOW_MISSING_LOCAL);
+ }
+ }
+
+ return result;
+ }
+
+ private IResource[] getResources(GitModelBlob modelBlob) {
+ IFile file = root.getFileForLocation(modelBlob.getLocation());
+
+ return new IResource[] { file };
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitTreeTraversal.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitTreeTraversal.java
new file mode 100644
index 0000000..467f18f
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitTreeTraversal.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.mapping;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.mapping.ResourceTraversal;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.ui.internal.synchronize.model.GitModelTree;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+
+class GitTreeTraversal extends ResourceTraversal {
+
+ public GitTreeTraversal(GitModelTree modelTree) {
+ this(modelTree.getRepository(), modelTree.getBaseId(), modelTree
+ .getRemoteId(), modelTree.getLocation());
+ }
+
+ public GitTreeTraversal(Repository repo, RevCommit commit) {
+ this(repo, commit.getParent(0).getTree().getId(), commit.getTree()
+ .getId(), new Path(repo.getWorkTree().toString()));
+ }
+
+ private GitTreeTraversal(Repository repo, AnyObjectId baseId,
+ AnyObjectId actualId, IPath path) {
+ super(getResourcesImpl(repo, path, baseId, actualId),
+ IResource.DEPTH_INFINITE, IResource.NONE);
+ }
+
+ private static IResource[] getResourcesImpl(Repository repo, IPath path,
+ AnyObjectId baseId, AnyObjectId remoteId) {
+ TreeWalk tw = new TreeWalk(repo);
+ List<IResource> result = new ArrayList<IResource>();
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+
+ tw.reset();
+ tw.setRecursive(false);
+ tw.setFilter(TreeFilter.ANY_DIFF);
+ try {
+ tw.addTree(baseId);
+ int actualNth = tw.addTree(remoteId);
+
+ while (tw.next()) {
+ int objectType = tw.getFileMode(actualNth).getObjectType();
+ IPath childPath = path.append(tw.getNameString());
+
+ IResource resource = null;
+ if (objectType == Constants.OBJ_BLOB)
+ resource = root.getFileForLocation(childPath);
+ else if (objectType == Constants.OBJ_TREE)
+ resource = root.getContainerForLocation(childPath);
+
+ if (resource != null)
+ result.add(resource);
+ }
+ } catch (IOException e) {
+ Activator.logError(e.getMessage(), e);
+ }
+
+ return result.toArray(new IResource[result.size()]);
+ }
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelBlob.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelBlob.java
new file mode 100644
index 0000000..fc42b5e
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelBlob.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.model;
+
+import static org.eclipse.jgit.lib.ObjectId.zeroId;
+
+import java.io.IOException;
+
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.structuremergeviewer.Differencer;
+import org.eclipse.compare.structuremergeviewer.ICompareInput;
+import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.egit.ui.internal.CompareUtils;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Git blob object representation in Git ChangeSet
+ */
+public class GitModelBlob extends GitModelCommit implements ICompareInput {
+
+ private final String name;
+
+ private final ObjectId baseId;
+
+ private final ObjectId remoteId;
+
+ private final ObjectId ancestorId;
+
+ private final IPath location;
+
+ private final String gitPath;
+
+ private static final GitModelObject[] empty = new GitModelObject[0];
+
+ /**
+ *
+ * @param parent
+ * parent of this object
+ * @param commit
+ * remote commit
+ * @param ancestorId
+ * common ancestor id
+ * @param baseId
+ * id of base object variant
+ * @param remoteId
+ * id of remote object variant
+ * @param name
+ * human readable blob name (file name)
+ * @throws IOException
+ */
+ public GitModelBlob(GitModelObject parent, RevCommit commit,
+ ObjectId ancestorId, ObjectId baseId, ObjectId remoteId, String name)
+ throws IOException {
+ super(parent, commit);
+ this.name = name;
+ this.baseId = baseId;
+ this.remoteId = remoteId;
+ this.ancestorId = ancestorId;
+ location = getParent().getLocation().append(name);
+ gitPath = Repository.stripWorkDir(getRepository().getWorkTree(),
+ getLocation().toFile());
+ }
+
+ @Override
+ public GitModelObject[] getChildren() {
+ return empty;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public IProject[] getProjects() {
+ return getParent().getProjects();
+ }
+
+ @Override
+ public IPath getLocation() {
+ return location;
+ }
+
+ public Image getImage() {
+ // currently itsn't used
+ return null;
+ }
+
+ public int getKind() {
+ return Differencer.CONFLICTING;
+ }
+
+ public ITypedElement getAncestor() {
+ if (objectExist(getAncestorCommit(), ancestorId))
+ return CompareUtils.getFileRevisionTypedElement(gitPath,
+ getAncestorCommit(), getRepository(), ancestorId);
+
+ return null;
+ }
+
+ public ITypedElement getLeft() {
+ if (objectExist(getRemoteCommit(), remoteId))
+ return CompareUtils.getFileRevisionTypedElement(gitPath,
+ getRemoteCommit(), getRepository(), remoteId);
+
+ return null;
+ }
+
+ public ITypedElement getRight() {
+ if (objectExist(getBaseCommit(), baseId))
+ return CompareUtils.getFileRevisionTypedElement(gitPath,
+ getBaseCommit(), getRepository(), baseId);
+
+ return null;
+ }
+
+ public void addCompareInputChangeListener(
+ ICompareInputChangeListener listener) {
+ // data in commit will never change, therefore change listeners are
+ // useless
+ }
+
+ public void removeCompareInputChangeListener(
+ ICompareInputChangeListener listener) {
+ // data in commit will never change, therefore change listeners are
+ // useless
+ }
+
+ public void copy(boolean leftToRight) {
+ // do nothing, we should disallow coping content between commits
+ }
+
+ private boolean objectExist(RevCommit commit, ObjectId id) {
+ return commit != null && id != null && !id.equals(zeroId());
+ }
+
+}
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
new file mode 100644
index 0000000..9e4c56a
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommit.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.egit.core.Activator;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.revwalk.filter.RevFilter;
+import org.eclipse.jgit.treewalk.TreeWalk;
+
+/**
+ * Git commit object representation in Git ChangeSet
+ */
+public class GitModelCommit extends GitModelObject {
+
+ private final RevCommit baseCommit;
+
+ private final RevCommit remoteCommit;
+
+ private final RevCommit ancestorCommit;
+
+ private String name;
+
+ private GitModelObject[] children;
+
+ /**
+ * @param parent
+ * instance of repository model object that is parent for this
+ * commit
+ * @param commit
+ * instance of commit that will be associated with this model
+ * object
+ * @throws IOException
+ */
+ public GitModelCommit(GitModelRepository parent, RevCommit commit)
+ throws IOException {
+ super(parent);
+ remoteCommit = commit;
+ ancestorCommit = calculateAncestor(remoteCommit);
+
+ RevCommit[] parents = remoteCommit.getParents();
+ if (parents != null && parents.length > 0)
+ baseCommit = remoteCommit.getParent(0);
+ else {
+ baseCommit = null;
+ }
+ }
+
+ /**
+ * Constructor for child classes.
+ *
+ * @param parent
+ * instance of repository model object that is parent for this
+ * commit
+ * @param commit
+ * instance of commit that will be associated with this model
+ * object
+ * @throws IOException
+ */
+ protected GitModelCommit(GitModelObject parent, RevCommit commit)
+ throws IOException {
+ super(parent);
+ remoteCommit = commit;
+ ancestorCommit = calculateAncestor(remoteCommit);
+
+ RevCommit[] parents = remoteCommit.getParents();
+ if (parents != null && parents.length > 0)
+ baseCommit = remoteCommit.getParent(0);
+ else {
+ baseCommit = null;
+ }
+ }
+
+ @Override
+ public GitModelObject[] getChildren() {
+ if (children == null)
+ getChildrenImpl();
+
+ return children;
+
+ }
+
+ @Override
+ public String getName() {
+ if (name == null)
+ name = remoteCommit.getName().substring(0, 6)
+ + ": " + remoteCommit.getShortMessage();//$NON-NLS-1$
+
+ return name;
+ }
+
+ @Override
+ public IProject[] getProjects() {
+ return getParent().getProjects();
+ }
+
+ /**
+ * Returns common ancestor for this commit and all it parent's commits.
+ *
+ * @return common ancestor commit
+ */
+ public RevCommit getAncestorCommit() {
+ return ancestorCommit;
+ }
+
+ /**
+ * Returns instance of commit that is parent for one that is associated with
+ * this model object.
+ *
+ * @return base commit
+ */
+ public RevCommit getBaseCommit() {
+ return baseCommit;
+ }
+
+ /**
+ * Resurns instance of commit that is associated with this model object.
+ *
+ * @return rev commit
+ */
+ public RevCommit getRemoteCommit() {
+ return remoteCommit;
+ }
+
+ @Override
+ public IPath getLocation() {
+ return getParent().getLocation();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return remoteCommit.equals(obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return remoteCommit.hashCode();
+ }
+
+ private RevCommit calculateAncestor(RevCommit actual) throws IOException {
+ RevWalk rw = new RevWalk(getRepository());
+ rw.setRevFilter(RevFilter.MERGE_BASE);
+
+ for (RevCommit parent : actual.getParents()) {
+ RevCommit parentCommit = rw.parseCommit(parent.getId());
+ rw.markStart(parentCommit);
+ }
+
+ rw.markStart(rw.parseCommit(actual.getId()));
+
+ RevCommit result = rw.next();
+ return result != null ? result : rw.parseCommit(ObjectId.zeroId());
+ }
+
+ private void getChildrenImpl() {
+ TreeWalk tw = createTreeWalk();
+ List<GitModelObject> result = new ArrayList<GitModelObject>();
+ try {
+ int ancestorNth = tw.addTree(ancestorCommit.getTree());
+ int baseNth = -1;
+ if (baseCommit != null)
+ baseNth = tw.addTree(baseCommit.getTree());
+ int actualNth = tw.addTree(remoteCommit.getTree());
+
+ while (tw.next()) {
+ GitModelObject obj = getModelObject(tw, ancestorNth, baseNth,
+ actualNth);
+ if (obj != null)
+ result.add(obj);
+ }
+ } catch (IOException e) {
+ Activator.logError(e.getMessage(), e);
+ }
+
+ children = result.toArray(new GitModelObject[result.size()]);
+ }
+
+ private GitModelObject getModelObject(TreeWalk tw, int ancestorNth,
+ int baseNth, int actualNth) throws IOException {
+ String objName = tw.getNameString();
+
+ ObjectId objBaseId;
+ if (baseNth > -1)
+ objBaseId = tw.getObjectId(baseNth);
+ else
+ objBaseId = null;
+
+ ObjectId objRemoteId = tw.getObjectId(actualNth);
+ ObjectId objAncestorId = tw.getObjectId(ancestorNth);
+ int objectType = tw.getFileMode(actualNth).getObjectType();
+
+ if (objectType == Constants.OBJ_BLOB)
+ return new GitModelBlob(this, remoteCommit, objAncestorId,
+ objBaseId, objRemoteId, objName);
+ else if (objectType == Constants.OBJ_TREE)
+ return new GitModelTree(this, remoteCommit, objAncestorId,
+ objBaseId, objRemoteId, objName);
+
+ return null;
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelObject.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelObject.java
new file mode 100644
index 0000000..dc688e0
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelObject.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.model;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+
+/**
+ * Abstract representation of all object that are included in Git ChangeSet
+ * model.
+ */
+public abstract class GitModelObject extends PlatformObject {
+
+ private final GitModelObject parent;
+
+ /**
+ * Creates root of Git ChangeSet model.
+ *
+ * @param data
+ * synchronization data
+ * @return Git ChangeSet model root
+ * @throws IOException
+ * @throws MissingObjectException
+ */
+ public static GitModelObject createRoot(GitSynchronizeData data)
+ throws MissingObjectException, IOException {
+ return new GitModelRepository(data);
+ }
+
+ /**
+ * @return child's of particular model object
+ */
+ public abstract GitModelObject[] getChildren();
+
+ /**
+ * Returns name of model object, in case of:
+ * <ul>
+ * <li>root node it will return repository path
+ * <li>commit node it will return first 6 characters of commit's SHA-1
+ * connected with short commit message
+ * <li>tree node it will return folder name
+ * <li>blob node it will return file name
+ * </ul>
+ *
+ * @return name of model object
+ */
+ public abstract String getName();
+
+ /**
+ * @return list of projects that are connected with particular object model
+ */
+ public abstract IProject[] getProjects();
+
+ /**
+ * @return location of resource associated with particular model object
+ */
+ public abstract IPath getLocation();
+
+ /**
+ *
+ * @param parent
+ * of particular model object
+ */
+ protected GitModelObject(GitModelObject parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * @return parent of particular model object, or <code>null</code> if object
+ * is root node
+ */
+ public GitModelObject getParent() {
+ return parent;
+ }
+
+ /**
+ * @return repository associated with particular model object
+ */
+ public Repository getRepository() {
+ return parent.getRepository();
+ }
+
+ /**
+ * Returns preinitialized instance of {@link TreeWalk}. Set of
+ * initialization call's is common for all model object's.
+ *
+ * @return tree walk
+ */
+ protected TreeWalk createTreeWalk() {
+ TreeWalk tw = new TreeWalk(getRepository());
+
+ tw.reset();
+ tw.setRecursive(false);
+ tw.setFilter(TreeFilter.ANY_DIFF);
+
+ return tw;
+ }
+
+}
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
new file mode 100644
index 0000000..7de3519
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepository.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.RevUtils;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.JGitInternalException;
+import org.eclipse.jgit.api.NoHeadException;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.ObjectWalk;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevCommitList;
+import org.eclipse.jgit.revwalk.RevObject;
+
+/**
+ * Representation of Git repository in Git ChangeSet model.
+ */
+public class GitModelRepository extends GitModelObject {
+
+ private final Repository repo;
+
+ private final ObjectId srcRev;
+
+ private final ObjectId dstRev;
+
+ private final IProject[] projects;
+
+ private GitModelObject[] childrens;
+
+ private IPath location;
+
+ /**
+ * @param data
+ * synchronization data
+ * @throws IOException
+ * @throws MissingObjectException
+ */
+ public GitModelRepository(GitSynchronizeData data)
+ throws MissingObjectException, IOException {
+ super(null);
+ repo = data.getRepository();
+ Set<IProject> projectSet = data.getProjects();
+ projects = projectSet.toArray(new IProject[projectSet.size()]);
+
+ ObjectWalk ow = new ObjectWalk(repo);
+ ow.markStart(ow.parseAny(data.getSrcRev().getObjectId()));
+ srcRev = ow.next();
+
+ ow.reset();
+ ow.markStart(ow.parseAny(data.getDstRev().getObjectId()));
+ dstRev = ow.next();
+ }
+
+ @Override
+ public GitModelObject[] getChildren() {
+ if (childrens == null)
+ getChildrenImpl();
+
+ return childrens;
+ }
+
+ @Override
+ public String getName() {
+ return repo.getWorkTree().toString();
+ }
+
+ @Override
+ public IProject[] getProjects() {
+ return projects;
+ }
+
+ /**
+ * @return repository
+ */
+ public Repository getRepository() {
+ return repo;
+ }
+
+ /**
+ * @return source {@link RevObject}
+ */
+ public ObjectId getSrcRev() {
+ return srcRev;
+ }
+
+ /**
+ * @return destination {@link RevObject}
+ */
+ public ObjectId getDstRev() {
+ return dstRev;
+ }
+
+ @Override
+ public IPath getLocation() {
+ if (location == null)
+ location = new Path(repo.getWorkTree().toString());
+
+ return location;
+ }
+
+ private void getChildrenImpl() {
+ List<GitModelCommit> result = new ArrayList<GitModelCommit>();
+
+ try {
+ RevCommit ancestorCommit = RevUtils.getCommonAncestor(repo, srcRev,
+ dstRev);
+ RevCommitList<RevCommit> commits = getRevCommits(ancestorCommit, dstRev);
+ commits.addAll(getRevCommits(ancestorCommit, srcRev));
+
+ for (RevCommit commit : commits)
+ result.add(new GitModelCommit(this, commit));
+ } catch (IOException e) {
+ Activator.logError(e.getMessage(), e);
+ }
+
+ childrens = result.toArray(new GitModelCommit[result.size()]);
+ }
+
+ private RevCommitList<RevCommit> getRevCommits(AnyObjectId since, AnyObjectId until) {
+ Git git = new Git(repo);
+ RevCommitList<RevCommit> result = new RevCommitList<RevCommit>();
+ try {
+ Iterable<RevCommit> call = git.log().addRange(since, until).call();
+
+ for (RevCommit commit : call)
+ result.add(commit);
+
+ } catch (NoHeadException e) {
+ Activator.logError(e.getMessage(), e);
+ } catch (JGitInternalException e) {
+ Activator.logError(e.getMessage(), e);
+ } catch (MissingObjectException e) {
+ Activator.logError(e.getMessage(), e);
+ } catch (IncorrectObjectTypeException e) {
+ Activator.logError(e.getMessage(), e);
+ }
+
+ return result;
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRoot.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRoot.java
new file mode 100644
index 0000000..0e5fde4
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRoot.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+
+/**
+ * Root of all model objects.
+ */
+public class GitModelRoot {
+
+ private final GitSynchronizeDataSet gsds;
+
+ /**
+ * @param gsds
+ */
+ public GitModelRoot(GitSynchronizeDataSet gsds) {
+ this.gsds = gsds;
+ }
+
+ /**
+ * @return git synchronization data
+ */
+ public GitSynchronizeDataSet getGsds() {
+ return gsds;
+ }
+
+ /**
+ * @return children
+ */
+ public GitModelRepository[] getChildren() {
+ List<GitModelRepository> restult = new ArrayList<GitModelRepository>();
+ for (GitSynchronizeData data : gsds) {
+ try {
+ restult.add(new GitModelRepository(data));
+ } catch (IOException e) {
+ Activator.logError(e.getMessage(), e);
+ }
+ }
+
+ return restult.toArray(new GitModelRepository[restult.size()]);
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelTree.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelTree.java
new file mode 100644
index 0000000..e47a109
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelTree.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.synchronize.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.egit.core.Activator;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.treewalk.TreeWalk;
+
+/**
+ * Representation of Git tree's in Git ChangeSet model
+ */
+public class GitModelTree extends GitModelCommit {
+
+ private final String name;
+
+ private final ObjectId baseId;
+
+ private final ObjectId remoteId;
+
+ private final ObjectId ancestorId;
+
+ private GitModelObject[] children;
+
+ private IPath location;
+
+ /**
+ * @param parent
+ * parent of this tree
+ * @param commit
+ * commit associated with this tree
+ * @param ancestorId
+ * id of common ancestor tree for this on
+ * @param baseId
+ * id of base tree
+ * @param remoteId
+ * this tree id
+ * @param name
+ * name resource associated with this tree
+ * @throws IOException
+ */
+ public GitModelTree(GitModelObject parent, RevCommit commit,
+ ObjectId ancestorId, ObjectId baseId, ObjectId remoteId, String name)
+ throws IOException {
+ super(parent, commit);
+ this.name = name;
+ this.baseId = baseId;
+ this.remoteId = remoteId;
+ this.ancestorId = ancestorId;
+ }
+
+ @Override
+ public GitModelObject[] getChildren() {
+ if (children == null)
+ getChildrenImpl();
+
+ return children;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public IProject[] getProjects() {
+ return getParent().getProjects();
+ }
+
+ /**
+ * Return id of tree that should be used as a base variant in
+ * three-way-compare.
+ *
+ * @return base id
+ */
+ public ObjectId getBaseId() {
+ return baseId;
+ }
+
+ /**
+ * Returns id of tree that should be used as a remote in three-way-compare
+ *
+ * @return object id
+ */
+ public ObjectId getRemoteId() {
+ return remoteId;
+ }
+
+ @Override
+ public IPath getLocation() {
+ if (location == null)
+ location = getParent().getLocation().append(name);
+
+ return location;
+ }
+
+ private void getChildrenImpl() {
+ TreeWalk tw = createTreeWalk();
+ List<GitModelObject> result = new ArrayList<GitModelObject>();
+
+ try {
+ int ancestorNth = tw.addTree(ancestorId);
+ int baseNth = tw.addTree(baseId);
+ int remoteNth = tw.addTree(remoteId);
+
+ while (tw.next()) {
+ GitModelObject obj = createChildren(tw, ancestorNth, baseNth,
+ remoteNth);
+ if (obj != null)
+ result.add(obj);
+ }
+ } catch (IOException e) {
+ Activator.logError(e.getMessage(), e);
+ }
+
+ children = result.toArray(new GitModelObject[result.size()]);
+ }
+
+ private GitModelObject createChildren(TreeWalk tw, int ancestorNth,
+ int baseNth, int remoteNth) throws IOException {
+ String objName = tw.getNameString();
+ ObjectId objBaseId = tw.getObjectId(baseNth);
+ ObjectId objRemoteId = tw.getObjectId(remoteNth);
+ ObjectId objAncestorId = tw.getObjectId(ancestorNth);
+ int objectType = tw.getFileMode(remoteNth).getObjectType();
+
+ if (objectType == Constants.OBJ_BLOB)
+ return new GitModelBlob(this, getRemoteCommit(), objAncestorId,
+ objBaseId, objRemoteId, objName);
+ else if (objectType == Constants.OBJ_TREE)
+ return new GitModelTree(this, getRemoteCommit(), objAncestorId,
+ objBaseId, objRemoteId, objName);
+
+ return null;
+ }
+
+}