in plugin/src/com/microsoft/alm/plugin/idea/tfvc/core/tfs/operations/ScheduleForDeletion.java [57:185]
public static Collection<VcsException> execute(final Project project, final List<FilePath> files) {
// choose roots
// find if changes need reverted and revert them
// schedule roots for deletion using their original names
final Collection<VcsException> errors = new ArrayList<>();
final List<String> filePaths = new ArrayList<>(files.size());
for (final FilePath filePath : files) {
filePaths.add(filePath.getPath());
}
try {
final List<PendingChange> pendingChanges = new ArrayList<>();
final List<String> revert = new ArrayList<>();
final Set<String> scheduleForDeletion = new HashSet<>();
final ServerContext context = TFSVcs.getInstance(project).getServerContext(true);
TfvcClient client = TfvcClient.getInstance();
for (final String path : filePaths) {
List<PendingChange> fileChanges = client.getStatusForFiles(project, context, ImmutableList.of(path));
// deleting a file that has no changes
if (fileChanges.isEmpty()) {
scheduleForDeletion.add(path);
} else {
pendingChanges.addAll(fileChanges);
}
}
for (final PendingChange pendingChange : pendingChanges) {
StatusProvider.visitByStatus(new StatusProvider.StatusAdapter() {
public void unversioned(final @NotNull FilePath localPath, final boolean localItemExists,
final @NotNull ServerStatus serverStatus) {
// if an unversioned delete, IDE has already deleted the file and now TFVC has to delete it
if (pendingChange.getChangeTypes().contains(ServerStatusType.DELETE)) {
logger.info("ScheduleForDeletion: unversioned deleted file " + localPath.getPath());
scheduleForDeletion.add(StringUtils.isNotEmpty(pendingChange.getSourceItem()) ? pendingChange.getSourceItem() : pendingChange.getLocalItem());
} else {
// do nothing because file isn't recognized
logger.info("ScheduleForDeletion: do nothing for unversioned file " + localPath.getPath());
}
}
public void checkedOutForEdit(final @NotNull FilePath localPath, final boolean localItemExists,
final @NotNull ServerStatus serverStatus) {
logger.info("ScheduleForDeletion: checkedOutForEdit file " + localPath.getPath());
revert.add(pendingChange.getLocalItem());
scheduleForDeletion.add(pendingChange.getLocalItem());
}
public void scheduledForAddition(final @NotNull FilePath localPath, final boolean localItemExists,
final @NotNull ServerStatus serverStatus) {
logger.info("ScheduleForDeletion: scheduledForAddition file " + localPath.getPath());
revert.add(pendingChange.getLocalItem());
}
public void scheduledForDeletion(final @NotNull FilePath localPath, final boolean localItemExists,
final @NotNull ServerStatus serverStatus) {
logger.warn("ScheduleForDeletion: " + localPath + " already is deleted");
}
public void renamed(final @NotNull FilePath localPath, final boolean localItemExists,
final @NotNull ServerStatus serverStatus) {
logger.info("ScheduleForDeletion: renamed file " + localPath.getPath());
// revert local path but delete the source path since that is the original path before the rename
revert.add(pendingChange.getLocalItem());
scheduleForDeletion.add(pendingChange.getSourceItem());
}
public void renamedCheckedOut(final @NotNull FilePath localPath, final boolean localItemExists,
final @NotNull ServerStatus serverStatus) {
logger.info("ScheduleForDeletion: renamedCheckedOut file " + localPath.getPath());
// revert local path but delete the source path since that is the original path before the rename
revert.add(pendingChange.getLocalItem());
scheduleForDeletion.add(pendingChange.getSourceItem());
}
public void undeleted(final @NotNull FilePath localPath, final boolean localItemExists,
final @NotNull ServerStatus serverStatus) {
logger.info("ScheduleForDeletion: undeleted file " + localPath.getPath());
revert.add(pendingChange.getLocalItem());
}
}, pendingChange);
}
if (!revert.isEmpty()) {
List<TfsPath> pathsForUndo = revert.stream().map(TfsLocalPath::new).collect(Collectors.toList());
client.undoLocalChanges(project, context, pathsForUndo);
}
final List<String> confirmedDeletedFiles = new ArrayList<>();
if (!scheduleForDeletion.isEmpty()) {
// a workspace is needed since some paths are server paths, all changes will have the same workspace so
// just get it from the first change (list isn't empty since deletes were found)
// if no pending changes exist a workspace isn't needed b/c a local path is being used
final String workspace;
if (!pendingChanges.isEmpty()) {
workspace = pendingChanges.get(0).getWorkspace();
} else {
workspace = StringUtils.EMPTY;
}
TfvcDeleteResult deleteResult = CommandUtils.deleteFiles(
context,
new ArrayList<>(scheduleForDeletion),
workspace,
false);
deleteResult.throwIfErrorMessagesAreNotEmpty();
deleteResult.throwIfNotFoundPathsAreNotEmpty();
List<String> deletedPaths = deleteResult.getDeletedPaths().stream()
.map(Path::toString)
.collect(Collectors.toList());
confirmedDeletedFiles.addAll(deletedPaths);
}
for (final FilePath expectedDeletedFile : files) {
if (confirmedDeletedFiles.contains(expectedDeletedFile.getPath())) {
TfsFileUtil.markFileDirty(project, expectedDeletedFile);
}
}
} catch (Throwable t) {
logger.warn("executeDelete experienced a failure while looking for altered files to delete", t);
errors.add(TFSVcs.convertToVcsException(t));
}
return errors;
}