in src/org/jetbrains/tfsIntegration/core/TFSCheckinEnvironment.java [144:285]
public List<VcsException> commit(@NotNull List<Change> changes,
@NotNull String commitMessage,
@NotNull CommitContext commitContext,
@NotNull Set<String> feedback) {
myVcs.getCheckinData().messageLabel = null;
final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
final List<FilePath> files = new ArrayList<>();
for (Change change : changes) {
FilePath path = null;
ContentRevision beforeRevision = change.getBeforeRevision();
ContentRevision afterRevision = change.getAfterRevision();
if (afterRevision != null) {
path = afterRevision.getFile();
}
else if (beforeRevision != null) {
path = beforeRevision.getFile();
}
if (path != null) {
files.add(path);
}
}
final List<VcsException> errors = new ArrayList<>();
try {
WorkstationHelper.processByWorkspaces(files, false, myVcs.getProject(), new WorkstationHelper.VoidProcessDelegate() {
@Override
public void executeRequest(final WorkspaceInfo workspace, final List<ItemPath> paths) throws TfsException {
try {
TFSProgressUtil.setProgressText(progressIndicator, TFSBundle.message("loading.pending.changes"));
// get pending changes for given items
Collection<PendingChange> pendingChanges = workspace.getServer().getVCS()
.queryPendingSetsByLocalPaths(workspace.getName(), workspace.getOwnerName(), paths, RecursionType.None, myVcs.getProject(),
TFSBundle.message("loading.pending.changes"));
if (pendingChanges.isEmpty()) {
return;
}
Collection<String> checkIn = new ArrayList<>();
// upload files
TFSProgressUtil.setProgressText(progressIndicator, TFSBundle.message("uploading.files"));
for (PendingChange pendingChange : pendingChanges) {
if (pendingChange.getType() == ItemType.File) {
ChangeTypeMask changeType = new ChangeTypeMask(pendingChange.getChg());
if (changeType.contains(ChangeType_type0.Edit) || changeType.contains(ChangeType_type0.Add)) {
TFSProgressUtil
.setProgressText2(progressIndicator, VersionControlPath.localPathFromTfsRepresentation(pendingChange.getLocal()));
workspace.getServer().getVCS()
.uploadItem(workspace, pendingChange, myVcs.getProject(), null);
}
}
checkIn.add(pendingChange.getItem());
}
TFSProgressUtil.setProgressText2(progressIndicator, "");
final WorkItemsCheckinParameters state = myVcs.getCheckinData().parameters.getWorkItems(workspace.getServer());
final Map<WorkItem, CheckinWorkItemAction> workItemActions =
state != null ? state.getWorkItemsActions() : Collections.emptyMap();
List<Pair<String, String>> checkinNotes =
new ArrayList<>(myVcs.getCheckinData().parameters.getCheckinNotes(workspace.getServer()).size());
for (CheckinParameters.CheckinNote checkinNote : myVcs.getCheckinData().parameters.getCheckinNotes(workspace.getServer())) {
checkinNotes.add(Pair.create(checkinNote.name, StringUtil.notNullize(checkinNote.value)));
}
TFSProgressUtil.setProgressText(progressIndicator, TFSBundle.message("checking.in"));
ResultWithFailures<CheckinResult> result = workspace.getServer().getVCS()
.checkIn(workspace.getName(), workspace.getOwnerName(), checkIn, commitMessage, workItemActions, checkinNotes,
myVcs.getCheckinData().parameters.getPolicyOverride(workspace.getServer()), myVcs.getProject(), null);
errors.addAll(TfsUtil.getVcsExceptions(result.getFailures()));
Collection<String> commitFailed = new ArrayList<>(result.getFailures().size());
for (Failure failure : result.getFailures()) {
TFSVcs.assertTrue(failure.getItem() != null);
commitFailed.add(failure.getItem());
}
Collection<FilePath> invalidateRoots = new ArrayList<>(pendingChanges.size());
Collection<FilePath> invalidateFiles = new ArrayList<>();
// set readonly status for files
Collection<VirtualFile> makeReadOnly = new ArrayList<>();
for (PendingChange pendingChange : pendingChanges) {
TFSVcs.assertTrue(pendingChange.getItem() != null);
if (commitFailed.contains(pendingChange.getItem())) {
continue;
}
ChangeTypeMask changeType = new ChangeTypeMask(pendingChange.getChg());
if (pendingChange.getType() == ItemType.File) {
if (changeType.contains(ChangeType_type0.Edit) ||
changeType.contains(ChangeType_type0.Add) ||
changeType.contains(ChangeType_type0.Rename)) {
VirtualFile file = VersionControlPath.getVirtualFile(pendingChange.getLocal());
if (file != null && file.isValid()) {
makeReadOnly.add(file);
}
}
}
// TODO don't add recursive invalidate
// TODO if Rename, invalidate old and new items?
final FilePath path = VersionControlPath.getFilePath(pendingChange.getLocal(), pendingChange.getType() == ItemType.Folder);
invalidateRoots.add(path);
if (changeType.contains(ChangeType_type0.Add) || changeType.contains(ChangeType_type0.Rename)) {
// [IDEADEV-27087] invalidate parent folders since they can be implicitly checked in with child checkin
final VirtualFile vcsRoot = ProjectLevelVcsManager.getInstance(myVcs.getProject()).getVcsRootFor(path);
if (vcsRoot != null) {
final FilePath vcsRootPath = TfsFileUtil.getFilePath(vcsRoot);
for (FilePath parent = path.getParentPath();
parent != null && parent.isUnder(vcsRootPath, false);
parent = parent.getParentPath()) {
invalidateFiles.add(parent);
}
}
}
}
TfsFileUtil.setReadOnly(makeReadOnly, true);
TFSProgressUtil.setProgressText(progressIndicator, TFSBundle.message("updating.work.items"));
if (commitFailed.isEmpty()) {
CheckinResult checkinResult = result.getResult().iterator().next();
workspace.getServer().getVCS()
.updateWorkItemsAfterCheckin(workspace.getOwnerName(), workItemActions, checkinResult.getCset(), myVcs.getProject(),
null);
}
TfsFileUtil.markDirty(myVcs.getProject(), invalidateRoots, invalidateFiles);
}
catch (IOException e) {
errors.add(new VcsException(e));
}
}
});
}
catch (TfsException e) {
errors.add(new VcsException(e));
}
myVcs.getCheckinData().parameters = null;
myVcs.fireRevisionChanged();
return errors;
}