| /******************************************************************************* |
| * Copyright (C) 2013, 2015 Obeo and others |
| * |
| * 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 |
| * |
| * Contributors: |
| * Obeo - initial API and implementation |
| * Florian Zoubek - rebase method added |
| *******************************************************************************/ |
| package org.eclipse.papyrus.compare.diagram.tests.egit.fixture; |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.OutputStreamWriter; |
| import java.io.Writer; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.mapping.IModelProviderDescriptor; |
| import org.eclipse.core.resources.mapping.ModelProvider; |
| import org.eclipse.core.resources.mapping.RemoteResourceMappingContext; |
| 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.IPath; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.egit.core.Activator; |
| import org.eclipse.egit.core.op.BranchOperation; |
| import org.eclipse.egit.core.op.CherryPickOperation; |
| import org.eclipse.egit.core.op.ConnectProviderOperation; |
| import org.eclipse.egit.core.op.DisconnectProviderOperation; |
| import org.eclipse.egit.core.op.IgnoreOperation; |
| import org.eclipse.egit.core.op.MergeOperation; |
| import org.eclipse.egit.core.op.RebaseOperation; |
| import org.eclipse.egit.core.op.ResetOperation; |
| 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.emf.compare.ide.ui.tests.workspace.TestProject; |
| import org.eclipse.jgit.api.CommitCommand; |
| import org.eclipse.jgit.api.Git; |
| import org.eclipse.jgit.api.ResetCommand.ResetType; |
| import org.eclipse.jgit.api.RmCommand; |
| import org.eclipse.jgit.api.Status; |
| import org.eclipse.jgit.api.errors.GitAPIException; |
| import org.eclipse.jgit.api.errors.NoFilepatternException; |
| import org.eclipse.jgit.lib.ObjectId; |
| import org.eclipse.jgit.lib.Ref; |
| import org.eclipse.jgit.lib.RefUpdate; |
| import org.eclipse.jgit.lib.Repository; |
| import org.eclipse.jgit.merge.MergeStrategy; |
| import org.eclipse.jgit.revwalk.RevCommit; |
| import org.eclipse.jgit.revwalk.RevWalk; |
| import org.eclipse.jgit.util.FileUtils; |
| import org.eclipse.team.core.subscribers.Subscriber; |
| import org.eclipse.team.core.subscribers.SubscriberScopeManager; |
| |
| import com.google.common.collect.Iterables; |
| |
| /** |
| * This class is largely inspired from org.eclipse.egit.core.test.TestRepository. It has been copied here in |
| * order to be usable from our build without dependencies towards egit.core.tests. |
| */ |
| @SuppressWarnings({"nls", "restriction" }) |
| public class GitTestRepository { |
| private final List<Runnable> disposers; |
| |
| Repository repository; |
| |
| String workdirPrefix; |
| |
| /** |
| * Creates a new test repository. |
| * |
| * @param gitDir |
| * The ".git" file we'll use to create a repository. |
| * @throws IOException |
| * Thrown if we cannot write at the given location. |
| */ |
| public GitTestRepository(File gitDir) throws IOException { |
| repository = Activator.getDefault().getRepositoryCache().lookupRepository(gitDir); |
| repository.create(); |
| |
| try { |
| workdirPrefix = repository.getWorkTree().getCanonicalPath(); |
| } catch (IOException err) { |
| workdirPrefix = repository.getWorkTree().getAbsolutePath(); |
| } |
| workdirPrefix = workdirPrefix.replace('\\', '/'); |
| if (!workdirPrefix.endsWith("/")) { |
| workdirPrefix += "/"; |
| } |
| |
| this.disposers = new ArrayList<>(); |
| } |
| |
| public Repository getRepository() { |
| return this.repository; |
| } |
| |
| /** |
| * Adds all changes and creates a commit. |
| * <p> |
| * This is a convenience method for {@link #addAllAndCommit(String, boolean)}, whereas deleted or missing |
| * files are <em>not</em> added to the index. |
| * </p> |
| * |
| * @param commitMessage |
| * The commit message. |
| * @return The reference to the created commit. |
| * @throws Exception |
| * if anything goes wrong. |
| */ |
| public RevCommit addAllAndCommit(String commitMessage) throws Exception { |
| return addAllAndCommit(commitMessage, false); |
| } |
| |
| /** |
| * Adds all changes and creates a commit. |
| * |
| * @param commitMessage |
| * The commit message. |
| * @param addDeleted |
| * Specifies whether missing or deleted files should added to index, too. |
| * @return The reference to the created commit. |
| * @throws Exception |
| * if anything goes wrong. |
| */ |
| public RevCommit addAllAndCommit(String commitMessage, boolean addDeleted) throws Exception { |
| Git git = new Git(repository); |
| try { |
| git.add().addFilepattern(".").call(); |
| if (addDeleted) { |
| addDeletedFiles(); |
| } |
| return commit(commitMessage); |
| } finally { |
| git.close(); |
| } |
| } |
| |
| /** |
| * Adds all missing or deleted files to the index. |
| * |
| * @throws Exception |
| * if anything goes wrong. |
| */ |
| public void addDeletedFiles() throws Exception { |
| Git git = new Git(repository); |
| try { |
| Status status = git.status().call(); |
| if (!status.getMissing().isEmpty() || !status.getRemoved().isEmpty()) { |
| RmCommand rm = git.rm(); |
| for (String deletedFile : Iterables.concat(status.getMissing(), status.getRemoved())) { |
| rm.addFilepattern(deletedFile); |
| } |
| rm.call(); |
| } |
| } finally { |
| git.close(); |
| } |
| } |
| |
| /** |
| * Adds all changes and amends the latest commit, also changing its message to the given message. |
| * |
| * @param message |
| * the amended commit message, must not be null |
| * @return The RevCommit of the amended commit. |
| * @throws Exception |
| * if anything goes wrong. |
| */ |
| public RevCommit addAllAndAmend(String message) throws Exception { |
| Git git = new Git(repository); |
| try { |
| git.add().addFilepattern(".").call(); |
| return git.commit().setAmend(true).setMessage(message).call(); |
| } finally { |
| git.close(); |
| } |
| } |
| |
| /** |
| * Track, add to index and finally commit the given files. |
| * |
| * @param testProject |
| * The project within which this file is located. |
| * @param commitMessage |
| * Message with which to commit this file. |
| * @param files |
| * The files to add and commit. |
| * @return The RevCommit corresponding to this operation. |
| */ |
| public RevCommit addAndCommit(TestProject testProject, String commitMessage, File... files) |
| throws Exception { |
| addToIndex(testProject, files); |
| return commit(commitMessage); |
| } |
| |
| /** |
| * Track, add to index and finally commit given file |
| * |
| * @param project |
| * @param file |
| * @param commitMessage |
| * @return commit object |
| * @throws Exception |
| */ |
| public RevCommit addAndCommit(IProject project, String commitMessage, File... files) throws Exception { |
| for (File file : files) { |
| track(file); |
| addToIndex(project, file); |
| } |
| return commit(commitMessage); |
| } |
| |
| /** |
| * Appends content to end of given file. |
| * |
| * @param file |
| * @param content |
| * @throws IOException |
| */ |
| public void appendFileContent(File file, byte[] content) throws IOException { |
| appendFileContent(file, new String(content, "UTF-8"), true); |
| } |
| |
| /** |
| * Appends content to end of given file. |
| * |
| * @param file |
| * @param content |
| * @throws IOException |
| */ |
| public void appendFileContent(File file, String content) throws IOException { |
| appendFileContent(file, content, true); |
| } |
| |
| /** |
| * Appends content to given file. |
| * |
| * @param file |
| * @param content |
| * @param append |
| * if true, then bytes will be written to the end of the file rather than the beginning |
| * @throws IOException |
| */ |
| public void appendFileContent(File file, byte[] content, boolean append) throws IOException { |
| appendFileContent(file, new String(content, "UTF-8"), append); |
| } |
| |
| /** |
| * Appends content to given file. |
| * |
| * @param file |
| * @param content |
| * @param append |
| * if true, then bytes will be written to the end of the file rather than the beginning |
| * @throws IOException |
| */ |
| public void appendFileContent(File file, String content, boolean append) throws IOException { |
| Writer fw = null; |
| try { |
| fw = new OutputStreamWriter(new FileOutputStream(file, append), "UTF-8"); |
| fw.append(content); |
| } finally { |
| if (fw != null) { |
| fw.close(); |
| } |
| } |
| } |
| |
| /** |
| * Adds the given file to the index |
| * |
| * @param project |
| * @param file |
| * @throws Exception |
| */ |
| public void addToIndex(IProject project, File file) throws Exception { |
| IFile iFile = getIFile(project, file); |
| addToIndex(iFile); |
| } |
| |
| /** |
| * Adds the given resource to the index |
| * |
| * @param resource |
| * @throws CoreException |
| * @throws IOException |
| * @throws GitAPIException |
| * @throws NoFilepatternException |
| */ |
| public void addToIndex(IResource resource) |
| throws CoreException, IOException, NoFilepatternException, GitAPIException { |
| String repoPath = getRepoRelativePath(resource.getLocation().toString()); |
| Git git = new Git(repository); |
| try { |
| git.add().addFilepattern(repoPath).call(); |
| } finally { |
| git.close(); |
| } |
| } |
| |
| /** |
| * Appends file content to given file, then track, add to index and finally commit it. |
| * |
| * @param project |
| * @param file |
| * @param content |
| * @param commitMessage |
| * @return commit object |
| * @throws Exception |
| */ |
| public RevCommit appendContentAndCommit(IProject project, File file, byte[] content, String commitMessage) |
| throws Exception { |
| return appendContentAndCommit(project, file, new String(content, "UTF-8"), commitMessage); |
| } |
| |
| /** |
| * Appends file content to given file, then track, add to index and finally commit it. |
| * |
| * @param project |
| * @param file |
| * @param content |
| * @param commitMessage |
| * @return commit object |
| * @throws Exception |
| */ |
| public RevCommit appendContentAndCommit(IProject project, File file, String content, String commitMessage) |
| throws Exception { |
| appendFileContent(file, content); |
| track(file); |
| addToIndex(project, file); |
| |
| return commit(commitMessage); |
| } |
| |
| public void ignore(File... files) throws Exception { |
| final Set<IPath> paths = new LinkedHashSet<>(); |
| for (File file : files) { |
| paths.add(new Path(file.getPath())); |
| } |
| new IgnoreOperation(paths).execute(new NullProgressMonitor()); |
| } |
| |
| /** |
| * Adds the given files to the index. |
| * |
| * @param testProject |
| * Project that contains these files. |
| * @param files |
| * Files to add to the index. |
| */ |
| public void addToIndex(TestProject testProject, File... files) throws Exception { |
| for (File file : files) { |
| addToIndex(testProject.getIFile(testProject.getProject(), file)); |
| } |
| } |
| |
| /** |
| * Removes the given files from the index. |
| * |
| * @param testProject |
| * Project that contains these files. |
| * @param files |
| * Files to remove from the index. |
| */ |
| public void removeFromIndex(TestProject testProject, File... files) throws Exception { |
| for (File file : files) { |
| removeFromIndex(testProject.getIFile(testProject.getProject(), file)); |
| } |
| } |
| |
| /** |
| * Adds the given resources to the index |
| * |
| * @param resources |
| * Resources to add to the index. |
| */ |
| public void addToIndex(IResource... resources) |
| throws CoreException, IOException, NoFilepatternException, GitAPIException { |
| Git git = new Git(repository); |
| try { |
| for (IResource resource : resources) { |
| String repoPath = getRepoRelativePath(resource.getLocation().toString()); |
| git.add().addFilepattern(repoPath).call(); |
| } |
| } finally { |
| git.close(); |
| } |
| } |
| |
| /** |
| * Adds the given resources to the index |
| * |
| * @param resources |
| * Resources to add to the index. |
| */ |
| public void removeFromIndex(IResource... resources) |
| throws CoreException, IOException, NoFilepatternException, GitAPIException { |
| Git git = new Git(repository); |
| try { |
| for (IResource resource : resources) { |
| String repoPath = getRepoRelativePath(resource.getLocation().toString()); |
| git.rm().addFilepattern(repoPath).call(); |
| } |
| } finally { |
| git.close(); |
| } |
| } |
| |
| /** |
| * Commits the current index. |
| * |
| * @param message |
| * commit message |
| * @return commit object |
| */ |
| public RevCommit commit(String message) throws Exception { |
| Git git = new Git(repository); |
| try { |
| CommitCommand commitCommand = git.commit(); |
| commitCommand.setAuthor("J. Git", "j.git@egit.org"); |
| commitCommand.setCommitter(commitCommand.getAuthor()); |
| commitCommand.setMessage(message); |
| return commitCommand.call(); |
| } finally { |
| git.close(); |
| } |
| } |
| |
| /** |
| * Connect a project to this repository. |
| * |
| * @param project |
| * The project to connect |
| */ |
| public void connect(IProject project) throws CoreException { |
| ConnectProviderOperation op = new ConnectProviderOperation(project, repository.getDirectory()); |
| op.execute(null); |
| } |
| |
| /** |
| * Disconnects provider from project |
| * |
| * @param project |
| * @throws CoreException |
| */ |
| public void disconnect(IProject project) throws CoreException { |
| Collection<IProject> projects = Collections.singleton(project.getProject()); |
| DisconnectProviderOperation disconnect = new DisconnectProviderOperation(projects); |
| disconnect.execute(null); |
| } |
| |
| /** |
| * Create a file or get an existing one |
| * |
| * @param project |
| * instance of project inside with file will be created |
| * @param name |
| * name of file |
| * @return nearly created file |
| * @throws IOException |
| */ |
| public File createFile(IProject project, String name) throws IOException { |
| String path = project.getLocation().append(name).toOSString(); |
| int lastSeparator = path.lastIndexOf(File.separator); |
| FileUtils.mkdirs(new File(path.substring(0, lastSeparator)), true); |
| |
| File file = new File(path); |
| if (!file.exists()) { |
| FileUtils.createNewFile(file); |
| } |
| |
| return file; |
| } |
| |
| public IFile getIFile(IProject project, File file) throws CoreException { |
| String relativePath = getRepoRelativePath(file.getAbsolutePath()); |
| |
| // In case the project is not at the root of the repository |
| // we need to remove the whole path before the project name. |
| int index = relativePath.indexOf(project.getName()); |
| if (index >= 0) { |
| relativePath = relativePath.substring(index + project.getName().length()); |
| } |
| IFile iFile = project.getFile(relativePath); |
| iFile.refreshLocal(0, null); |
| |
| return iFile; |
| } |
| |
| /** |
| * Creates a new branch and immediately checkout it. |
| * |
| * @param refName |
| * starting point for the new branch |
| * @param newRefName |
| * @throws Exception |
| */ |
| public void createAndCheckoutBranch(String refName, String newRefName) throws Exception { |
| createBranch(refName, newRefName); |
| checkoutBranch(newRefName); |
| } |
| |
| /** |
| * Creates a new branch. |
| * |
| * @param refName |
| * Starting point for the new branch. |
| * @param newRefName |
| * Name of the new branch. |
| */ |
| public void createBranch(String refName, String newRefName) throws IOException { |
| RefUpdate updateRef; |
| updateRef = repository.updateRef(newRefName); |
| Ref startRef = repository.exactRef(refName); |
| ObjectId startAt = repository.resolve(refName); |
| String startBranch; |
| if (startRef != null) { |
| startBranch = refName; |
| } else { |
| startBranch = startAt.name(); |
| } |
| startBranch = Repository.shortenRefName(startBranch); |
| updateRef.setNewObjectId(startAt); |
| updateRef.setRefLogMessage("branch: Created from " + startBranch, false); |
| updateRef.update(); |
| } |
| |
| /** |
| * Resets branch. |
| * |
| * @param refName |
| * Full name of the branch. |
| * @param type |
| * Type of the reset. |
| */ |
| public void reset(String refName, ResetType type) throws CoreException { |
| new ResetOperation(repository, refName, type).execute(null); |
| } |
| |
| /** |
| * Checkouts branch. |
| * |
| * @param refName |
| * Full name of the branch. |
| */ |
| public void checkoutBranch(String refName) throws CoreException { |
| new BranchOperation(repository, refName).execute(null); |
| } |
| |
| /** |
| * Merge the given ref with the current HEAD, using the default (logical) strategy. |
| * |
| * @param refName |
| * Name of a commit to merge with the current HEAD. |
| */ |
| public void mergeLogical(String refName) throws CoreException { |
| new MergeOperation(repository, refName).execute(null); |
| } |
| |
| /** |
| * Merge the given ref with the current HEAD, using the default (logical) strategy. |
| * |
| * @param refName |
| * Name of a commit to merge with the current HEAD. |
| */ |
| public void mergeLogicalWithNewCommit(String refName) throws CoreException { |
| MergeOperation mergeOperation = new MergeOperation(repository, refName); |
| mergeOperation.setCommit(true); |
| mergeOperation.execute(null); |
| } |
| |
| /** |
| * Merge the given ref with the current HEAD, using the textual "recursive" strategy. |
| * |
| * @param refName |
| * Name of a commit to merge with the current HEAD. |
| */ |
| public void mergeTextual(String refName) throws CoreException { |
| new MergeOperation(repository, refName, MergeStrategy.RECURSIVE.getName()).execute(null); |
| } |
| |
| /** |
| * Rebase the current HEAD on the given ref, using the default (logical) strategy. |
| * |
| * @param refName |
| * Name of a commit to rebase the current HEAD on. |
| */ |
| public void rebaseLogical(String refName) throws CoreException, IOException { |
| new RebaseOperation(repository, repository.exactRef(refName)).execute(null); |
| } |
| |
| /** |
| * CherryPick the given ref on the current HEAD , using the default (logical) strategy. |
| * |
| * @param refName |
| * Name of a commit to cherry-pick on the current HEAD. |
| */ |
| public void cherryPickLogical(String refName) throws CoreException, IOException { |
| RevWalk revWalk = new RevWalk(repository); |
| try { |
| RevCommit commitId = revWalk.parseCommit(repository.exactRef(refName).getObjectId()); |
| new CherryPickOperation(repository, commitId).execute(null); |
| } catch (IOException e) { |
| Activator.logError(e.getMessage(), e); |
| } finally { |
| revWalk.close(); |
| } |
| } |
| |
| /** |
| * Returns the status of this repository's files as would "git status". |
| * |
| * @return |
| * @throws Exception |
| */ |
| public Status status() throws Exception { |
| Git git = new Git(repository); |
| try { |
| return git.status().call(); |
| } finally { |
| git.close(); |
| } |
| } |
| |
| /** |
| * Adds file to version control |
| * |
| * @param file |
| * @throws IOException |
| * @throws GitAPIException |
| * @throws NoFilepatternException |
| */ |
| public void track(File file) throws IOException, NoFilepatternException, GitAPIException { |
| String repoPath = getRepoRelativePath(new Path(file.getPath()).toString()); |
| Git git = new Git(repository); |
| try { |
| git.add().addFilepattern(repoPath).call(); |
| } finally { |
| git.close(); |
| } |
| } |
| |
| /** |
| * Return the commit with the given name if any. |
| * |
| * @param revstr |
| * see {@link Repository#resolve(String)} |
| * @return The commit with the given name if any. |
| * @see {@link Repository#resolve(String)} |
| */ |
| public RevCommit findCommit(String revstr) throws Exception { |
| RevWalk walk = null; |
| try { |
| walk = new RevWalk(repository); |
| return walk.parseCommit(repository.resolve(revstr)); |
| } finally { |
| if (walk != null) { |
| walk.close(); |
| } |
| } |
| } |
| |
| /** |
| * Dispose of this wrapper along with its underlying repository. |
| */ |
| public void dispose() { |
| if (repository != null) { |
| repository.close(); |
| repository = null; |
| } |
| for (Runnable disposer : disposers) { |
| disposer.run(); |
| } |
| disposers.clear(); |
| } |
| |
| /** |
| * Creates a subscriber capable of providing synchronization information for the current |
| * {@link #repository}. |
| * |
| * @param sourceRef |
| * Source reference (i.e. "left" side of a comparison). |
| * @param targetRef |
| * Target reference (i.e. "right" side of the comparison). |
| * @param includeLocal |
| * Whether to use local data as the "source" side. |
| * @return The created subscriber. |
| */ |
| public Subscriber createSubscriberForResolution(String sourceRef, String targetRef, boolean includeLocal) |
| throws IOException { |
| final GitSynchronizeData data = new GitSynchronizeData(repository, sourceRef, targetRef, |
| includeLocal); |
| final GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data); |
| final GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(dataSet); |
| subscriber.init(new NullProgressMonitor()); |
| disposers.add(new Runnable() { |
| @Override |
| public void run() { |
| subscriber.dispose(); |
| } |
| }); |
| |
| return subscriber; |
| } |
| |
| /** |
| * Simulate a comparison between the two given references and returns back the subscriber that can provide |
| * all computed synchronization information. It will use the local comparison context for retrieving the |
| * resource mappings. |
| * |
| * @param sourceRef |
| * Source reference (i.e. "left" side of the comparison). |
| * @param targetRef |
| * Target reference (i.e. "right" side of the comparison). |
| * @param comparedFile |
| * The file we are comparing (that would be the file right-clicked into the workspace). |
| * @param includeLocal |
| * Whether to use local data as the "source" side. |
| * @return The created subscriber. |
| */ |
| public Subscriber createSubscriberForComparison(String sourceRef, String targetRef, IFile comparedFile, |
| boolean includeLocal) throws IOException { |
| final GitSynchronizeData data = new GitSynchronizeData(repository, sourceRef, targetRef, |
| includeLocal); |
| final GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data); |
| final GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(dataSet); |
| subscriber.init(new NullProgressMonitor()); |
| final ResourceMapping[] mappings = getResourceMappings(comparedFile, |
| ResourceMappingContext.LOCAL_CONTEXT); |
| |
| final RemoteResourceMappingContext remoteContext = new GitSubscriberResourceMappingContext(subscriber, |
| dataSet); |
| final SubscriberScopeManager manager = new SubscriberScopeManager(subscriber.getName(), mappings, |
| subscriber, remoteContext, true); |
| final GitSubscriberMergeContext context = new GitSubscriberMergeContext(subscriber, manager, dataSet); |
| disposers.add(new Runnable() { |
| @Override |
| public void run() { |
| manager.dispose(); |
| context.dispose(); |
| subscriber.dispose(); |
| } |
| }); |
| return context.getSubscriber(); |
| } |
| |
| /** |
| * Simulate a comparison between the two given references and returns back the subscriber that can provide |
| * all computed synchronization information. It will use a remote comparison context for retrieving the |
| * resource mappings. |
| * |
| * @param sourceRef |
| * Source reference (i.e. "left" side of the comparison). |
| * @param targetRef |
| * Target reference (i.e. "right" side of the comparison). |
| * @param comparedFile |
| * The file we are comparing (that would be the file right-clicked into the workspace). |
| * @return The created subscriber. |
| */ |
| public Subscriber createSubscriberForComparisonWithRemoteMappings(String sourceRef, String targetRef, |
| IFile comparedFile) throws IOException { |
| final GitSynchronizeData data = new GitSynchronizeData(repository, sourceRef, targetRef, false); |
| final GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data); |
| final GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(dataSet); |
| subscriber.init(new NullProgressMonitor()); |
| |
| final RemoteResourceMappingContext remoteContext = new GitSubscriberResourceMappingContext(subscriber, |
| dataSet); |
| final ResourceMapping[] mappings = getResourceMappings(comparedFile, remoteContext); |
| final SubscriberScopeManager manager = new SubscriberScopeManager(subscriber.getName(), mappings, |
| subscriber, remoteContext, true); |
| final GitSubscriberMergeContext context = new GitSubscriberMergeContext(subscriber, manager, dataSet); |
| disposers.add(new Runnable() { |
| @Override |
| public void run() { |
| manager.dispose(); |
| context.dispose(); |
| subscriber.dispose(); |
| } |
| }); |
| return context.getSubscriber(); |
| } |
| |
| public String getRepoRelativePath(File file) { |
| return getRepoRelativePath(new Path(file.getPath()).toString()); |
| } |
| |
| public String getRepoRelativePath(String path) { |
| final int pfxLen = workdirPrefix.length(); |
| final int pLen = path.length(); |
| if (pLen > pfxLen) { |
| return path.substring(pfxLen); |
| } else if (path.length() == pfxLen - 1) { |
| return ""; |
| } |
| return null; |
| } |
| |
| /** |
| * This will query all model providers for those that are enabled on the given file and list all mappings |
| * available for that file. |
| * |
| * @param file |
| * The file for which we need the associated resource mappings. |
| * @param context |
| * The {@link ResourceMappingContext} that will be used for retrieving the mappings. |
| * @return All mappings available for that file. |
| */ |
| private static ResourceMapping[] getResourceMappings(IFile file, ResourceMappingContext context) { |
| final IModelProviderDescriptor[] modelDescriptors = ModelProvider.getModelProviderDescriptors(); |
| |
| final Set<ResourceMapping> mappings = new LinkedHashSet<>(); |
| for (IModelProviderDescriptor candidate : modelDescriptors) { |
| try { |
| final IResource[] resources = candidate.getMatchingResources(new IResource[] {file, }); |
| if (resources.length > 0) { |
| // get mappings from model provider if there are matching |
| // resources |
| final ModelProvider model = candidate.getModelProvider(); |
| final ResourceMapping[] modelMappings = model.getMappings(file, context, null); |
| for (ResourceMapping mapping : modelMappings) { |
| mappings.add(mapping); |
| } |
| } |
| } catch (CoreException e) { |
| Activator.logError(e.getMessage(), e); |
| } |
| } |
| return mappings.toArray(new ResourceMapping[mappings.size()]); |
| } |
| } |