From f0d7e4644f92ae5d499af697c17b628a49423fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 27 Jan 2024 13:00:07 -0300 Subject: [PATCH] GitPlugin: Allow to ammend last commit. Improved thread safety. Reduced some calls. --- bin/assets/fonts/codicon.ttf | Bin 73452 -> 79504 bytes bin/assets/ui/breeze.css | 4 + include/eepp/system/condition.hpp | 8 +- src/thirdparty/subprocess/subprocess.h | 2 +- src/tools/ecode/iconmanager.cpp | 4 + .../plugins/formatter/formatterplugin.cpp | 2 +- src/tools/ecode/plugins/git/git.cpp | 16 ++- src/tools/ecode/plugins/git/git.hpp | 2 +- .../ecode/plugins/git/gitbranchmodel.cpp | 10 ++ .../ecode/plugins/git/gitbranchmodel.hpp | 2 + src/tools/ecode/plugins/git/gitplugin.cpp | 118 +++++++++++++----- src/tools/ecode/plugins/git/gitplugin.hpp | 12 +- src/tools/ecode/plugins/pluginmanager.cpp | 3 + src/tools/ecode/plugins/pluginmanager.hpp | 1 + 14 files changed, 137 insertions(+), 47 deletions(-) diff --git a/bin/assets/fonts/codicon.ttf b/bin/assets/fonts/codicon.ttf index 3d1dc3d86b8887461892729305b22a54bd642c0a..4894dfa316d4a98f4804f67b7840b00e0e20051a 100644 GIT binary patch delta 13329 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 delta 7818 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 F{|nX!S-JoK diff --git a/bin/assets/ui/breeze.css b/bin/assets/ui/breeze.css index 9b863c0ac..ae874668f 100644 --- a/bin/assets/ui/breeze.css +++ b/bin/assets/ui/breeze.css @@ -190,6 +190,10 @@ selectbutton:disabled { border-color: var(--disabled-border); } +checkbox:disabled { + color: var(--disabled-color); +} + PushButton::icon, SelectButton::icon, TableView::cell::icon, diff --git a/include/eepp/system/condition.hpp b/include/eepp/system/condition.hpp index 552fe72f5..261a50da4 100644 --- a/include/eepp/system/condition.hpp +++ b/include/eepp/system/condition.hpp @@ -20,7 +20,7 @@ class EE_API Condition : NonCopyable { }; /** Initializes a Condition object and sets its internal value to value. - * Thus using WaitAndLock(value, ...) will immediately return. + * Thus using waitAndLock(value, ...) will immediately return. */ Condition( int value = 0 ); @@ -66,7 +66,7 @@ class EE_API Condition : NonCopyable { void unlock(); - /** Performs an assignement followed by a Signal() call. + /** Performs an assignement followed by a signal() call. * The internal Condition value is updated to value() and the Condition is * signaled. Note that the Condition must be unlocked in order * to be updated, otherwise it'll block until the Condition @@ -92,13 +92,13 @@ class EE_API Condition : NonCopyable { void signal(); /** Signals the Condition and disables blocking calls, - * thus WaitAndLock() does no more wait whatever + * thus waitAndLock() does no more wait whatever * the awaitedValue is and waiting calls are unlocked, returning false. */ void invalidate(); /** Restores the blocking capabilities of the Condition, - * possibly previously disabled with Invalidate() + * possibly previously disabled with invalidate() */ void restore(); diff --git a/src/thirdparty/subprocess/subprocess.h b/src/thirdparty/subprocess/subprocess.h index 90138ddcc..497bf040e 100644 --- a/src/thirdparty/subprocess/subprocess.h +++ b/src/thirdparty/subprocess/subprocess.h @@ -1071,7 +1071,7 @@ int subprocess_join(struct subprocess_s *const process, return 0; #else - int status; + int status = 0; if (process->stdin_file) { fclose(process->stdin_file); diff --git a/src/tools/ecode/iconmanager.cpp b/src/tools/ecode/iconmanager.cpp index 2ec6df77b..c3f013cc9 100644 --- a/src/tools/ecode/iconmanager.cpp +++ b/src/tools/ecode/iconmanager.cpp @@ -207,6 +207,10 @@ void IconManager::init( UISceneNode* sceneNode, FontTrueType* iconFont, FontTrue { "repo-pull", 0xeb40 }, { "repo-push", 0xeb41 }, { "repo-forked", 0xea63 }, + { "repo-fetch", 0xec1d }, + { "git-fetch", 0xf101 }, + { "git-commit", 0xeafc }, + { "remove", 0xeb3b }, { "tag", 0xea66 } }; for ( const auto& icon : codIcons ) diff --git a/src/tools/ecode/plugins/formatter/formatterplugin.cpp b/src/tools/ecode/plugins/formatter/formatterplugin.cpp index 781ec8557..8fa147303 100644 --- a/src/tools/ecode/plugins/formatter/formatterplugin.cpp +++ b/src/tools/ecode/plugins/formatter/formatterplugin.cpp @@ -53,7 +53,7 @@ FormatterPlugin::~FormatterPlugin() { mWorkerCondition.wait( lock, [this]() { return mWorkersCount <= 0; } ); } - for ( auto editor : mEditors ) { + for ( auto& editor : mEditors ) { for ( auto& kb : mKeyBindings ) { editor.first->getKeyBindings().removeCommandKeybind( kb.first ); if ( editor.first->hasDocument() ) diff --git a/src/tools/ecode/plugins/git/git.cpp b/src/tools/ecode/plugins/git/git.cpp index f5698238a..aa6a3ac04 100644 --- a/src/tools/ecode/plugins/git/git.cpp +++ b/src/tools/ecode/plugins/git/git.cpp @@ -1,4 +1,5 @@ #include "git.hpp" +#include #include #include #include @@ -58,6 +59,7 @@ Git::Git( const std::string& projectDir, const std::string& gitPath ) : mGitPath } int Git::git( const std::string& args, const std::string& projectDir, std::string& buf ) const { + Clock clock; buf.clear(); Process p; p.create( mGitPath, args, @@ -65,9 +67,10 @@ int Git::git( const std::string& args, const std::string& projectDir, std::strin Process::Options::InheritEnvironment, { { "LC_ALL", "en_US.UTF-8" } }, projectDir.empty() ? mProjectPath : projectDir ); p.readAllStdOut( buf ); - int retCode; + int retCode = 0; p.join( &retCode ); - Log::info( "GitPlugin run: %s %s", mGitPath, args ); + Log::info( "GitPlugin cmd in %s (%d): %s %s", clock.getElapsedTime().toString(), retCode, + mGitPath, args ); return retCode; } @@ -230,7 +233,8 @@ Git::Result Git::deleteBranch( const std::string& branch, const std::string& pro return gitSimple( String::format( "branch -D %s", branch ), projectDir ); } -Git::Result Git::commit( const std::string& commitMsg, const std::string& projectDir ) { +Git::Result Git::commit( const std::string& commitMsg, bool ammend, + const std::string& projectDir ) { auto tmpPath = Sys::getTempPath() + ".ecode-git-commit-" + String::randString( 16 ); if ( !FileSystem::fileWrite( tmpPath, commitMsg ) ) { Git::Result res; @@ -239,9 +243,9 @@ Git::Result Git::commit( const std::string& commitMsg, const std::string& projec return res; } std::string buf; - int retCode = - git( String::format( "commit --cleanup=whitespace --allow-empty --file=%s", tmpPath ), - projectDir, buf ); + int retCode = git( String::format( "commit %s --cleanup=whitespace --allow-empty --file=%s", + ammend ? "--ammend" : "", tmpPath ), + projectDir, buf ); FileSystem::fileRemove( tmpPath ); Git::Result res; res.returnCode = retCode; diff --git a/src/tools/ecode/plugins/git/git.hpp b/src/tools/ecode/plugins/git/git.hpp index 63f7358dd..10d0e6e12 100644 --- a/src/tools/ecode/plugins/git/git.hpp +++ b/src/tools/ecode/plugins/git/git.hpp @@ -228,7 +228,7 @@ class Git { Result deleteBranch( const std::string& branch, const std::string& projectDir = "" ); - Result commit( const std::string& commitMsg, const std::string& projectDir = "" ); + Result commit( const std::string& commitMsg, bool ammend, const std::string& projectDir = "" ); Result fetch( const std::string& projectDir = "" ); diff --git a/src/tools/ecode/plugins/git/gitbranchmodel.cpp b/src/tools/ecode/plugins/git/gitbranchmodel.cpp index 79c3f647f..8d57f5cf4 100644 --- a/src/tools/ecode/plugins/git/gitbranchmodel.cpp +++ b/src/tools/ecode/plugins/git/gitbranchmodel.cpp @@ -133,4 +133,14 @@ Git::Branch GitBranchModel::branch( const ModelIndex& index ) const { return *static_cast( index.internalData() ); } +Git::Branch GitBranchModel::branch( const std::string& name ) const { + for ( const auto& type : mBranches ) { + for ( const auto& branch : type.data ) { + if ( branch.name == name ) + return branch; + } + } + return {}; +} + } // namespace ecode diff --git a/src/tools/ecode/plugins/git/gitbranchmodel.hpp b/src/tools/ecode/plugins/git/gitbranchmodel.hpp index 26dbbbec3..328a24a2b 100644 --- a/src/tools/ecode/plugins/git/gitbranchmodel.hpp +++ b/src/tools/ecode/plugins/git/gitbranchmodel.hpp @@ -55,6 +55,8 @@ class GitBranchModel : public Model { Git::Branch branch( const ModelIndex& index ) const; + Git::Branch branch( const std::string& name ) const; + protected: std::vector mBranches; GitPlugin* mPlugin{ nullptr }; diff --git a/src/tools/ecode/plugins/git/gitplugin.cpp b/src/tools/ecode/plugins/git/gitplugin.cpp index 26008ca8c..2e5627cc2 100644 --- a/src/tools/ecode/plugins/git/gitplugin.cpp +++ b/src/tools/ecode/plugins/git/gitplugin.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,7 @@ std::string GitPlugin::statusTypeToString( Git::GitStatusType type ) { } std::vector GitPlugin::repos() { + Lock l( mReposMutex ); std::vector ret; for ( const auto& repo : mRepos ) ret.push_back( repo.first ); @@ -296,13 +298,7 @@ void GitPlugin::updateStatus( bool force ) { if ( !mGit || mGit->getGitFolder().empty() ) return; - decltype( mGitBranches ) prevBranch; - { - auto branches = mGit->branches( repos() ); - Lock l( mGitBranchMutex ); - prevBranch = mGitBranches; - mGitBranches = std::move( branches ); - } + auto prevBranch = updateReposBranches(); Git::Status prevGitStatus; { Lock l( mGitStatusMutex ); @@ -629,16 +625,48 @@ void GitPlugin::branchCreate() { msgBox->showWhenReady(); } -void GitPlugin::commit() { +void GitPlugin::commit( const std::string& repoPath ) { UIMessageBox* msgBox = UIMessageBox::New( UIMessageBox::TEXT_EDIT, i18n( "git_commit_message", "Commit Message:" ) ); - msgBox->on( Event::OnConfirm, [this, msgBox]( const Event* ) { + + UICheckBox* chkBox = UICheckBox::New(); + chkBox->setLayoutMargin( Rectf( 0, 8, 0, 0 ) ) + ->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::WrapContent ) + ->setLayoutGravity( UI_HALIGN_LEFT | UI_VALIGN_CENTER ) + ->setClipType( ClipType::None ) + ->setParent( msgBox->getLayoutCont()->getFirstChild() ) + ->setId( "git-ammend" ); + chkBox->setText( i18n( "git_ammend", "Ammend last commit" ) ); + chkBox->toPosition( 2 ); + + if ( !repoPath.empty() ) { + auto branchName = mGitBranches[repoPath]; + if ( !branchName.empty() ) { + if ( repoPath != repoSelected() || mBranchesTree->getModel() == nullptr ) { + + auto branch = mGit->getAllBranchesAndTags( Git::RefType::All, + "refs/heads/" + branchName, repoPath ); + if ( !branch.empty() ) + chkBox->setEnabled( branch.front().ahead > 0 ); + + } else { + auto model = static_cast( mBranchesTree->getModel() ); + auto branch = model->branch( branchName ); + if ( !branch.name.empty() ) + chkBox->setEnabled( branch.ahead > 0 ); + } + } + } + + msgBox->on( Event::OnConfirm, [this, msgBox, chkBox]( const Event* ) { std::string msg( msgBox->getTextEdit()->getText().toUtf8() ); if ( msg.empty() ) return; msgBox->closeWindow(); - runAsync( [this, msg]() { return mGit->commit( msg ); }, true, true ); + runAsync( [this, msg, chkBox]() { return mGit->commit( msg, chkBox->isChecked() ); }, true, + true ); } ); + msgBox->setCloseShortcut( { KEY_ESCAPE, KEYMOD_NONE } ); msgBox->setTitle( i18n( "git_commit", "Commit" ) ); msgBox->center(); @@ -798,6 +826,32 @@ bool GitPlugin::onKeyDown( UICodeEditor* editor, const KeyEvent& event ) { return false; } +std::unordered_map GitPlugin::updateReposBranches() { + mGit->getSubModules(); + + bool reposEmpty = false; + { + Lock l( mReposMutex ); + reposEmpty = mRepos.empty(); + } + if ( reposEmpty ) + updateRepos(); + + Lock l( mGitBranchMutex ); + + decltype( mGitBranches ) prevBranch; + if ( mGitBranches.empty() || mLastBranchesUpdate.getElapsedTime() > Seconds( 1 ) ) { + prevBranch = mGitBranches; + mGitBranches = mGit->branches( repos() ); + mLastBranchesUpdate.restart(); + } else { + Lock l( mGitBranchMutex ); + prevBranch = mGitBranches; + } + + return prevBranch; +} + void GitPlugin::updateBranches( bool force ) { if ( !mGit || !mGitFound || ( mRunningUpdateBranches && !force ) ) return; @@ -808,15 +862,7 @@ void GitPlugin::updateBranches( bool force ) { if ( !mGit || mGit->getGitFolder().empty() ) return; - mGit->getSubModules(); - - decltype( mGitBranches ) prevBranch; - { - Lock l( mGitBranchMutex ); - prevBranch = mGitBranches; - mGitBranches = mGit->branches( repos() ); - } - + auto prevBranch = updateReposBranches(); auto branches = mGit->getAllBranchesAndTags( Git::RefType::All, {}, repoSelected() ); auto hash = GitBranchModel::hashBranches( branches ); auto model = GitBranchModel::asModel( std::move( branches ), hash, this ); @@ -833,12 +879,7 @@ void GitPlugin::updateBranches( bool force ) { [this]( auto ) { mRunningUpdateBranches--; } ); } -void GitPlugin::updateBranchesUI( std::shared_ptr model ) { - buildSidePanelTab(); - mBranchesTree->setModel( model ); - mBranchesTree->setColumnsVisible( { GitBranchModel::Name } ); - mBranchesTree->expandAll(); - +void GitPlugin::updateRepos() { if ( !mGit ) return; @@ -853,10 +894,19 @@ void GitPlugin::updateBranchesUI( std::shared_ptr model ) { repos.insert( { std::move( subModulePath ), FileSystem::fileNameFromPath( subModule ) } ); } + Lock l( mReposMutex ); if ( repos == mRepos ) return; mRepos = std::move( repos ); +} + +void GitPlugin::updateBranchesUI( std::shared_ptr model ) { + buildSidePanelTab(); + mBranchesTree->setModel( model ); + mBranchesTree->setColumnsVisible( { GitBranchModel::Name } ); + mBranchesTree->expandAll(); + updateRepos(); std::vector items; for ( const auto& repo : mRepos ) items.push_back( repo.second ); @@ -1020,11 +1070,15 @@ void GitPlugin::buildSidePanelTab() { if ( status->type == Git::GitStatusType::Staged || status->type == Git::GitStatusType::Untracked || status->type == Git::GitStatusType::Changed ) { + std::string repoPath; + if ( !status->files.empty() ) + repoPath = mGit->repoPath( status->files.front().file ); + UIPopUpMenu* menu = UIPopUpMenu::New(); menu->setId( "git_status_type_menu" ); if ( status->type == Git::GitStatusType::Staged ) { - addMenuItem( menu, "git-commit", "Commit" ); + addMenuItem( menu, "git-commit", "Commit", "git-commit" ); addMenuItem( menu, "git-unstage-all", "Unstage All" ); } @@ -1033,13 +1087,14 @@ void GitPlugin::buildSidePanelTab() { status->type == Git::GitStatusType::Changed ) addMenuItem( menu, "git-stage-all", "Stage All" ); - menu->on( Event::OnItemClicked, [this, model]( const Event* event ) { + menu->on( Event::OnItemClicked, [this, model, + repoPath]( const Event* event ) { if ( !mGit ) return; UIMenuItem* item = event->getNode()->asType(); std::string id( item->getId() ); if ( id == "git-commit" ) { - commit(); + commit( repoPath ); } else if ( id == "git-stage-all" ) { stage( model->getFiles( mGit->repoName( "" ), (Uint32)Git::GitStatusType::Untracked | @@ -1081,10 +1136,10 @@ void GitPlugin::openBranchMenu( const Git::Branch& branch ) { UIPopUpMenu* menu = UIPopUpMenu::New(); menu->setId( "git_branch_menu" ); - addMenuItem( menu, "git-fetch", "Fetch" ); + addMenuItem( menu, "git-fetch", "Fetch", "repo-fetch" ); if ( gitBranch() != branch.name ) { - addMenuItem( menu, "git-checkout", "Check Out..." ); + addMenuItem( menu, "git-checkout", "Check Out...", "git-fetch" ); } if ( branch.type == Git::RefType::Head ) { @@ -1095,7 +1150,7 @@ void GitPlugin::openBranchMenu( const Git::Branch& branch ) { if ( branch.behind ) addMenuItem( menu, "git-fast-forward-merge", "Fast Forward Merge" ); menu->addSeparator(); - addMenuItem( menu, "git-branch-delete", "Delete" ); + addMenuItem( menu, "git-branch-delete", "Delete", "remove" ); } addMenuItem( menu, "git-create-branch", "Create Branch", "repo-forked", { KEY_F7 } ); @@ -1176,6 +1231,7 @@ void GitPlugin::runAsync( std::function fn, bool _updateStatus, b } if ( _updateBranches ) updateBranches(); + if ( _updateStatus ) updateStatus( true ); } ); diff --git a/src/tools/ecode/plugins/git/gitplugin.hpp b/src/tools/ecode/plugins/git/gitplugin.hpp index 1077cccbc..78a06488c 100644 --- a/src/tools/ecode/plugins/git/gitplugin.hpp +++ b/src/tools/ecode/plugins/git/gitplugin.hpp @@ -69,6 +69,10 @@ class GitPlugin : public PluginBase { std::vector repos(); + std::unordered_map updateReposBranches(); + + void updateRepos(); + protected: std::unique_ptr mGit; std::unordered_map mGitBranches; @@ -103,11 +107,13 @@ class GitPlugin : public PluginBase { UIWidget* mGitContentView{ nullptr }; UIWidget* mGitNoContentView{ nullptr }; UILoader* mLoader{ nullptr }; - std::atomic mRunningUpdateBranches{ false }; - std::atomic mRunningUpdateStatus{ false }; + std::atomic mRunningUpdateBranches{ 0 }; + std::atomic mRunningUpdateStatus{ 0 }; + Clock mLastBranchesUpdate; Mutex mGitBranchMutex; Mutex mGitStatusMutex; Mutex mRepoMutex; + Mutex mReposMutex; struct CustomTokenizer { SyntaxDefinition def; @@ -152,7 +158,7 @@ class GitPlugin : public PluginBase { void branchCreate(); - void commit(); + void commit( const std::string& repoPath = "" ); void stage( const std::vector& files ); diff --git a/src/tools/ecode/plugins/pluginmanager.cpp b/src/tools/ecode/plugins/pluginmanager.cpp index f7b9a809c..8cb0e775d 100644 --- a/src/tools/ecode/plugins/pluginmanager.cpp +++ b/src/tools/ecode/plugins/pluginmanager.cpp @@ -274,10 +274,12 @@ void PluginManager::setFileSystemListener( FileSystemListener* listener ) { } void PluginManager::subscribeFileSystemListener( Plugin* plugin ) { + Lock l( mPluginsFSSubsMutex ); mPluginsFSSubs.insert( plugin ); } void PluginManager::unsubscribeFileSystemListener( Plugin* plugin ) { + Lock l( mPluginsFSSubsMutex ); mPluginsFSSubs.erase( plugin ); } @@ -287,6 +289,7 @@ void PluginManager::subscribeFileSystemListener() { mFileSystemListenerCb = mFileSystemListener->addListener( [this]( const FileEvent& ev, const FileInfo& file ) { + Lock l( mPluginsFSSubsMutex ); for ( Plugin* plugin : mPluginsFSSubs ) plugin->onFileSystemEvent( ev, file ); } ); diff --git a/src/tools/ecode/plugins/pluginmanager.hpp b/src/tools/ecode/plugins/pluginmanager.hpp index 49b7a3c30..faa362914 100644 --- a/src/tools/ecode/plugins/pluginmanager.hpp +++ b/src/tools/ecode/plugins/pluginmanager.hpp @@ -357,6 +357,7 @@ class PluginManager { UICodeEditorSplitter* mSplitter{ nullptr }; FileSystemListener* mFileSystemListener{ nullptr }; Mutex mSubscribedPluginsMutex; + Mutex mPluginsFSSubsMutex; SubscribedPlugins mSubscribedPlugins; OnLoadFileCb mLoadFileFn; Uint64 mFileSystemListenerCb{ 0 };