Files
UnrealEngine/Engine/Source/Developer/SourceControl/Private/SourceControlOperations.cpp
2025-05-18 13:04:45 +08:00

97 lines
3.3 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "SourceControlOperations.h"
#include "Containers/StringView.h"
#include "HAL/FileManager.h"
#include "ISourceControlModule.h"
#include "Misc/PathViews.h"
#include "Misc/Paths.h"
bool FUpdateStatus::IsDirectoryPath(const FString& Path) const
{
// Problem:
// We need to be able to work out if a path if a directory or not as some source
// control implementations will need to append wildcards to the path if it is
// a directory in order for it to function correctly.
//
// Strictly speaking the only way we can tell the difference between a file path
// and a directory path is to check with the file system.
// However some source control implementations let us reference files on the server
// and do not require us to have them on the users machine. This means checking with
// the file system does not give an accurate result and can end up being very
// slow if the file system interprets the path as a UNC path and tries to resolve it.
//
// Ideally we would let the caller clearly mark if the path is for a file or a
// directory but this would require a large overhaul of the source control API.
// We cannot change the existing behavior as it is very likely that 3rd party code is
// relying on it.
//
// Solution:
// As a 'temporary' solution, the caller can set bSetRequireDirPathEndWithSeparator
// to true. When it is true we will assume that all directory paths end with a
// separator. Although we tend to not terminate directory paths with a separator in the
// engine, this will allow us an opt in to the new behavior until more substantial API
// changes can be made.
if (bSetRequireDirPathEndWithSeparator)
{
return Path.EndsWith(TEXT("/")) || Path.EndsWith(TEXT("\\"));
}
else
{
return IFileManager::Get().DirectoryExists(*Path);
}
}
PRAGMA_DISABLE_DEPRECATION_WARNINGS
FDownloadFile::FDownloadFile(FStringView InTargetDirectory, EVerbosity InVerbosity)
: FDownloadFile(InTargetDirectory)
{
if (InVerbosity == EVerbosity::None)
{
SetEnableErrorLogging(false);
}
}
PRAGMA_ENABLE_DEPRECATION_WARNINGS
FDownloadFile::FDownloadFile(FStringView InTargetDirectory)
: TargetDirectory(InTargetDirectory)
{
FPaths::NormalizeDirectoryName(TargetDirectory);
// Due to the asynchronous nature of the source control api, it might be some time before
// the TargetDirectory is actually used. So we do a validation pass on it now to try and
// give errors close to the point that they were created. The caller is still free to try
// and use the FDownloadFile but with an invalid path it probably won't work.
FText Reason;
if (!FPaths::ValidatePath(TargetDirectory, &Reason))
{
UE_LOG(LogSourceControl, Error, TEXT("Path '%s' passed to FDownloadFile is invalid due to: %s"),
*TargetDirectory, *Reason.ToString());
}
}
FSharedBuffer FDownloadFile::GetFileData(const FStringView& Filename)
{
const uint32 Hash = GetTypeHash(Filename);
FSharedBuffer* Buffer = FileDataMap.FindByHash(Hash, Filename);
if (Buffer != nullptr)
{
return *Buffer;
}
else
{
return FSharedBuffer();
}
}
FCreateWorkspace::FCreateWorkspace(FStringView InWorkspaceName, FStringView InWorkspaceRoot)
: WorkspaceName(InWorkspaceName)
{
TStringBuilder<512> AbsoluteWorkspaceName;
FPathViews::ToAbsolutePath(InWorkspaceRoot, AbsoluteWorkspaceName);
WorkspaceRoot = AbsoluteWorkspaceName.ToString();
}