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);
}