25#include <wx/filename.h>
29#include <wx/datetime.h>
33#define HISTORY_LOCK_TRACE wxT( "KICAD_HISTORY_LOCK" )
51 wxLogTrace(
HISTORY_LOCK_TRACE,
"Attempting to acquire lock for project: %s (timeout: %d sec)",
75 wxLogTrace(
HISTORY_LOCK_TRACE,
"Successfully acquired all locks for project: %s", aProjectPath );
92 git_repository_free(
m_repo );
116 return wxString::Format( wxS(
"%s@%s" ),
120 return wxEmptyString;
129 wxLogNull suppressSysErrorPopups;
131 if( !wxFileName::Mkdir(
m_historyPath, 0777, wxPATH_MKDIR_FULL ) )
142 wxLogWarning(
"Detected stale lock file, removing it" );
150 m_fileLock = std::make_unique<LOCKFILE>( lockPath.GetFullPath(),
true );
155 _(
"History repository is locked by %s@%s" ),
179 const git_error* err = git_error_last();
181 _(
"Failed to open git repository: %s" ),
182 err ? wxString::FromUTF8( err->message ) : wxString(
"Unknown error" ) );
191 const git_error* err = git_error_last();
193 err ? wxString::FromUTF8( err->message ) : wxString(
"Unknown error" ) );
201 if( ignoreFile.FileExists() )
203 wxFFile f( ignoreFile.GetFullPath(), wxT(
"rb" ) );
206 if( f.IsOpened() && f.ReadAll( &content ) )
207 git_ignore_add_rule(
m_repo, content.utf8_str() );
219 m_lockError =
_(
"Cannot acquire index lock: repository not open" );
228 const git_error* err = git_error_last();
230 _(
"Failed to acquire git index lock (another operation in progress?): %s" ),
231 err ? wxString::FromUTF8( err->message ) : wxString(
"Unknown error" ) );
243 if( aStaleTimeoutSec <= 0 )
247 wxFileName lockPath( histPath, wxS(
".repo.lock" ) );
249 if( !lockPath.FileExists() )
253 if( !lockPath.GetTimes(
nullptr, &modTime,
nullptr ) )
256 wxDateTime now = wxDateTime::Now();
257 wxTimeSpan age = now - modTime;
260 (
int)age.GetSeconds().ToLong(), aStaleTimeoutSec );
262 return age.GetSeconds().ToLong() > aStaleTimeoutSec;
269 wxFileName lockPath( histPath, wxS(
".repo.lock" ) );
271 if( !lockPath.FileExists() )
275 wxFileName lockFilePath( histPath, wxS(
".repo" ) );
281 if( lockPath.FileExists() )
283 result = wxRemoveFile( lockPath.GetFullPath() );
287 wxLogError(
"Failed to remove stale lock: %s", lockPath.GetFullPath() );
290 if( lockFilePath.FileExists() )
292 bool lockFileResult = wxRemoveFile( lockFilePath.GetFullPath() );
294 wxLogTrace(
HISTORY_LOCK_TRACE,
"Removed stale lockfile: %s", lockFilePath.GetFullPath() );
313 git_repository_free(
m_repo );
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
wxString GetLockHolder() const
Get information about who currently holds the lock.
HISTORY_LOCK_MANAGER(const wxString &aProjectPath, int aStaleTimeoutSec=0)
Construct a lock manager and attempt to acquire locks.
void ReleaseRepository()
Release git repository and index handles early, but keep the file lock.
~HISTORY_LOCK_MANAGER()
Destructor releases all locks and closes git repository.
wxString GetLockError() const
Get error message describing why lock could not be acquired.
static bool BreakStaleLock(const wxString &aProjectPath)
Forcibly remove a stale lock file.
std::unique_ptr< LOCKFILE > m_fileLock
static bool IsLockStale(const wxString &aProjectPath, int aStaleTimeoutSec=0)
Check if a lock file exists and is stale (older than timeout).
bool IsLocked() const
Check if locks were successfully acquired.
virtual SETTINGS_MANAGER & GetSettingsManager() const
wxString GetLocalHistoryDirForPath(const wxString &aProjectPath) const
Resolve the local-history directory for a project given by its on-disk path.
int m_HistoryLockStaleTimeout
Stale lock timeout for local history repository locks, in seconds.
static const std::string LockFileExtension
static const std::string LockFilePrefix
static wxString historyPath(const wxString &aProjectPath)
#define HISTORY_LOCK_TRACE
PGM_BASE & Pgm()
The global program "get" accessor.
wxString result
Test unit parsing edge cases and error handling.