Java源码示例:com.intellij.openapi.vcs.changes.VcsDirtyScope
示例1
public void clearScope(final List<VcsDirtyScope> scopes) {
// VcsDirtyScope.belongsTo() performs some checks under read action. So deadlock could occur if some thread tries to modify
// ContentRevisionCache (i.e. call getOrLoadCurrentAsBytes()) under write action while other thread invokes clearScope(). To prevent
// such deadlocks we also perform locking "myLock" (and other logic) under read action.
// TODO: "myCurrentRevisionsCache" logic should be refactored to be more clear and possibly to avoid creating such wrapping read actions
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
synchronized (myLock) {
++myCounter;
for (final VcsDirtyScope scope : scopes) {
final Set<CurrentKey> toRemove = new HashSet<>();
myCurrentRevisionsCache.iterateKeys(new Consumer<CurrentKey>() {
@Override
public void consume(CurrentKey currentKey) {
if (scope.belongsTo(currentKey.getPath())) {
toRemove.add(currentKey);
}
}
});
for (CurrentKey key : toRemove) {
myCurrentRevisionsCache.remove(key);
}
}
}
}
});
}
示例2
public void getChanges(@NotNull final VcsDirtyScope dirtyScope,
@NotNull final ChangelistBuilder builder,
@NotNull final ProgressIndicator progress,
@NotNull final ChangeListManagerGate addGate) {
Project project = myVcs.getProject();
if (project.isDisposed()) {
return;
}
progress.setText("Processing changes");
// process only roots, filter out child items since requests are recursive anyway
RootsCollection.FilePathRootsCollection roots = new RootsCollection.FilePathRootsCollection();
roots.addAll(dirtyScope.getRecursivelyDirtyDirectories());
final ChangeListManager changeListManager = ChangeListManager.getInstance(project);
for (FilePath dirtyFile : dirtyScope.getDirtyFiles()) {
// workaround for IDEADEV-31511 and IDEADEV-31721
if (dirtyFile.getVirtualFile() == null || !changeListManager.isIgnoredFile(dirtyFile.getVirtualFile())) {
roots.add(dirtyFile);
}
}
if (roots.isEmpty()) {
return;
}
final List<String> pathsToProcess = TFVCUtil.filterValidTFVCPaths(project, roots);
if (pathsToProcess.isEmpty()) {
return;
}
List<PendingChange> changes;
try {
ServerContext serverContext = myVcs.getServerContext(true);
changes = TfvcClient.getInstance(project).getStatusForFiles(serverContext, pathsToProcess);
} catch (final Throwable t) {
logger.error("Failed to get changes from command line. roots=" + StringUtils.join(pathsToProcess, ", "), t);
changes = Collections.emptyList();
}
// for each change, find out the status of the changes and then add to the list
final ChangelistBuilderStatusVisitor changelistBuilderStatusVisitor = new ChangelistBuilderStatusVisitor(project, builder);
for (final PendingChange change : changes) {
StatusProvider.visitByStatus(changelistBuilderStatusVisitor, change);
}
}
示例3
/**
* Ensure that, when offline, one file change is correctly reported.
*
* @param tmp temp folder
*/
@ExtendWith(TemporaryFolderExtension.class)
@Test
void offlineOneChange(TemporaryFolder tmp)
throws IOException, VcsException {
List<Throwable> errors = new ArrayList<>();
vcs.idea.useInlineThreading(errors);
VcsDirtyScope dirtyScope = mock(VcsDirtyScope.class);
MockChangeListManagerGate addGate = new MockChangeListManagerGate(vcs.getMockChangelistManager());
MockChangelistBuilder changeBuilder = new MockChangelistBuilder(addGate, vcs.vcs);
ProgressIndicator progressIndicator = DummyProgressIndicator.nullSafe(null);
when(dirtyScope.getVcs()).thenReturn(vcs.vcs);
when(dirtyScope.wasEveryThingDirty()).thenReturn(true);
// Setup offline mode
ClientConfigRoot root = vcs.addClientConfigRoot(tmp, "client");
assertNotNull(root.getClientRootDir());
vcs.goOffline(root);
assertFalse(vcs.registry.isOnline(root.getClientConfig().getClientServerRef()));
// Ensure the default changelist is in our cache.
// Should the test be run with no default changelist? That implies that the server has never been
// synchronized, so I'm guessing no.
P4ChangelistId defaultChangeId = vcs.addDefaultChangelist(root);
// Add the pending add action.
VirtualFile addedVirtualFile = root.getClientRootDir().createChildData(this, "added.txt");
FilePath addedFile = VcsUtil.getFilePath(addedVirtualFile);
// Inline threading, so no need to block.
vcs.server.getCommandRunner()
.perform(root.getClientConfig(), new AddEditAction(addedFile, null, defaultChangeId, (String) null));
assertSize(0, errors);
assertSize(1, vcs.cacheComponent.getState().pendingActions);
assertEquals(ADD_EDIT_FILE, vcs.cacheComponent.getState().pendingActions.get(0).clientActionCmd);
// Run the test.
P4ChangeProvider provider = new P4ChangeProvider(vcs.vcs, vcs.getMockProject());
provider.getChanges(dirtyScope, changeBuilder, progressIndicator, addGate);
// Validations
assertContainsExactly(changeBuilder.addedChangedFiles.values(),
addedFile);
assertSize(1, changeBuilder.addedChanges.keySet());
Map.Entry<String, Change> change =
changeBuilder.addedChanges.entrySet().iterator().next();
assertEquals(LocalChangeList.DEFAULT_NAME, change.getKey());
assertNull(change.getValue().getBeforeRevision());
assertNotNull(change.getValue().getAfterRevision());
assertEquals(addedFile, change.getValue().getAfterRevision().getFile());
assertSize(0, changeBuilder.ignored);
assertSize(0, changeBuilder.locallyDeleted);
assertSize(0, changeBuilder.lockedFolder);
assertSize(0, changeBuilder.modifiedWithoutCheckout);
assertSize(0, changeBuilder.removedChanges);
assertSize(0, changeBuilder.unversioned);
assertSize(0, addGate.removed);
assertSize(0, addGate.added);
}
示例4
/**
* Ensure that, when offline, adding a new IDE change list does not cause the plugin to create a
* new Perforce changelist, or some other unexpected side effect.
*
* @param tmp temp folder
*/
@ExtendWith(TemporaryFolderExtension.class)
@Test
void offlineNewIdeChangelist(TemporaryFolder tmp)
throws IOException, VcsException {
List<Throwable> errors = new ArrayList<>();
vcs.idea.useInlineThreading(errors);
VcsDirtyScope dirtyScope = mock(VcsDirtyScope.class);
MockChangeListManagerGate addGate = new MockChangeListManagerGate(vcs.getMockChangelistManager());
MockChangelistBuilder changeBuilder = new MockChangelistBuilder(addGate, vcs.vcs);
ProgressIndicator progressIndicator = DummyProgressIndicator.nullSafe(null);
when(dirtyScope.getVcs()).thenReturn(vcs.vcs);
when(dirtyScope.wasEveryThingDirty()).thenReturn(true);
// Setup offline mode
ClientConfigRoot root = vcs.addClientConfigRoot(tmp, "client");
assertNotNull(root.getClientRootDir());
vcs.goOffline(root);
assertFalse(vcs.registry.isOnline(root.getClientConfig().getClientServerRef()));
// Ensure the default changelist is in our cache.
// Should the test be run with no default changelist? That implies that the server has never been
// synchronized, so I'm guessing no.
P4ChangelistId defaultChangeId = vcs.addDefaultChangelist(root);
// Add the IDE changelist.
vcs.addIdeChangelist("Test change", "A test change", false);
// Run the test.
P4ChangeProvider provider = new P4ChangeProvider(vcs.vcs, vcs.getMockProject());
provider.getChanges(dirtyScope, changeBuilder, progressIndicator, addGate);
// Validations
assertSize(0, changeBuilder.addedChangedFiles.values());
assertSize(0, changeBuilder.addedChanges.keySet());
assertSize(0, changeBuilder.ignored);
assertSize(0, changeBuilder.locallyDeleted);
assertSize(0, changeBuilder.lockedFolder);
assertSize(0, changeBuilder.modifiedWithoutCheckout);
assertSize(0, changeBuilder.removedChanges);
assertSize(0, changeBuilder.unversioned);
assertSize(0, addGate.removed);
assertSize(0, addGate.added);
}
示例5
/**
* Verify that a file open for add in a non-default changelist is not moved.
*/
@ExtendWith(TemporaryFolderExtension.class)
@Test
void offlineFileInNonDefaultChangelist(TemporaryFolder tmp)
throws IOException {
List<Throwable> errors = new ArrayList<>();
vcs.idea.useInlineThreading(errors);
VcsDirtyScope dirtyScope = mock(VcsDirtyScope.class);
MockChangeListManagerGate addGate = new MockChangeListManagerGate(vcs.getMockChangelistManager());
MockChangelistBuilder changeBuilder = new MockChangelistBuilder(addGate, vcs.vcs);
ProgressIndicator progressIndicator = DummyProgressIndicator.nullSafe(null);
when(dirtyScope.getVcs()).thenReturn(vcs.vcs);
when(dirtyScope.wasEveryThingDirty()).thenReturn(true);
// Setup offline mode
ClientConfigRoot root = vcs.addClientConfigRoot(tmp, "client");
assertNotNull(root.getClientRootDir());
vcs.goOffline(root);
assertFalse(vcs.registry.isOnline(root.getClientConfig().getClientServerRef()));
// Ensure the default changelist is in our cache.
// Should the test be run with no default changelist? That implies that the server has never been
// synchronized, so I'm guessing no.
P4ChangelistId defaultChangeId = vcs.addDefaultChangelist(root);
// Add the IDE changelist.
MockLocalChangeList newIdeChange = vcs.addIdeChangelist("Test change", "A test", false);
// Link the IDE changelist to a Perforce change.
P4ChangelistId newP4Change = vcs.addNewChangelist(root, 1, "Test change");
vcs.linkP4ChangelistToIdeChangelist(root, newP4Change, newIdeChange);
// Add the pending add action.
VirtualFile addedVirtualFile = root.getClientRootDir().createChildData(this, "added.txt");
FilePath addedFile = VcsUtil.getFilePath(addedVirtualFile);
// Inline threading, so no need to block.
vcs.server.getCommandRunner()
.perform(root.getClientConfig(), new AddEditAction(addedFile, null, newP4Change, "UTF-8"));
assertSize(0, errors);
assertSize(1, vcs.cacheComponent.getState().pendingActions);
assertEquals(ADD_EDIT_FILE, vcs.cacheComponent.getState().pendingActions.get(0).clientActionCmd);
}
示例6
/**
* The bug this tests: A file is open for edit in the default changelist, and there is another changelist
* linked to an IDE changelist. Then the user moves the file to another changelist, and then refreshes the
* change view. The bug was where the refresh would loop because the provider would not correctly adjust
* the file change.
*
* @param tmp
* @param errors
* @throws InterruptedException
* @throws IOException
*/
@ExtendWith({ TemporaryFolderExtension.class, ErrorCollectorExtension.class })
@Test
void refreshAfterFileMoved(TemporaryFolder tmp, Errors errors)
throws InterruptedException, IOException, VcsException {
vcs.idea.useInlineThreading(errors.get());
final VcsDirtyScope dirtyScope = mock(VcsDirtyScope.class);
final MockChangeListManagerGate addGate = new MockChangeListManagerGate(vcs.getMockChangelistManager());
final MockChangelistBuilder changeBuilder = new MockChangelistBuilder(addGate, vcs.vcs);
final ProgressIndicator progressIndicator = DummyProgressIndicator.nullSafe(null);
when(dirtyScope.getVcs()).thenReturn(vcs.vcs);
when(dirtyScope.wasEveryThingDirty()).thenReturn(true);
// Simulate online mode
ClientConfigRoot root = vcs.addClientConfigRoot(tmp, "client");
assertNotNull(root.getClientRootDir());
vcs.goOnline(root);
// The IDE should have a default changelist.
MockLocalChangeList ideDefaultCl = vcs.addIdeChangelist(LocalChangeList.DEFAULT_NAME, null, true);
// Setup the server: 2 changelists, 1 file in default changelist.
final File openedFile = tmp.newFile("test.txt");
final IFileSpec openedFileSpec = FileSpecBuildUtil.forFiles(openedFile).get(0);
/* Default changelist is implicit, so we don't need to explicitly construct it.
final Changelist defCl = new Changelist(
0, root.getClientConfig().getClientname(),
root.getClientConfig().getServerConfig().getUsername(),
ChangelistStatus.PENDING, new Date(), "<default>", false, null
);
defCl.setFileSpecs(Collections.singletonList(openedFileSpec));
*/
final Changelist secondCl = new Changelist(
2, root.getClientConfig().getClientname(),
root.getClientConfig().getServerConfig().getUsername(),
ChangelistStatus.PENDING, new Date(), "new cl", false, null
);
secondCl.setFileSpecs(Collections.emptyList());
vcs.connectionManager
.withErrors(errors)
.withServerSetup((config, base) -> {
//defCl.setServerImpl(base);
secondCl.setServerImpl(base);
when(base.getChangelists(eq(null), any())).thenReturn(Arrays.asList(
//defCl,
secondCl
));
//when(base.getChangelist(eq(0), any())).thenReturn(defCl);
when(base.getChangelist(eq(2), any())).thenReturn(secondCl);
// Get the files opened in the default list.
ExtendedFileSpec spec = new ExtendedFileSpec("//depot/test.txt");
spec.setAction(FileAction.ADD);
when(base.getExtendedFiles(
argThat(t -> t.size() == 1 && t.get(0)
.getOriginalPathString().equals("//" + root.getClientConfig().getClientname() + "/...")),
argThat(t -> t.getAffectedByChangelist() == 0))).thenReturn(Collections.singletonList(
spec
));
return base;
})
.withClientSetup((config, base) -> {
when(base.openedFiles(any(), any())).then((args) -> {
return args.getArguments()[0];
});
return base;
});
// Update the cache.
P4ChangeProvider provider = new P4ChangeProvider(vcs.vcs, vcs.getMockProject());
provider.getChanges(dirtyScope, changeBuilder, progressIndicator, addGate);
// Initial validations that refresh worked.
assertSize(1, changeBuilder.addedChangedFiles.values());
assertSize(1, changeBuilder.addedChanges.keySet());
assertSize(0, changeBuilder.ignored);
assertSize(0, changeBuilder.locallyDeleted);
assertSize(0, changeBuilder.lockedFolder);
assertSize(0, changeBuilder.modifiedWithoutCheckout);
assertSize(0, changeBuilder.removedChanges);
assertSize(0, changeBuilder.unversioned);
assertSize(0, addGate.removed);
assertSize(1, addGate.added);
}