diff options
author | Michael Valenta | 2004-05-04 16:43:52 +0000 |
---|---|---|
committer | Michael Valenta | 2004-05-04 16:43:52 +0000 |
commit | 0da3050e6a660690866ffda2978170acb0e02dfd (patch) | |
tree | cc6fab509737989bd0cefdbdbace7411bee826fc | |
parent | ba57d9a05f3bce0bbfd778491fb9e4df33d37ec1 (diff) | |
download | eclipse.platform.team-0da3050e6a660690866ffda2978170acb0e02dfd.tar.gz eclipse.platform.team-0da3050e6a660690866ffda2978170acb0e02dfd.tar.xz eclipse.platform.team-0da3050e6a660690866ffda2978170acb0e02dfd.zip |
56249: Make all operations proper granularity
8 files changed, 370 insertions, 399 deletions
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java index 5a544853d..ef88134fd 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java @@ -10,26 +10,67 @@ *******************************************************************************/ package org.eclipse.team.internal.ccvs.core; -import java.io.*; -import java.util.*; -import org.eclipse.core.resources.*; +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFileModificationValidator; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectNature; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceRuleFactory; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.team.IMoveDeleteHook; import org.eclipse.core.resources.team.ResourceRuleFactory; -import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.MultiRule; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.ccvs.core.client.*; +import org.eclipse.team.internal.ccvs.core.client.Command; +import org.eclipse.team.internal.ccvs.core.client.Commit; +import org.eclipse.team.internal.ccvs.core.client.Diff; +import org.eclipse.team.internal.ccvs.core.client.Session; import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption; import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; -import org.eclipse.team.internal.ccvs.core.client.listeners.*; -import org.eclipse.team.internal.ccvs.core.connection.CVSServerException; +import org.eclipse.team.internal.ccvs.core.client.listeners.AdminKSubstListener; +import org.eclipse.team.internal.ccvs.core.client.listeners.DiffListener; +import org.eclipse.team.internal.ccvs.core.client.listeners.EditorsListener; +import org.eclipse.team.internal.ccvs.core.client.listeners.ICommandOutputListener; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; -import org.eclipse.team.internal.ccvs.core.syncinfo.*; -import org.eclipse.team.internal.ccvs.core.util.*; +import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; +import org.eclipse.team.internal.ccvs.core.syncinfo.MutableResourceSyncInfo; +import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; +import org.eclipse.team.internal.ccvs.core.util.Assert; +import org.eclipse.team.internal.ccvs.core.util.MoveDeleteHook; +import org.eclipse.team.internal.ccvs.core.util.ResourceStateChangeListeners; +import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; import org.eclipse.team.internal.core.streams.CRLFtoLFInputStream; import org.eclipse.team.internal.core.streams.LFtoCRLFInputStream; @@ -157,8 +198,6 @@ public class CVSTeamProvider extends RepositoryProvider { public IProject getProject() { return project; } - - /** * @see IProjectNature#setProject(IProject) @@ -176,48 +215,6 @@ public class CVSTeamProvider extends RepositoryProvider { } } - /** - * Checkin any local changes using "cvs commit ...". - * - * TODO: This method can be removed once the RelEng plugin no longer uses it - * @deprecated use CommitOperation instead - */ - public void checkin(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException { - - // Build the local options - List localOptions = new ArrayList(); - localOptions.add(Commit.makeArgumentOption(Command.MESSAGE_OPTION, comment)); - - // If the depth is not infinite, we want the -l option - if (depth != IResource.DEPTH_INFINITE) { - localOptions.add(Commit.DO_NOT_RECURSE); - } - LocalOption[] commandOptions = (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]); - - // Build the arguments list - String[] arguments = getValidArguments(resources, commandOptions); - - // Commit the resources - IStatus status; - Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot()); - progress.beginTask(null, 100); - try { - // Opening the session takes 20% of the time - s.open(Policy.subMonitorFor(progress, 20), true /* open for modification */); - status = Command.COMMIT.execute(s, - Command.NO_GLOBAL_OPTIONS, - commandOptions, - arguments, null, - Policy.subMonitorFor(progress, 80)); - } finally { - s.close(); - progress.done(); - } - if (status.getCode() == CVSStatus.SERVER_ERROR) { - throw new CVSServerException(status); - } - } - /** * Diff the resources with the repository and write the output to the provided * PrintStream in a form that is usable as a patch. The patch is rooted at the @@ -397,86 +394,6 @@ public class CVSTeamProvider extends RepositoryProvider { throw e; } } - - /* - * Use specialiazed tagging to move all local changes (including additions and - * deletions) to the specified branch. - */ - public void makeBranch(IResource[] resources, final CVSTag versionTag, final CVSTag branchTag, boolean moveToBranch, IProgressMonitor monitor) throws TeamException { - - // Determine the total amount of work - int totalWork = (versionTag!= null ? 60 : 40) + (moveToBranch ? 20 : 0); - monitor.beginTask(Policy.bind("CVSTeamProvider.makeBranch"), totalWork); //$NON-NLS-1$ - try { - // Build the arguments list - final ICVSResource[] arguments = getCVSArguments(resources); - - // Tag the remote resources - IStatus status = null; - if (versionTag != null) { - // Version using a custom tag command that skips added but not commited reesources - Session session = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot(), true /* output to console */); - session.open(Policy.subMonitorFor(monitor, 5), true /* open for modification */); - try { - status = Command.CUSTOM_TAG.execute( - session, - Command.NO_GLOBAL_OPTIONS, - Command.NO_LOCAL_OPTIONS, - versionTag, - arguments, - null, - Policy.subMonitorFor(monitor, 35)); - } finally { - session.close(); - } - if (status.isOK()) { - // Branch using the tag - session = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot(), true /* output to console */); - session.open(Policy.subMonitorFor(monitor, 5), true /* open for modification */); - try { - status = Command.CUSTOM_TAG.execute( - session, - Command.NO_GLOBAL_OPTIONS, - Command.NO_LOCAL_OPTIONS, - branchTag, - arguments, - null, - Policy.subMonitorFor(monitor, 15)); - } finally { - session.close(); - } - } - } else { - // Just branch using tag - Session session = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot(), true /* output to console */); - session.open(Policy.subMonitorFor(monitor, 5), true /* open for modification */); - try { - status = Command.CUSTOM_TAG.execute( - session, - Command.NO_GLOBAL_OPTIONS, - Command.NO_LOCAL_OPTIONS, - branchTag, - arguments, - null, - Policy.subMonitorFor(monitor, 35)); - } finally { - session.close(); - } - - } - if ( ! status.isOK()) { - throw new CVSServerException(status); - } - - // Set the tag of the local resources to the branch tag (The update command will not - // properly update "cvs added" and "cvs removed" resources so a custom visitor is used - if (moveToBranch) { - setTag(resources, branchTag, Policy.subMonitorFor(monitor, 20)); - } - } finally { - monitor.done(); - } - } /** * Set the comment to be used on the next checkin @@ -486,99 +403,6 @@ public class CVSTeamProvider extends RepositoryProvider { } /* - * This method sets the tag for a project. - * It expects to be passed an InfiniteSubProgressMonitor - */ - private void setTag(final IResource[] resources, final CVSTag tag, IProgressMonitor monitor) throws TeamException { - - workspaceRoot.getLocalRoot().run(new ICVSRunnable() { - public void run(IProgressMonitor progress) throws CVSException { - try { - // 512 ticks gives us a maximum of 2048 which seems reasonable for folders and files in a project - progress.beginTask(null, 100); - final IProgressMonitor monitor = Policy.infiniteSubMonitorFor(progress, 100); - monitor.beginTask(Policy.bind("CVSTeamProvider.folderInfo", project.getName()), 512); //$NON-NLS-1$ - - // Visit all the children folders in order to set the root in the folder sync info - for (int i = 0; i < resources.length; i++) { - CVSWorkspaceRoot.getCVSResourceFor(resources[i]).accept(new ICVSResourceVisitor() { - public void visitFile(ICVSFile file) throws CVSException { - monitor.worked(1); - //ResourceSyncInfo info = file.getSyncInfo(); - byte[] syncBytes = file.getSyncBytes(); - if (syncBytes != null) { - monitor.subTask(Policy.bind("CVSTeamProvider.updatingFile", file.getName())); //$NON-NLS-1$ - file.setSyncBytes(ResourceSyncInfo.setTag(syncBytes, tag), ICVSFile.UNKNOWN); - } - } - public void visitFolder(ICVSFolder folder) throws CVSException { - monitor.worked(1); - FolderSyncInfo info = folder.getFolderSyncInfo(); - if (info != null) { - monitor.subTask(Policy.bind("CVSTeamProvider.updatingFolder", info.getRepository())); //$NON-NLS-1$ - folder.setFolderSyncInfo(new FolderSyncInfo(info.getRepository(), info.getRoot(), tag, info.getIsStatic())); - folder.acceptChildren(this); - } - } - }); - } - } finally { - progress.done(); - } - } - }, monitor); - } - - /** - * Generally useful update. - * - * The tag parameter determines any stickyness after the update is run. If tag is null, any tagging on the - * resources being updated remain the same. If the tag is a branch, version or date tag, then the resources - * will be appropriatly tagged. If the tag is HEAD, then there will be no tag on the resources (same as -A - * clear sticky option). - * - * TODO: This method can be removed once the RelEng plugin no longer uses it - * @param createBackups if true, creates .# files for updated files - * @deprecated use UpdateOperation instead - */ - public void update(IResource[] resources, LocalOption[] options, CVSTag tag, boolean createBackups, IProgressMonitor progress) throws TeamException { - progress.beginTask(null, 100); - Session session = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot(), true /* output to console */); - session.open(Policy.subMonitorFor(progress,10), false /* read-only */); - try { - update(session, resources, options, tag, createBackups, Policy.subMonitorFor(progress, 90)); - } finally { - session.close(); - } - } - - private void update(Session session, IResource[] resources, LocalOption[] options, CVSTag tag, boolean createBackups, IProgressMonitor progress) throws TeamException { - // Build the local options - List localOptions = new ArrayList(); - - // Use the appropriate tag options - if (tag != null) { - localOptions.add(Update.makeTagOption(tag)); - } - - // Build the arguments list - localOptions.addAll(Arrays.asList(options)); - final LocalOption[] commandOptions = (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]); - final ICVSResource[] arguments = getCVSArguments(resources); - - IStatus status = Command.UPDATE.execute( - session, - Command.NO_GLOBAL_OPTIONS, - commandOptions, - arguments, - null, - progress); - if (status.getCode() == CVSStatus.SERVER_ERROR) { - throw new CVSServerException(status); - } - } - - /* * @see ITeamProvider#isDirty(IResource) */ public boolean isDirty(IResource resource) { diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/messages.properties b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/messages.properties index 36f75f315..9a4460757 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/messages.properties +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/messages.properties @@ -88,11 +88,7 @@ CVSTeamProvider.checkinProblems=Problems occurred committing resources to server CVSTeamProvider.invalidProjectState=CVS sharing information is missing from project {0} CVSTeamProvider.typesDiffer=Error retrieving remote resource tree. Local and remote resource types differ for {0} CVSTeamProvider.connectionInfo=Updating connection information for project {0} -CVSTeamProvider.folderInfo=Updating folder synchronization information for project {0} -CVSTeamProvider.updatingFolder=Updating {0} CVSTeamProvider.scrubbingResource=Scrubbing {0} -CVSTeamProvider.updatingFile=Updating {0} -CVSTeamProvider.makeBranch=Creating branch CVSTeamProvider.preparingToSetKSubst=Preparing to set keyword substitution mode CVSTeamProvider.settingKSubst=Setting keyword substitution mode CVSTeamProvider.cleanLineDelimitersException=Exception occurred while cleaning line delimiters diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/BranchAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/BranchAction.java index c79269e39..94eac3ad1 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/BranchAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/BranchAction.java @@ -11,34 +11,8 @@ package org.eclipse.team.internal.ccvs.ui.actions; import java.lang.reflect.InvocationTargetException; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.InputDialog; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSTag; -import org.eclipse.team.internal.ccvs.core.CVSTeamProvider; -import org.eclipse.team.internal.ccvs.core.ICVSFile; -import org.eclipse.team.internal.ccvs.core.ICVSFolder; -import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; -import org.eclipse.team.internal.ccvs.core.ICVSResource; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; -import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; -import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; -import org.eclipse.team.internal.ccvs.ui.BranchPromptDialog; -import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; -import org.eclipse.team.internal.ccvs.ui.Policy; -import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; -import org.eclipse.ui.actions.WorkspaceModifyOperation; +import org.eclipse.team.internal.ccvs.ui.operations.BranchOperation; /** * BranchAction tags the selected resources with a branch tag specified by the user, @@ -46,147 +20,11 @@ import org.eclipse.ui.actions.WorkspaceModifyOperation; */ public class BranchAction extends WorkspaceAction { - /* - * @see CVSAction#execute() + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.actions.CVSAction#execute(org.eclipse.jface.action.IAction) */ public void execute(IAction action) throws InvocationTargetException, InterruptedException { - - // Prompt for the branch tag and whether to start working in the branch - final IResource[] resources = getSelectedResources(); - boolean allSticky = areAllResourcesSticky(resources); - ICVSFolder folder = CVSWorkspaceRoot.getCVSFolderFor(resources[0].getProject()); - final BranchPromptDialog dialog = new BranchPromptDialog(getShell(), - Policy.bind("BranchWizard.title"), //$NON-NLS-1$ - folder, - allSticky, - calculateInitialVersionName(resources,allSticky)); - if (dialog.open() != InputDialog.OK) return; - - // Capture the dialog info in local variables - final String tagString = dialog.getBranchTagName(); - final boolean update = dialog.getUpdate(); - final String versionString = dialog.getVersionTagName(); - final CVSTag rootVersionTag = (versionString == null) ? null : new CVSTag(versionString, CVSTag.VERSION); - final CVSTag branchTag = new CVSTag(tagString, CVSTag.BRANCH); - - // For non-projects determine if the tag being loaded is the same as the resource's parent - // If it's not, warn the user that they will be mixing tags - if (update) { - try { - if(!CVSAction.checkForMixingTags(getShell(), resources, branchTag)) { - return; - } - } catch (CVSException e) { - throw new InvocationTargetException(e); - } - } - - final RepositoryManager manager = CVSUIPlugin.getPlugin().getRepositoryManager(); - - // perform the branch - run(new WorkspaceModifyOperation() { - public void execute(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - - Hashtable table = getProviderMapping(resources); - Set keySet = table.keySet(); - monitor.beginTask(null, keySet.size() * 1000); - Iterator iterator = keySet.iterator(); - while (iterator.hasNext()) { - IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1000); - CVSTeamProvider provider = (CVSTeamProvider)iterator.next(); - List list = (List)table.get(provider); - IResource[] providerResources = (IResource[])list.toArray(new IResource[list.size()]); - try { - ICVSRepositoryLocation root = provider.getCVSWorkspaceRoot().getRemoteLocation(); - if (!areAllResourcesSticky(resources)) { - // version everything in workspace with the root version tag specified in dialog - provider.makeBranch(providerResources, rootVersionTag, branchTag, update, subMonitor); - } else { - // all resources are versions, use that version as the root of the branch - provider.makeBranch(providerResources, null, branchTag, update, subMonitor); - } - if (rootVersionTag != null || update) { - for (int i = 0; i < providerResources.length; i++) { - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(providerResources[i]); - if (rootVersionTag != null) { - manager.addTags(cvsResource, new CVSTag[] { rootVersionTag }); - } - if (update) { - manager.addTags(cvsResource, new CVSTag[] { branchTag }); - } - } - } - } catch (TeamException e) { - // Accumulate the status which will be displayed by CVSAction#endOperation(IAction) - addStatus(e.getStatus()); - } - } - } - }, true /* cancelable */, PROGRESS_DIALOG); - } - - /** - * Answers <code>true</code> if all resources in the array have a sticky tag - */ - private boolean areAllResourcesSticky(IResource[] resources) { - for (int i = 0; i < resources.length; i++) { - if(!hasStickyTag(resources[i])) return false; - } - return true; - } - - /** - * Answers <code>true</code> if the resource has a sticky tag - */ - private boolean hasStickyTag(IResource resource) { - try { - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); - CVSTag tag; - if(cvsResource.isFolder()) { - FolderSyncInfo folderInfo = ((ICVSFolder)cvsResource).getFolderSyncInfo(); - tag = folderInfo.getTag(); - } else { - ResourceSyncInfo info = cvsResource.getSyncInfo(); - tag = info.getTag(); - } - if(tag!=null) { - int tagType = tag.getType(); - if(tagType==CVSTag.VERSION) { - return true; - } - } - } catch(CVSException e) { - CVSUIPlugin.log(e); - return false; - } - return false; - } - - private String calculateInitialVersionName(IResource[] resources, boolean allSticky) { - String versionName = ""; //$NON-NLS-1$ - try { - if(allSticky) { - IResource stickyResource = resources[0]; - if(stickyResource.getType()==IResource.FILE) { - ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor((IFile)stickyResource); - versionName = cvsFile.getSyncInfo().getTag().getName(); - } else { - ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor((IContainer)stickyResource); - versionName = cvsFolder.getFolderSyncInfo().getTag().getName(); - } - } - } catch(CVSException e) { - CVSUIPlugin.log(e); - versionName = ""; //$NON-NLS-1$ - } - return versionName; - } - - /** - * @see org.eclipse.team.internal.ccvs.ui.actions.CVSAction#getErrorTitle() - */ - protected String getErrorTitle() { - return Policy.bind("BranchWizard.errorBranching"); //$NON-NLS-1$ + new BranchOperation(getTargetPart(), getSelectedResources()).run(); } } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties index 0d4cd58a0..4f3f3fed8 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties @@ -1116,3 +1116,8 @@ CheckoutAsWizard.3=Select Tag CheckoutAsWizard.4=Choose the tag to check out from CheckoutAsWizard.5=&Select tag CheckoutAsMainPage.10=(Only available when the .project file does not exist in the repository) +CVSTeamProvider.updatingFile=Updating {0} +CVSTeamProvider.makeBranch=Creating branch +CVSTeamProvider.folderInfo=Updating folder synchronization information for project {0} +CVSTeamProvider.updatingFolder=Updating {0} +BranchOperation.0=Branching diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/BranchOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/BranchOperation.java new file mode 100644 index 000000000..2af0e6d00 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/BranchOperation.java @@ -0,0 +1,302 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.operations; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.internal.ccvs.core.CVSException; +import org.eclipse.team.internal.ccvs.core.CVSTag; +import org.eclipse.team.internal.ccvs.core.CVSTeamProvider; +import org.eclipse.team.internal.ccvs.core.ICVSFile; +import org.eclipse.team.internal.ccvs.core.ICVSFolder; +import org.eclipse.team.internal.ccvs.core.ICVSResource; +import org.eclipse.team.internal.ccvs.core.ICVSResourceVisitor; +import org.eclipse.team.internal.ccvs.core.ICVSRunnable; +import org.eclipse.team.internal.ccvs.core.client.Command; +import org.eclipse.team.internal.ccvs.core.client.Session; +import org.eclipse.team.internal.ccvs.core.connection.CVSServerException; +import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; +import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; +import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; +import org.eclipse.team.internal.ccvs.ui.BranchPromptDialog; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; +import org.eclipse.team.internal.ccvs.ui.Policy; +import org.eclipse.team.internal.ccvs.ui.actions.CVSAction; +import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; +import org.eclipse.ui.IWorkbenchPart; + +/** + * Perform a CVS branch operaiton + */ +public class BranchOperation extends RepositoryProviderOperation { + + private boolean update; + private CVSTag rootVersionTag; + private CVSTag branchTag; + + public BranchOperation(IWorkbenchPart part, IResource[] resources) { + super(part, resources); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.TeamOperation#shouldRun() + */ + protected boolean shouldRun() { + IResource[] resources = getResources(); + boolean allSticky = areAllResourcesSticky(resources); + ICVSFolder folder = CVSWorkspaceRoot.getCVSFolderFor(resources[0].getProject()); + final BranchPromptDialog dialog = new BranchPromptDialog(getShell(), + Policy.bind("BranchWizard.title"), //$NON-NLS-1$ + folder, + allSticky, + calculateInitialVersionName(resources,allSticky)); + if (dialog.open() != InputDialog.OK) return false; + + // Capture the dialog info in local variables + final String tagString = dialog.getBranchTagName(); + update = dialog.getUpdate(); + final String versionString = dialog.getVersionTagName(); + rootVersionTag = (versionString == null) ? null : new CVSTag(versionString, CVSTag.VERSION); + branchTag = new CVSTag(tagString, CVSTag.BRANCH); + + // For non-projects determine if the tag being loaded is the same as the resource's parent + // If it's not, warn the user that they will be mixing tags + if (update) { + try { + if(!CVSAction.checkForMixingTags(getShell(), resources, branchTag)) { + return false; + } + } catch (CVSException e) { + CVSUIPlugin.log(e); + } + } + return super.shouldRun(); + } + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.RepositoryProviderOperation#execute(org.eclipse.team.internal.ccvs.core.CVSTeamProvider, org.eclipse.core.resources.IResource[], org.eclipse.core.runtime.IProgressMonitor) + */ + protected void execute(CVSTeamProvider provider, IResource[] providerResources, IProgressMonitor monitor) throws CVSException, InterruptedException { + try { + makeBranch(provider, providerResources, rootVersionTag, branchTag, update, monitor); + updateRememberedags(providerResources); + collectStatus(Status.OK_STATUS); + } catch (TeamException e) { + // Accumulate the status which will be displayed by CVSAction#endOperation(IAction) + collectStatus(e.getStatus()); + } + } + + private void makeBranch(CVSTeamProvider provider, IResource[] resources, final CVSTag versionTag, final CVSTag branchTag, boolean moveToBranch, IProgressMonitor monitor) throws TeamException { + + // Determine the total amount of work + int totalWork = (versionTag!= null ? 60 : 40) + (moveToBranch ? 20 : 0); + monitor.beginTask(Policy.bind("CVSTeamProvider.makeBranch"), totalWork); //$NON-NLS-1$ + try { + // Build the arguments list + final ICVSResource[] arguments = getCVSArguments(resources); + + // Tag the remote resources + IStatus status = null; + if (versionTag != null) { + // Version using a custom tag command that skips added but not commited reesources + Session session = new Session(getRemoteLocation(provider), getLocalRoot(provider), true /* output to console */); + session.open(Policy.subMonitorFor(monitor, 5), true /* open for modification */); + try { + status = Command.CUSTOM_TAG.execute( + session, + Command.NO_GLOBAL_OPTIONS, + Command.NO_LOCAL_OPTIONS, + versionTag, + arguments, + null, + Policy.subMonitorFor(monitor, 35)); + } finally { + session.close(); + } + if (status.isOK()) { + // Branch using the tag + session = new Session(getRemoteLocation(provider), getLocalRoot(provider), true /* output to console */); + session.open(Policy.subMonitorFor(monitor, 5), true /* open for modification */); + try { + status = Command.CUSTOM_TAG.execute( + session, + Command.NO_GLOBAL_OPTIONS, + Command.NO_LOCAL_OPTIONS, + branchTag, + arguments, + null, + Policy.subMonitorFor(monitor, 15)); + } finally { + session.close(); + } + } + } else { + // Just branch using tag + Session session = new Session(getRemoteLocation(provider), getLocalRoot(provider), true /* output to console */); + session.open(Policy.subMonitorFor(monitor, 5), true /* open for modification */); + try { + status = Command.CUSTOM_TAG.execute( + session, + Command.NO_GLOBAL_OPTIONS, + Command.NO_LOCAL_OPTIONS, + branchTag, + arguments, + null, + Policy.subMonitorFor(monitor, 35)); + } finally { + session.close(); + } + + } + if ( ! status.isOK()) { + throw new CVSServerException(status); + } + + // Set the tag of the local resources to the branch tag (The update command will not + // properly update "cvs added" and "cvs removed" resources so a custom visitor is used + if (moveToBranch) { + setTag(provider, resources, branchTag, Policy.subMonitorFor(monitor, 20)); + } + } finally { + monitor.done(); + } + } + + /* + * This method sets the tag for a project. + * It expects to be passed an InfiniteSubProgressMonitor + */ + private void setTag(final CVSTeamProvider provider, final IResource[] resources, final CVSTag tag, IProgressMonitor monitor) throws TeamException { + + getLocalRoot(provider).run(new ICVSRunnable() { + public void run(IProgressMonitor progress) throws CVSException { + try { + // 512 ticks gives us a maximum of 2048 which seems reasonable for folders and files in a project + progress.beginTask(null, 100); + final IProgressMonitor monitor = Policy.infiniteSubMonitorFor(progress, 100); + monitor.beginTask(Policy.bind("CVSTeamProvider.folderInfo", provider.getProject().getName()), 512); //$NON-NLS-1$ + + // Visit all the children folders in order to set the root in the folder sync info + for (int i = 0; i < resources.length; i++) { + CVSWorkspaceRoot.getCVSResourceFor(resources[i]).accept(new ICVSResourceVisitor() { + public void visitFile(ICVSFile file) throws CVSException { + monitor.worked(1); + //ResourceSyncInfo info = file.getSyncInfo(); + byte[] syncBytes = file.getSyncBytes(); + if (syncBytes != null) { + monitor.subTask(Policy.bind("CVSTeamProvider.updatingFile", file.getName())); //$NON-NLS-1$ + file.setSyncBytes(ResourceSyncInfo.setTag(syncBytes, tag), ICVSFile.UNKNOWN); + } + } + public void visitFolder(ICVSFolder folder) throws CVSException { + monitor.worked(1); + FolderSyncInfo info = folder.getFolderSyncInfo(); + if (info != null) { + monitor.subTask(Policy.bind("CVSTeamProvider.updatingFolder", info.getRepository())); //$NON-NLS-1$ + folder.setFolderSyncInfo(new FolderSyncInfo(info.getRepository(), info.getRoot(), tag, info.getIsStatic())); + folder.acceptChildren(this); + } + } + }); + } + } finally { + progress.done(); + } + } + }, monitor); + } + + private void updateRememberedags(IResource[] providerResources) throws CVSException { + if (rootVersionTag != null || update) { + for (int i = 0; i < providerResources.length; i++) { + ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(providerResources[i]); + RepositoryManager manager = CVSUIPlugin.getPlugin().getRepositoryManager(); + + if (rootVersionTag != null) { + manager.addTags(cvsResource, new CVSTag[] { rootVersionTag }); + } + if (update) { + manager.addTags(cvsResource, new CVSTag[] { branchTag }); + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getTaskName() + */ + protected String getTaskName() { + return Policy.bind("BranchOperation.0"); //$NON-NLS-1$ + } + + /** + * Answers <code>true</code> if all resources in the array have a sticky tag + */ + private boolean areAllResourcesSticky(IResource[] resources) { + for (int i = 0; i < resources.length; i++) { + if(!hasStickyTag(resources[i])) return false; + } + return true; + } + + /** + * Answers <code>true</code> if the resource has a sticky tag + */ + private boolean hasStickyTag(IResource resource) { + try { + ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); + CVSTag tag; + if(cvsResource.isFolder()) { + FolderSyncInfo folderInfo = ((ICVSFolder)cvsResource).getFolderSyncInfo(); + tag = folderInfo.getTag(); + } else { + ResourceSyncInfo info = cvsResource.getSyncInfo(); + tag = info.getTag(); + } + if(tag!=null) { + int tagType = tag.getType(); + if(tagType==CVSTag.VERSION) { + return true; + } + } + } catch(CVSException e) { + CVSUIPlugin.log(e); + return false; + } + return false; + } + + private String calculateInitialVersionName(IResource[] resources, boolean allSticky) { + String versionName = ""; //$NON-NLS-1$ + try { + if(allSticky) { + IResource stickyResource = resources[0]; + if(stickyResource.getType()==IResource.FILE) { + ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor((IFile)stickyResource); + versionName = cvsFile.getSyncInfo().getTag().getName(); + } else { + ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor((IContainer)stickyResource); + versionName = cvsFolder.getFolderSyncInfo().getTag().getName(); + } + } + } catch(CVSException e) { + CVSUIPlugin.log(e); + versionName = ""; //$NON-NLS-1$ + } + return versionName; + } +} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java index e3221affd..aa75eb0dd 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java @@ -287,6 +287,12 @@ public class EclipseTest extends EclipseWorkspaceTest { } } } + public void makeBranch(IResource[] resources, CVSTag version, CVSTag branch, boolean update) throws CVSException { + BranchOperation op = new BranchOperation(null, resources) { + + }; + executeHeadless(op); + } /** * Return a collection of resources defined by hierarchy. The resources * are added to the workspace and to the file system. If the manage flag is true, the diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/CVSProviderTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/CVSProviderTest.java index 9b02b246b..3ac8b4925 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/CVSProviderTest.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/CVSProviderTest.java @@ -189,7 +189,7 @@ public class CVSProviderTest extends EclipseTest { // Make the branch including a pre-version CVSTag version = new CVSTag("v1", CVSTag.BRANCH); CVSTag branch = new CVSTag("branch1", CVSTag.BRANCH); - getProvider(project).makeBranch(new IResource[] {project}, version, branch, true, DEFAULT_MONITOR); + makeBranch(new IResource[] {project}, version, branch, true); // Checkout a copy from the branch and version and compare IProject branchCopy = checkoutCopy(project, branch); @@ -201,7 +201,7 @@ public class CVSProviderTest extends EclipseTest { updateProject(branchCopy, null, false); assertEquals(branchCopy, project, false, true); } - + public void testPruning() throws TeamException, CoreException, IOException { // Create a project with empty folders CVSProviderPlugin.getPlugin().setPruneEmptyDirectories(false); diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSWorkspaceSubscriberTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSWorkspaceSubscriberTest.java index 3f848316e..dfd282e78 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSWorkspaceSubscriberTest.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSWorkspaceSubscriberTest.java @@ -1049,7 +1049,7 @@ public class CVSWorkspaceSubscriberTest extends CVSSyncSubscriberTest { IProject copy = checkoutCopy(project, "-copy"); CVSTag version = new CVSTag("v1", CVSTag.BRANCH); CVSTag branch = new CVSTag("branch1", CVSTag.BRANCH); - getProvider(copy).makeBranch(new IResource[] {copy}, version, branch, true, DEFAULT_MONITOR); + makeBranch(new IResource[] {copy}, version, branch, true); addResources(copy, new String[] {"folder2/folder3/a.txt"}, true); // Fetch the tree corresponding to the branch using the original as the base. |