Skip to content

Commit

Permalink
fix #80
Browse files Browse the repository at this point in the history
  • Loading branch information
mastercoms committed Apr 26, 2023
1 parent 8550cd7 commit 95eb46e
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 43 deletions.
12 changes: 12 additions & 0 deletions Source/GitSourceControl/Private/GitSourceControlModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,18 @@ class FGitSourceControlModule : public IModuleInterface
return FModuleManager::Get().LoadModuleChecked< FGitSourceControlModule >("GitSourceControl");
}

static inline FGitSourceControlModule* GetThreadSafe()
{
IModuleInterface* ModulePtr = FModuleManager::Get().GetModule("GitSourceControl");
if (!ModulePtr)
{
// Main thread should never have this unloaded.
check(!IsInGameThread());
return nullptr;
}
return static_cast<FGitSourceControlModule*>(ModulePtr);
}

/** Set list of error messages that occurred after last git command */
static void SetLastErrors(const TArray<FText>& InErrors);

Expand Down
8 changes: 6 additions & 2 deletions Source/GitSourceControl/Private/GitSourceControlRevision.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ bool FGitSourceControlRevision::Get( FString& InOutFilename, EConcurrency::Type
bool FGitSourceControlRevision::Get( FString& InOutFilename ) const
{
#endif
const FGitSourceControlModule& GitSourceControl = FGitSourceControlModule::Get();
const FGitSourceControlProvider& Provider = GitSourceControl.GetProvider();
const FGitSourceControlModule* GitSourceControl = FGitSourceControlModule::GetThreadSafe();
if (!GitSourceControl)
{
return false;
}
const FGitSourceControlProvider& Provider = GitSourceControl->GetProvider();
const FString PathToGitBinary = Provider.GetGitBinaryPath();
FString PathToRepositoryRoot = Provider.GetPathToRepositoryRoot();
// the repo root can be customised if in a plugin that has it's own repo
Expand Down
6 changes: 3 additions & 3 deletions Source/GitSourceControl/Private/GitSourceControlRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ uint32 FGitSourceControlRunner::Run()
// Flag that we're running the task already
bRefreshSpawned = true;
const auto ExecuteResult = Async(EAsyncExecution::TaskGraphMainThread, [=] {
FGitSourceControlModule* GitSourceControl = FGitSourceControlModule::GetThreadSafe();
// Module not loaded, bail. Usually happens when editor is shutting down, and this prevents a crash from bad timing.
if (!FModuleManager::Get().GetModule("GitSourceControl"))
if (!GitSourceControl)
{
return ECommandResult::Failed;
}
FGitSourceControlModule& GitSourceControl = FGitSourceControlModule::Get();
FGitSourceControlProvider& Provider = GitSourceControl.GetProvider();
FGitSourceControlProvider& Provider = GitSourceControl->GetProvider();
TSharedRef<FGitFetch, ESPMode::ThreadSafe> RefreshOperation = ISourceControlOperation::Create<FGitFetch>();
RefreshOperation->bUpdateStatus = true;
#if ENGINE_MAJOR_VERSION >= 5
Expand Down
111 changes: 73 additions & 38 deletions Source/GitSourceControl/Private/GitSourceControlUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,12 @@ void GetUserConfig(const FString& InPathToGitBinary, const FString& InRepository

bool GetBranchName(const FString& InPathToGitBinary, const FString& InRepositoryRoot, FString& OutBranchName)
{
const FGitSourceControlProvider& Provider = FGitSourceControlModule::Get().GetProvider();
const FGitSourceControlModule* GitSourceControl = FGitSourceControlModule::GetThreadSafe();
if (!GitSourceControl)
{
return false;
}
const FGitSourceControlProvider& Provider = GitSourceControl->GetProvider();
if (!Provider.GetBranchName().IsEmpty())
{
OutBranchName = Provider.GetBranchName();
Expand Down Expand Up @@ -597,7 +602,12 @@ bool GetBranchName(const FString& InPathToGitBinary, const FString& InRepository

bool GetRemoteBranchName(const FString& InPathToGitBinary, const FString& InRepositoryRoot, FString& OutBranchName)
{
const FGitSourceControlProvider& Provider = FGitSourceControlModule::Get().GetProvider();
const FGitSourceControlModule* GitSourceControl = FGitSourceControlModule::GetThreadSafe();
if (!GitSourceControl)
{
return false;
}
const FGitSourceControlProvider& Provider = GitSourceControl->GetProvider();
if (!Provider.GetRemoteBranchName().IsEmpty())
{
OutBranchName = Provider.GetRemoteBranchName();
Expand Down Expand Up @@ -813,6 +823,7 @@ class FGitLfsLocksParser
// Filename ID (or we expect it to be the username, but it's empty, or is the ID, we have to assume it's the current user)
if (Informations.Num() == 2 || Informations[1].IsEmpty() || Informations[1].StartsWith(TEXT("ID:")))
{
// TODO: thread safety
LockUser = FGitSourceControlModule::Get().GetProvider().GetLockUser();
}
// Filename Username ID
Expand Down Expand Up @@ -1123,8 +1134,13 @@ R Content/Textures/T_Perlin_Noise_M.uasset -> Content/Textures/T_Perlin_Noise_M
static void ParseFileStatusResult(const FString& InPathToGitBinary, const FString& InRepositoryRoot, const bool InUsingLfsLocking, const TSet<FString>& InFiles,
const TMap<FString, FString>& InResults, TMap<FString, FGitSourceControlState>& OutStates)
{
FGitSourceControlModule& GitSourceControl = FGitSourceControlModule::Get();
const FString& LfsUserName = GitSourceControl.GetProvider().GetLockUser();
FGitSourceControlModule* GitSourceControl = FGitSourceControlModule::GetThreadSafe();
if (!GitSourceControl)
{
return;
}
FGitSourceControlProvider& Provider = GitSourceControl->GetProvider();
const FString& LfsUserName = Provider.GetLockUser();

TMap<FString, FString> LockedFiles;
TMap<FString, FString> Results = InResults;
Expand Down Expand Up @@ -1280,7 +1296,13 @@ void CheckRemote(const FString& InPathToGitBinary, const FString& InRepositoryRo
// We can obtain a list of files that were modified between our remote branches and HEAD. Assumes that fetch has been run to get accurate info.

// Gather valid remote branches
const TArray<FString> StatusBranches = FGitSourceControlModule::Get().GetProvider().GetStatusBranchNames();
FGitSourceControlModule* GitSourceControl = FGitSourceControlModule::GetThreadSafe();
if (!GitSourceControl)
{
return;
}
FGitSourceControlProvider& Provider = GitSourceControl->GetProvider();
const TArray<FString> StatusBranches = Provider.GetStatusBranchNames();

TSet<FString> BranchesToDiff{ StatusBranches };

Expand Down Expand Up @@ -1339,7 +1361,7 @@ void CheckRemote(const FString& InPathToGitBinary, const FString& InRepositoryRo
// Check if there's newer binaries pending on this branch
if (bCurrentBranch && (NewerFileName == TEXT(".checksum") || NewerFileName.StartsWith("Binaries")))
{
FGitSourceControlModule::Get().GetProvider().bPendingRestart = true;
Provider.bPendingRestart = true;
}
continue;
}
Expand Down Expand Up @@ -1384,7 +1406,7 @@ bool GetAllLocks(const FString& InRepositoryRoot, const FString& GitBinaryFallba
const FTimespan CacheTimeElapsed = CurrentTime - FGitLockedFilesCache::LastUpdated;
bCacheExpired = CacheTimeElapsed > CacheLimit;
}
bool bResult;
bool bResult = false;
if (bCacheExpired)
{
// Our cache expired, or they asked us to expire cache. Query locks directly from the remote server.
Expand All @@ -1411,42 +1433,51 @@ bool GetAllLocks(const FString& InRepositoryRoot, const FString& GitBinaryFallba
TArray<FString> Params;
Params.Add(TEXT("--cached"));

const FString& LockUser = FGitSourceControlModule::Get().GetProvider().GetLockUser();

Results.Reset();
bResult = RunLFSCommand(TEXT("locks"), InRepositoryRoot, GitBinaryFallback, Params, FGitSourceControlModule::GetEmptyStringArray(), Results, OutErrorMessages);
for (const FString& Result : Results)
FGitSourceControlModule* GitSourceControl = FGitSourceControlModule::GetThreadSafe();
if (!GitSourceControl)
{
FGitLfsLocksParser LockFile(InRepositoryRoot, Result);
#if UE_BUILD_DEBUG && GIT_DEBUG_STATUS
UE_LOG(LogSourceControl, Log, TEXT("LockedFile(%s, %s)"), *LockFile.LocalFilename, *LockFile.LockUser);
#endif
// Only update remote locks
if (LockFile.LockUser != LockUser)
bResult = false;
}
else
{
FGitSourceControlProvider& Provider = GitSourceControl->GetProvider();
const FString& LockUser = Provider.GetLockUser();

Results.Reset();
bResult = RunLFSCommand(TEXT("locks"), InRepositoryRoot, GitBinaryFallback, Params, FGitSourceControlModule::GetEmptyStringArray(), Results, OutErrorMessages);
for (const FString& Result : Results)
{
OutLocks.Add(MoveTemp(LockFile.LocalFilename), MoveTemp(LockFile.LockUser));
FGitLfsLocksParser LockFile(InRepositoryRoot, Result);
#if UE_BUILD_DEBUG && GIT_DEBUG_STATUS
UE_LOG(LogSourceControl, Log, TEXT("LockedFile(%s, %s)"), *LockFile.LocalFilename, *LockFile.LockUser);
#endif
// Only update remote locks
if (LockFile.LockUser != LockUser)
{
OutLocks.Add(MoveTemp(LockFile.LocalFilename), MoveTemp(LockFile.LockUser));
}
}
}
// Get the latest local state of our own locks
Params.Reset(1);
Params.Add(TEXT("--local"));
// Get the latest local state of our own locks
Params.Reset(1);
Params.Add(TEXT("--local"));

Results.Reset();
bResult &= RunLFSCommand(TEXT("locks"), InRepositoryRoot, GitBinaryFallback, Params, FGitSourceControlModule::GetEmptyStringArray(), Results, OutErrorMessages);
for (const FString& Result : Results)
{
FGitLfsLocksParser LockFile(InRepositoryRoot, Result);
#if UE_BUILD_DEBUG && GIT_DEBUG_STATUS
UE_LOG(LogSourceControl, Log, TEXT("LockedFile(%s, %s)"), *LockFile.LocalFilename, *LockFile.LockUser);
#endif
// Only update local locks
if (LockFile.LockUser == LockUser)
Results.Reset();
bResult &= RunLFSCommand(TEXT("locks"), InRepositoryRoot, GitBinaryFallback, Params, FGitSourceControlModule::GetEmptyStringArray(), Results, OutErrorMessages);
for (const FString& Result : Results)
{
OutLocks.Add(MoveTemp(LockFile.LocalFilename), MoveTemp(LockFile.LockUser));
FGitLfsLocksParser LockFile(InRepositoryRoot, Result);
#if UE_BUILD_DEBUG && GIT_DEBUG_STATUS
UE_LOG(LogSourceControl, Log, TEXT("LockedFile(%s, %s)"), *LockFile.LocalFilename, *LockFile.LockUser);
#endif
// Only update local locks
if (LockFile.LockUser == LockUser)
{
OutLocks.Add(MoveTemp(LockFile.LocalFilename), MoveTemp(LockFile.LockUser));
}
}
}
}
else
if (!bResult)
{
// We can use our internally tracked local lock cache (an effective combination of --cached and --local)
OutLocks = FGitLockedFilesCache::LockedFiles;
Expand Down Expand Up @@ -1917,9 +1948,13 @@ bool UpdateCachedStates(const TMap<const FString, FGitState>& InResults)
{
return false;
}

FGitSourceControlModule& GitSourceControl = FGitSourceControlModule::Get();
FGitSourceControlProvider& Provider = GitSourceControl.GetProvider();

FGitSourceControlModule* GitSourceControl = FGitSourceControlModule::GetThreadSafe();
if (!GitSourceControl)
{
return false;
}
FGitSourceControlProvider& Provider = GitSourceControl->GetProvider();
const bool bUsingGitLfsLocking = Provider.UsesCheckout();

// TODO without LFS : Workaround a bug with the Source Control Module not updating file state after a simple "Save" with no "Checkout" (when not using File Lock)
Expand Down

0 comments on commit 95eb46e

Please sign in to comment.