bool FPerforceCopyWorker::Execute(class FPerforceSourceControlCommand& InCommand) { FScopedPerforceConnection ScopedConnection(InCommand); if (!InCommand.IsCanceled() && ScopedConnection.IsValid()) { FPerforceConnection& Connection = ScopedConnection.GetConnection(); check(InCommand.Operation->GetName() == GetName()); TSharedRef<FCopy, ESPMode::ThreadSafe> Operation = StaticCastSharedRef<FCopy>(InCommand.Operation); FString DestinationPath = FPaths::ConvertRelativePathToFull(Operation->GetDestination()); TArray<FString> Parameters; Parameters.Append(InCommand.Files); Parameters.Add(DestinationPath); FP4RecordSet Records; InCommand.bCommandSuccessful = Connection.RunCommand(TEXT("integrate"), Parameters, Records, InCommand.ErrorMessages, FOnIsCancelled::CreateRaw(&InCommand, &FPerforceSourceControlCommand::IsCanceled), InCommand.bConnectionDropped); // We now need to do a p4 resolve. // This is because when we copy a file in the Editor, we first make the copy on disk before attempting to branch. This causes a conflict in P4's eyes. // We must do this to prevent the asset registry from picking up what it thinks is a newly-added file (which would be created by the p4 integrate command) // and then the package system getting very confused about where to save the now-duplicated assets. if(InCommand.bCommandSuccessful) { TArray<FString> ResolveParameters; ResolveParameters.Add(TEXT("-ay")); // 'accept yours' ResolveParameters.Add(DestinationPath); InCommand.bCommandSuccessful = Connection.RunCommand(TEXT("resolve"), ResolveParameters, Records, InCommand.ErrorMessages, FOnIsCancelled::CreateRaw(&InCommand, &FPerforceSourceControlCommand::IsCanceled), InCommand.bConnectionDropped); } } return InCommand.bCommandSuccessful; }
bool FSubversionCopyWorker::Execute(FSubversionSourceControlCommand& InCommand) { check(InCommand.Operation->GetName() == GetName()); TSharedRef<FCopy, ESPMode::ThreadSafe> Operation = StaticCastSharedRef<FCopy>(InCommand.Operation); FString Destination = FPaths::ConvertRelativePathToFull(Operation->GetDestination()); // perform svn revert if the dest file already exists in the working copy (this is usually the case // as files that are copied in the editor are already marked for add when the package is created // in the new location) { TArray<FString> Files; Files.Add(Destination); InCommand.bCommandSuccessful = SubversionSourceControlUtils::RunCommand(TEXT("revert"), Files, TArray<FString>(), InCommand.InfoMessages, InCommand.ErrorMessages, InCommand.UserName); } // Now we need to move the file out of directory, copy then restore over the top, as SVN wont allow us // to 'svn copy' over an existing file, even if it is not already added to the working copy. // This will be OK as far as the asset registry/directory watcher goes as it will just see the file being modified several times const FString TempFileName = FPaths::CreateTempFilename(*FPaths::GameLogDir(), TEXT("SVN-CopyTemp"), TEXT(".uasset")); const bool bReplace = true; const bool bEvenIfReadOnly = true; if (InCommand.bCommandSuccessful) { InCommand.bCommandSuccessful = IFileManager::Get().Move(*TempFileName, *Destination, bReplace, bEvenIfReadOnly); } // copy from source files to destination parameter if(InCommand.bCommandSuccessful) { TArray<FString> Files; Files.Append(InCommand.Files); Files.Add(Destination); TArray<FString> Parameters; // Add nonexistent/non-versioned parent directories too Parameters.Add(TEXT("--parents")); InCommand.bCommandSuccessful = SubversionSourceControlUtils::RunCommand(TEXT("copy"), Files, Parameters, InCommand.InfoMessages, InCommand.ErrorMessages, InCommand.UserName); } // now move the file back if (InCommand.bCommandSuccessful) { InCommand.bCommandSuccessful = IFileManager::Get().Move(*Destination, *TempFileName, bReplace, bEvenIfReadOnly); } // now update the status of our files { TArray<FXmlFile> ResultsXml; TArray<FString> StatusParameters; StatusParameters.Add(TEXT("--verbose")); StatusParameters.Add(TEXT("--show-updates")); // Get status of both source and destination files TArray<FString> StatusFiles; StatusFiles.Append(InCommand.Files); StatusFiles.Add(Destination); InCommand.bCommandSuccessful &= SubversionSourceControlUtils::RunCommand(TEXT("status"), StatusFiles, StatusParameters, ResultsXml, InCommand.ErrorMessages, InCommand.UserName); SubversionSourceControlUtils::ParseStatusResults(ResultsXml, InCommand.ErrorMessages, InCommand.UserName, InCommand.WorkingCopyRoot, OutStates); } return InCommand.bCommandSuccessful; }