bool FPerforceCheckInWorker::Execute(FPerforceSourceControlCommand& InCommand) { FScopedPerforceConnection ScopedConnection(InCommand); if (!InCommand.IsCanceled() && ScopedConnection.IsValid()) { FPerforceConnection& Connection = ScopedConnection.GetConnection(); check(InCommand.Operation->GetName() == GetName()); TSharedRef<FCheckIn, ESPMode::ThreadSafe> Operation = StaticCastSharedRef<FCheckIn>(InCommand.Operation); int32 ChangeList = Connection.CreatePendingChangelist(Operation->GetDescription(), FOnIsCancelled::CreateRaw(&InCommand, &FPerforceSourceControlCommand::IsCanceled), InCommand.ErrorMessages); if (ChangeList > 0) { // Batch reopen into multiple commands, to avoid command line limits const int32 BatchedCount = 100; InCommand.bCommandSuccessful = true; for (int32 StartingIndex = 0; StartingIndex < InCommand.Files.Num() && InCommand.bCommandSuccessful; StartingIndex += BatchedCount) { FP4RecordSet Records; TArray< FString > ReopenParams; //Add changelist information to params ReopenParams.Insert(TEXT("-c"), 0); ReopenParams.Insert(FString::Printf(TEXT("%d"), ChangeList), 1); int32 NextIndex = FMath::Min(StartingIndex + BatchedCount, InCommand.Files.Num()); for (int32 FileIndex = StartingIndex; FileIndex < NextIndex; FileIndex++) { ReopenParams.Add(InCommand.Files[FileIndex]); } InCommand.bCommandSuccessful = Connection.RunCommand(TEXT("reopen"), ReopenParams, Records, InCommand.ErrorMessages, FOnIsCancelled::CreateRaw(&InCommand, &FPerforceSourceControlCommand::IsCanceled), InCommand.bConnectionDropped); } if (InCommand.bCommandSuccessful) { // Only submit if reopen was successful TArray<FString> SubmitParams; FP4RecordSet Records; SubmitParams.Insert(TEXT("-c"), 0); SubmitParams.Insert(FString::Printf(TEXT("%d"), ChangeList), 1); InCommand.bCommandSuccessful = Connection.RunCommand(TEXT("submit"), SubmitParams, Records, InCommand.ErrorMessages, FOnIsCancelled::CreateRaw(&InCommand, &FPerforceSourceControlCommand::IsCanceled), InCommand.bConnectionDropped); if (InCommand.ErrorMessages.Num() > 0) { InCommand.bCommandSuccessful = false; } if (InCommand.bCommandSuccessful) { // Remove any deleted files from status cache FPerforceSourceControlModule& PerforceSourceControl = FModuleManager::GetModuleChecked<FPerforceSourceControlModule>("PerforceSourceControl"); FPerforceSourceControlProvider& Provider = PerforceSourceControl.GetProvider(); TArray<TSharedRef<ISourceControlState, ESPMode::ThreadSafe>> States; Provider.GetState(InCommand.Files, States, EStateCacheUsage::Use); for (const auto& State : States) { if (State->IsDeleted()) { Provider.RemoveFileFromCache(State->GetFilename()); } } StaticCastSharedRef<FCheckIn>(InCommand.Operation)->SetSuccessMessage(ParseSubmitResults(Records)); for(auto Iter(InCommand.Files.CreateIterator()); Iter; Iter++) { OutResults.Add(*Iter, EPerforceState::ReadOnly); } } } } else { // Failed to create the changelist InCommand.bCommandSuccessful = false; } } return InCommand.bCommandSuccessful; }
bool FSubversionCheckInWorker::Execute(FSubversionSourceControlCommand& InCommand) { check(InCommand.Operation->GetName() == GetName()); TSharedRef<FCheckIn, ESPMode::ThreadSafe> Operation = StaticCastSharedRef<FCheckIn>(InCommand.Operation); { // make a temp file to place our message in FScopedTempFile DescriptionFile(Operation->GetDescription()); if(DescriptionFile.GetFilename().Len() > 0) { TArray<FString> Parameters; FString DescriptionFilename = DescriptionFile.GetFilename(); // We need to manually quote the filename because we're not passing the file argument via RunCommand's InFiles parameter SubversionSourceControlUtils::QuoteFilename(DescriptionFilename); Parameters.Add(FString(TEXT("--file ")) + DescriptionFilename); Parameters.Add(TEXT("--encoding utf-8")); // we need commit directories that are marked for add here if we are committing any child files that are also marked for add TArray<FString> FilesToCommit = InCommand.Files; AddDirectoriesToCommit(InCommand, FilesToCommit); // we need another temp file to add our file list to (as this must be an atomic operation we cant risk overflowing command-line limits) FString Targets; for(auto It(FilesToCommit.CreateConstIterator()); It; It++) { Targets += *It + LINE_TERMINATOR; } FScopedTempFile TargetsFile(Targets); if(TargetsFile.GetFilename().Len() > 0) { // we first need to release locks if we have any copy (branch) operations in our changes ReleaseAnyLocksForCopies(InCommand.Files, InCommand.WorkingCopyRoot, InCommand.RepositoryRoot, InCommand.UserName); FString TargetsFilename = TargetsFile.GetFilename(); // We need to manually quote the filename because we're not passing the file argument via RunCommand's InFiles parameter SubversionSourceControlUtils::QuoteFilename(TargetsFilename); Parameters.Add(FString(TEXT("--targets ")) + TargetsFilename); InCommand.bCommandSuccessful = SubversionSourceControlUtils::RunAtomicCommand(TEXT("commit"), TArray<FString>(), Parameters, InCommand.InfoMessages, InCommand.ErrorMessages, InCommand.UserName); if(InCommand.bCommandSuccessful) { // Remove any deleted files from status cache FSubversionSourceControlModule& SubversionSourceControl = FModuleManager::LoadModuleChecked<FSubversionSourceControlModule>("SubversionSourceControl"); FSubversionSourceControlProvider& Provider = SubversionSourceControl.GetProvider(); TArray<TSharedRef<ISourceControlState, ESPMode::ThreadSafe>> States; Provider.GetState(InCommand.Files, States, EStateCacheUsage::Use); for (const auto& State : States) { if (State->IsDeleted()) { Provider.RemoveFileFromCache(State->GetFilename()); } } StaticCastSharedRef<FCheckIn>(InCommand.Operation)->SetSuccessMessage(ParseCommitResults(InCommand.InfoMessages)); } } } } // now update the status of our files { TArray<FXmlFile> ResultsXml; TArray<FString> StatusParameters; StatusParameters.Add(TEXT("--verbose")); StatusParameters.Add(TEXT("--show-updates")); InCommand.bCommandSuccessful &= SubversionSourceControlUtils::RunCommand(TEXT("status"), InCommand.Files, StatusParameters, ResultsXml, InCommand.ErrorMessages, InCommand.UserName); SubversionSourceControlUtils::ParseStatusResults(ResultsXml, InCommand.ErrorMessages, InCommand.UserName, InCommand.WorkingCopyRoot, OutStates); } return InCommand.bCommandSuccessful; }