Class MergeContext
- All Implemented Interfaces:
IAdaptable
,IMergeContext
,ISynchronizationContext
- Direct Known Subclasses:
SubscriberMergeContext
IResourceMappingMerger
.
It provides access to the ancestor and remote resource mapping contexts
so that resource mapping mergers can attempt head-less auto-merges.
The ancestor context is only required for merges while the remote
is required for both merge and replace.- Since:
- 3.2
- See Also:
-
Field Summary
Fields inherited from interface org.eclipse.team.core.mapping.ISynchronizationContext
THREE_WAY, TWO_WAY
-
Constructor Summary
ModifierConstructorDescriptionprotected
MergeContext
(ISynchronizationScopeManager manager, int type, IResourceDiffTree deltaTree) Create a merge context. -
Method Summary
Modifier and TypeMethodDescriptionprotected void
ensureParentsExist
(IResource resource, IProgressMonitor monitor) Ensure that the parent folders of the given resource exist.<T> T
getAdapter
(Class<T> adapter) Returns an object which is an instance of the given class associated with this object.getMergeRule
(IDiff diff) Default implementation that returns the resource itself if it exists and the first existing parent if the resource does not exist.getMergeRule
(IDiff[] deltas) Return the scheduling rule that is required to merge (or reject) the resources associated with the given diffs.int
Return the type of merge that will be performed when using this context (eitherISynchronizationContext.TWO_WAY
orISynchronizationContext.THREE_WAY
).protected abstract void
makeInSync
(IDiff diff, IProgressMonitor monitor) Method that is invoked fromperformReplace(IDiff, IProgressMonitor)
after the local has been changed to match the remote.void
markAsMerged
(IDiff[] nodes, boolean inSyncHint, IProgressMonitor monitor) Mark the files associated with the given diff nodes as being merged.merge
(IDiff[] deltas, boolean force, IProgressMonitor monitor) Attempt to merge any files associated with the given diffs.merge
(IDiff diff, boolean ignoreLocalChanges, IProgressMonitor monitor) Method that can be called by the model merger to attempt a file-system level merge.protected void
performReplace
(IDiff diff, IProgressMonitor monitor) Make the local state of the resource associated with the given diff match that of the remote.protected IStatus
performThreeWayMerge
(IThreeWayDiff diff, IProgressMonitor monitor) Perform a three-way merge on the given three-way diff that contains a content conflict.void
reject
(IDiff[] diffs, IProgressMonitor monitor) Reject the changes associated with the given diffs.void
run
(IWorkspaceRunnable runnable, ISchedulingRule rule, int flags, IProgressMonitor monitor) Methods inherited from class org.eclipse.team.core.mapping.provider.SynchronizationContext
dispose, getCache, getDiffTree, getScope, getScopeManager, getType, refresh
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface org.eclipse.team.core.mapping.IMergeContext
markAsMerged, reject
Methods inherited from interface org.eclipse.team.core.mapping.ISynchronizationContext
dispose, getCache, getDiffTree, getScope, getType, refresh, refresh
-
Constructor Details
-
MergeContext
Create a merge context.- Parameters:
manager
- the manager that defines the scope of the synchronizationtype
- the type of synchronization (ONE_WAY or TWO_WAY)deltaTree
- the sync info tree that contains all out-of-sync resources
-
-
Method Details
-
reject
Description copied from interface:IMergeContext
Reject the changes associated with the given diffs. This method is equivalent to callingIMergeContext.reject(IDiff, IProgressMonitor)
for each diff.- Specified by:
reject
in interfaceIMergeContext
- Parameters:
diffs
- the diffsmonitor
- a progress monitor- Throws:
CoreException
- if an error occurs
-
markAsMerged
public void markAsMerged(IDiff[] nodes, boolean inSyncHint, IProgressMonitor monitor) throws CoreException Description copied from interface:IMergeContext
Mark the files associated with the given diff nodes as being merged. This method is equivalent to callingIMergeContext.markAsMerged(IDiff, boolean, IProgressMonitor)
for each diff but gives the context the opportunity to optimize the operation for multiple files.This method will batch change notification by using the
IMergeContext.run(IWorkspaceRunnable, ISchedulingRule, int, IProgressMonitor)
method. The rule for he method will be obtained usingIMergeContext.getMergeRule(IDiff)
and the flags will beIResource.NONE
meaning that intermittent change events may occur. Clients may wrap the call in an outer run that either uses a broader scheduling rule or theIWorkspace.AVOID_UPDATES
flag.- Specified by:
markAsMerged
in interfaceIMergeContext
- Parameters:
nodes
- the nodes to be marked as mergedinSyncHint
- a hint to the context that the model persisted in the file is in-sync.monitor
- a progress monitor- Throws:
CoreException
- if errors occur
-
merge
Description copied from interface:IMergeContext
Attempt to merge any files associated with the given diffs. This method is equivalent to callingIMergeContext.merge(IDiff, boolean, IProgressMonitor)
for each diff individually but gives the context a chance to perform a more optimal merge involving multiple resources.This method will batch change notification by using the
IMergeContext.run(IWorkspaceRunnable, ISchedulingRule, int, IProgressMonitor)
method. The rule for he method will be obtained usingIMergeContext.getMergeRule(IDiff)
and the flags will beIResource.NONE
meaning that intermittent change events may occur. Clients may wrap the call in an outer run that either uses a broader scheduling rule or theIWorkspace.AVOID_UPDATES
flag.- Specified by:
merge
in interfaceIMergeContext
- Parameters:
deltas
- the differences to be mergedforce
- ignore any local changes when performing the merge.monitor
- a progress monitor- Returns:
- a status indicating success or failure. A code of
MergeStatus.CONFLICTS
indicates that the file contain non-mergable conflicts and must be merged manually. - Throws:
CoreException
- if an error occurs
-
merge
public IStatus merge(IDiff diff, boolean ignoreLocalChanges, IProgressMonitor monitor) throws CoreException Description copied from interface:IMergeContext
Method that can be called by the model merger to attempt a file-system level merge. This is useful for cases where the model merger does not need to do any special processing to perform the merge. By default, this method attempts to use an appropriateIStorageMerger
to merge the files covered by the provided traversals. If a storage merger cannot be found, the text merger is used. If this behavior is not desired, sub-classes ofMergeContext
may override this method.This method does a best-effort attempt to merge of the file associated with the given diff. A file that could not be merged will be indicated in the returned status. If the status returned has the code
MergeStatus.CONFLICTS
, the list of failed files can be obtained by calling theMergeStatus#getConflictingFiles()
method.It is not expected that clients of this API will associate special meaning with the existence of a folder other than the fact that it contains files. The sync delta tree should still include folder changes so that clients that have a one-to-one correspondence between their model objects and folders can decorate these elements appropriately. However, clients of this API will only be expected to perform operations on file deltas and will expect folders to be created as needed to contain the files (i.e. implementations of this method should ignore any folder deltas in the provided deltas). Clients will also expect local folders that have incoming folder deletions to be removed once all the folder's children have been removed using merge.
There are two special cases where merge is meaningful for folders. First, a merge on a local added empty folder with force set should delete the folder. However, the folder should not be deleted if it has any local children unless merge is called for those resources first and they end up being deleted as a result. Second, a merge on an incoming folder addition should create the empty folder locally.
It is not expected that clients of this API will be capable of dealing with namespace conflicts. Implementors should ensure that any namespace conflicts are dealt with before the merger is invoked.
The deltas provided to this method should be those obtained from the tree (
ISynchronizationContext.getDiffTree()
) of this context. Any resource changes triggered by this merge will be reported through the resource delta mechanism and the change notification mechanisms of the delta tree associated with this context.For two-way merging, as indicated by either the
ISynchronizationContext.getType()
orIMergeContext.getMergeType()
methods, clients can either accept changes using theIMergeContext.merge(IDiff[], boolean, IProgressMonitor)
method or reject them usingIMergeContext.markAsMerged(IDiff, boolean, IProgressMonitor)
. Three-way changes are a bit more complicated. The following list summarizes how particular remote file changes can be handled. The delta kind and flags mentioned in the descriptions are obtained the remote change (seeIThreeWayDiff.getRemoteChange()
), whereas conflicts are indicated by the three-way delta itself.- When the delta kind is
IDiff.ADD
and the delta is also a move (i.e. theITwoWayDiff.MOVE_FROM
is set). The merge can either use theIMergeContext.merge(IDiff[], boolean, IProgressMonitor)
method to accept the rename or perform anIFile.move(IPath, boolean, boolean, IProgressMonitor)
where the source file is obtained usingITwoWayDiff.getFromPath()
and the destination is the path of the delta (IDiff.getPath()
). This later approach is helpful in the case where the local file and remote file both contain content changes (i.e. the file can be moved by the model and then the contents can be merged by the model). - When the delta kind is
IDiff.REMOVE
and the delta is also a move (i.e. theITwoWayDiff.MOVE_TO
is set). The merge can either use theIMergeContext.merge(IDiff[], boolean, IProgressMonitor)
method to accept the rename or perform anIFile.move(IPath, boolean, boolean, IProgressMonitor)
where the source file is obtained usingIDiff.getPath()
and the destination is obtained fromITwoWayDiff.getToPath()
. This later approach is helpful in the case where the local file and remote file both contain content changes (i.e. the file can be moved by the model and then the contents can be merged by the model). - When the delta kind is
IDiff.ADD
and it is not part of a move, the merger must use theIMergeContext.merge(IDiff[], boolean, IProgressMonitor)
method to accept this change. If there is a conflicting addition, the force flag can be set to override the local change. If the model wishes to keep the local changes, they can overwrite the file after merging it. Models should consult the flags to see if the remote change is a rename (ITwoWayDiff.MOVE_FROM
). - When the delta kind is
IDiff.REMOVE
and it is not part of a move, the merger can use theIMergeContext.merge(IDiff[], boolean, IProgressMonitor)
method but could also perform the delete manually using any of theIFile
delete methods. In the case where there are local changes to the file being deleted, the model may either choose to merge using the force flag (thus removing the file and the local changes) or callIMergeContext.markAsMerged(IDiff, boolean, IProgressMonitor)
on the file which will convert the incoming deletion to an outgoing addition. - When the delta kind is
IDiff.CHANGE
and there is no conflict, the model is advised to use theIMergeContext.merge(IDiff[], boolean, IProgressMonitor)
method to merge these changes as this is the most efficient means to do so. However, the model can choose to perform the merge themselves and then invokeIMergeContext.markAsMerged(IDiff, boolean, IProgressMonitor)
with theinSyncHint
set totrue
but this will be less efficient. - When the delta kind is
IDiff.CHANGE
and there is a conflict, the model can use theIMergeContext.merge(IDiff[], boolean, IProgressMonitor)
method to merge these changes. If the force flag is not set, an auto-merge is attempted using an appropriateIStorageMerger
. If the force flag is set, the local changes are discarded. The model can choose to attempt the merge themselves and, if it is successful, invokeIMergeContext.markAsMerged(IDiff, boolean, IProgressMonitor)
with theinSyncHint
set tofalse
which will make the file an outgoing change.
- Specified by:
merge
in interfaceIMergeContext
- Parameters:
diff
- the difference to be mergedignoreLocalChanges
- ignore any local changes when performing the merge.monitor
- a progress monitor- Returns:
- a status indicating success or failure. A code of
MergeStatus.CONFLICTS
indicates that the file contain non-mergable conflicts and must be merged manually. - Throws:
CoreException
- if an error occurs- See Also:
- When the delta kind is
-
performThreeWayMerge
protected IStatus performThreeWayMerge(IThreeWayDiff diff, IProgressMonitor monitor) throws CoreException Perform a three-way merge on the given three-way diff that contains a content conflict. By default, this method makes use ofIStorageMerger
instances registered with thestorageMergers
extension point. Note that the ancestor of the given diff may be missing. SomeIStorageMerger
instances can still merge without an ancestor so we need to consult the appropriate merger to find out.- Parameters:
diff
- the diffmonitor
- a progress monitor- Returns:
- a status indicating the results of the merge
- Throws:
CoreException
-
performReplace
Make the local state of the resource associated with the given diff match that of the remote. This method is invoked by themerge(IDiff, boolean, IProgressMonitor)
method. By default, it either overwrites the local contexts with the remote contents if both exist, deletes the local if the remote does not exists or adds the local if the local doesn't exist but the remote does. It then callsmakeInSync(IDiff, IProgressMonitor)
to give subclasses a change to make the file associated with the diff in-sync.- Parameters:
diff
- the diff whose local is to be replacedmonitor
- a progress monitor- Throws:
CoreException
- if an error occurs
-
makeInSync
Method that is invoked fromperformReplace(IDiff, IProgressMonitor)
after the local has been changed to match the remote. Subclasses may overrideperformReplace(IDiff, IProgressMonitor)
or this method in order to properly reconcile the synchronization state. This method is also invoked frommerge(IDiff, boolean, IProgressMonitor)
if deletion conflicts are encountered. It can also be invoked from that same method if a folder is created due to an incoming folder addition.- Parameters:
diff
- the diff whose local is now in-syncmonitor
- a progress monitor- Throws:
CoreException
- if an error occurs
-
ensureParentsExist
protected void ensureParentsExist(IResource resource, IProgressMonitor monitor) throws CoreException Ensure that the parent folders of the given resource exist. This method is invoked fromperformReplace(IDiff, IProgressMonitor)
for files that are being merged that do not exist locally. By default, this method creates the parents usingIFolder.create(boolean, boolean, IProgressMonitor)
. Subclasses may override.- Parameters:
resource
- a resourcemonitor
- a progress monitor- Throws:
CoreException
- if an error occurs
-
run
public void run(IWorkspaceRunnable runnable, ISchedulingRule rule, int flags, IProgressMonitor monitor) throws CoreException - Specified by:
run
in interfaceIMergeContext
- Parameters:
runnable
- a workspace runnablerule
- a scheduling rule to be obtained while the runnable is runflags
- flags indicating when updates occur (eitherIResource.NONE
orIWorkspace.AVOID_UPDATE
.monitor
- a progress monitor- Throws:
CoreException
- if an error occurs- See Also:
-
getMergeRule
Default implementation that returns the resource itself if it exists and the first existing parent if the resource does not exist. Subclass should override to provide the appropriate rule.- Specified by:
getMergeRule
in interfaceIMergeContext
- Parameters:
diff
- the diff to be merged- Returns:
- the scheduling rule that is required to merge the resource of the given diff
- See Also:
-
getMergeRule
Description copied from interface:IMergeContext
Return the scheduling rule that is required to merge (or reject) the resources associated with the given diffs. If a resource being merged is a folder or project, the returned rule will be sufficient to merge any files contained in the folder or project. The returned rule also applies toIMergeContext.markAsMerged(IDiff[], boolean, IProgressMonitor)
andIMergeContext.reject(IDiff[], IProgressMonitor)
.- Specified by:
getMergeRule
in interfaceIMergeContext
- Parameters:
deltas
- the diffs being merged- Returns:
- the scheduling rule that is required to merge the resources of the given diffs
-
getMergeType
public int getMergeType()Description copied from interface:IMergeContext
Return the type of merge that will be performed when using this context (eitherISynchronizationContext.TWO_WAY
orISynchronizationContext.THREE_WAY
). In most cases, this type which match that returned byISynchronizationContext.getType()
. However, for some THREE_WAY synchronizations, the merge type may be TWO_WAY which indicates that clients of the context should ignore local changes when performing merges. This capability is provided to support replace operations that support three-way preview but ignore local changes when replacing.- Specified by:
getMergeType
in interfaceIMergeContext
- Returns:
- the type of merge that will be performed when using this context.
-
getAdapter
Description copied from class:PlatformObject
Returns an object which is an instance of the given class associated with this object. Returnsnull
if no such object can be found.This implementation of the method declared by
IAdaptable
passes the request along to the platform's adapter manager; roughlyPlatform.getAdapterManager().getAdapter(this, adapter)
. Subclasses may override this method (however, if they do so, they should invoke the method on their superclass to ensure that the Platform's adapter manager is consulted).- Specified by:
getAdapter
in interfaceIAdaptable
- Overrides:
getAdapter
in classPlatformObject
- Type Parameters:
T
- the class type- Parameters:
adapter
- the class to adapt to- Returns:
- the adapted object or
null
- See Also:
-