From acb79278ee6f32afa649b8afd4401149c50bc31a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sun, 21 Jan 2024 01:48:14 -0300 Subject: [PATCH] Added branch rename. Fixed warning. Simplified branches data fetching. --- include/eepp/core/string.hpp | 2 +- projects/macos/ee.config | 1 + src/eepp/system/process.cpp | 2 + src/tools/ecode/plugins/git/git.cpp | 73 ++++++++++------------- src/tools/ecode/plugins/git/git.hpp | 11 ++-- src/tools/ecode/plugins/git/gitplugin.cpp | 37 ++++++++++++ src/tools/ecode/plugins/git/gitplugin.hpp | 2 + 7 files changed, 77 insertions(+), 51 deletions(-) diff --git a/include/eepp/core/string.hpp b/include/eepp/core/string.hpp index a18832af1..bdeab4a63 100644 --- a/include/eepp/core/string.hpp +++ b/include/eepp/core/string.hpp @@ -362,7 +362,7 @@ class EE_API String { #ifdef __clang__ #pragma clang diagnostic pop #elif defined( __GNUC__ ) -#pragma diagnostic pop +#pragma GCC diagnostic pop #endif return result; } diff --git a/projects/macos/ee.config b/projects/macos/ee.config index d8218324f..041783d1f 100644 --- a/projects/macos/ee.config +++ b/projects/macos/ee.config @@ -13,3 +13,4 @@ #define DR_FLAC_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION #define ECODE_USE_BACKWARD +#define SUBPROCESS_USE_POSIX_SPAWN diff --git a/src/eepp/system/process.cpp b/src/eepp/system/process.cpp index c738e44f9..8e465fac7 100644 --- a/src/eepp/system/process.cpp +++ b/src/eepp/system/process.cpp @@ -10,6 +10,8 @@ #if EE_PLATFORM == EE_PLATFORM_MACOS || EE_PLATFORM == EE_PLATFORM_IOS #define SUBPROCESS_USE_POSIX_SPAWN +#elif defined( __GLIBC__ ) && ( __GLIBC__ > 2 || ( __GLIBC__ == 2 && __GLIBC_MINOR__ >= 29 ) ) +#define SUBPROCESS_USE_POSIX_SPAWN #endif #include #include diff --git a/src/tools/ecode/plugins/git/git.cpp b/src/tools/ecode/plugins/git/git.cpp index c574964b7..1ce10822c 100644 --- a/src/tools/ecode/plugins/git/git.cpp +++ b/src/tools/ecode/plugins/git/git.cpp @@ -188,7 +188,7 @@ Git::CheckoutResult Git::checkoutAndCreateLocalBranch( const std::string& remote Git::Result Git::add( const std::string& file, const std::string& projectDir ) { std::string buf; int retCode = git( String::format( "add --force -- \"%s\"", file ), projectDir, buf ); - Git::CheckoutResult res; + Git::Result res; res.returnCode = retCode; res.result = buf; return res; @@ -197,7 +197,7 @@ Git::Result Git::add( const std::string& file, const std::string& projectDir ) { Git::Result Git::restore( const std::string& file, const std::string& projectDir ) { std::string buf; int retCode = git( String::format( "restore \"%s\"", file ), projectDir, buf ); - Git::CheckoutResult res; + Git::Result res; res.returnCode = retCode; res.result = buf; return res; @@ -206,7 +206,17 @@ Git::Result Git::restore( const std::string& file, const std::string& projectDir Git::Result Git::reset( const std::string& file, const std::string& projectDir ) { std::string buf; int retCode = git( String::format( "reset -q HEAD -- \"%s\"", file ), projectDir, buf ); - Git::CheckoutResult res; + Git::Result res; + res.returnCode = retCode; + res.result = buf; + return res; +} + +Git::Result Git::renameBranch( const std::string& branch, const std::string& newName, + const std::string& projectDir ) { + std::string buf; + int retCode = git( String::format( "branch -M %s %s", branch, newName ), projectDir, buf ); + Git::Result res; res.returnCode = retCode; res.result = buf; return res; @@ -215,7 +225,7 @@ Git::Result Git::reset( const std::string& file, const std::string& projectDir ) Git::Result Git::deleteBranch( const std::string& branch, const std::string& projectDir ) { std::string buf; int retCode = git( String::format( "branch -D %s", branch ), projectDir, buf ); - Git::CheckoutResult res; + Git::Result res; res.returnCode = retCode; res.result = buf; return res; @@ -273,31 +283,30 @@ std::vector Git::getAllBranches( const std::string& projectDir ) { projectDir ); } -Git::Branch Git::parseLocalBranch( const std::string_view& raw, - const std::unordered_map& headOrigins, - const std::string& projectDir ) { +Git::Branch Git::parseLocalBranch( const std::string_view& raw, const std::string& projectDir ) { static constexpr size_t len = std::string_view{ "refs/heads/"sv }.size(); if ( len >= raw.size() ) return {}; - std::string name( std::string{ raw.substr( len ) } ); - auto found = headOrigins.find( name ); - std::string remote; + auto split = String::split( raw, '\t' ); + if ( split.size() != 2 ) + return {}; + std::string name( std::string{ split[0].substr( len ) } ); + std::string remote( std::string{ split[1] } ); int64_t ahead = 0; int64_t behind = 0; - if ( found != headOrigins.end() ) { - remote = found->second; - auto res = branchHistoryPosition( name, remote ); - if ( res.success() ) { - ahead = res.ahead; - behind = res.behind; - } + + auto res = branchHistoryPosition( name, remote ); + if ( res.success() ) { + ahead = res.ahead; + behind = res.behind; } + return Git::Branch{ std::move( name ), std::move( remote ), Git::RefType::Head, std::string{}, ahead, behind }; } -static Git::Branch parseRemoteBranch( const std::string_view& raw ) { +static Git::Branch parseRemoteBranch( std::string_view raw ) { static constexpr size_t len = std::string_view( "refs/remotes/"sv ).size(); size_t indexOfRemote = raw.find_first_of( '/', len ); if ( indexOfRemote != std::string::npos && len < raw.size() ) { @@ -309,7 +318,7 @@ static Git::Branch parseRemoteBranch( const std::string_view& raw ) { } std::vector Git::getAllBranchesAndTags( RefType ref, const std::string& projectDir ) { - std::string args( "for-each-ref --format '%(refname)' --sort=v:refname" ); + std::string args( "for-each-ref --format '%(refname) %(upstream:short)' --sort=v:refname" ); if ( ref & RefType::Head ) args.append( " refs/heads" ); if ( ref & RefType::Remote ) @@ -325,12 +334,10 @@ std::vector Git::getAllBranchesAndTags( RefType ref, const std::str branches.reserve( countLines( buf ) ); - auto headOrigins = getHeadOrigins( projectDir ); - readAllLines( buf, [&]( const std::string_view& line ) { - auto branch = String::trim( String::trim( line, '\n' ), '\'' ); + auto branch = String::trim( String::trim( line, '\'' ), '\t' ); if ( ( ref & Head ) && String::startsWith( branch, "refs/heads/" ) ) { - branches.emplace_back( parseLocalBranch( branch, headOrigins ) ); + branches.emplace_back( parseLocalBranch( branch, projectDir ) ); } else if ( ( ref & Remote ) && String::startsWith( branch, "refs/remotes/" ) ) { branches.emplace_back( parseRemoteBranch( branch ) ); } else if ( ( ref & Tag ) && String::startsWith( branch, "refs/tags/" ) ) { @@ -368,26 +375,6 @@ std::vector Git::getSubModules( const std::string& projectDir ) { return mSubModules; } -std::unordered_map Git::getHeadOrigins( const std::string& projectDir ) { - std::unordered_map ret; - std::string buf; - int retCode = git( "for-each-ref --format='%(refname:short) %(upstream:short)' refs/heads", - projectDir, buf ); - Result res; - res.returnCode = retCode; - if ( res.fail() ) - return ret; - - readAllLines( buf, [&ret]( const std::string_view& line ) { - auto split = String::split( String::trim( line, '\'' ), '\t' ); - if ( split.size() != 2 ) - return; - ret[std::string{ split[0] }] = std::string{ split[1] }; - } ); - - return ret; -} - bool Git::hasSubmodules( const std::string& projectDir ) { return ( !projectDir.empty() && FileSystem::fileExists( projectDir + ".gitmodules" ) ) || ( !mProjectPath.empty() && FileSystem::fileExists( mProjectPath + ".gitmodules" ) ); diff --git a/src/tools/ecode/plugins/git/git.hpp b/src/tools/ecode/plugins/git/git.hpp index edb41b9d4..562a4b20b 100644 --- a/src/tools/ecode/plugins/git/git.hpp +++ b/src/tools/ecode/plugins/git/git.hpp @@ -1,7 +1,6 @@ #include #include #include -#include #include namespace ecode { @@ -208,6 +207,9 @@ class Git { Result reset( const std::string& file, const std::string& projectDir = "" ); + Result renameBranch( const std::string& branch, const std::string& newName, + const std::string& projectDir = "" ); + Result deleteBranch( const std::string& branch, const std::string& projectDir = "" ); CountResult branchHistoryPosition( const std::string& localBranch, @@ -254,9 +256,6 @@ class Git { std::vector getSubModules( const std::string& projectDir = "" ); - std::unordered_map - getHeadOrigins( const std::string& projectDir = "" ); - protected: std::string mGitPath; std::string mProjectPath; @@ -269,9 +268,7 @@ class Git { std::string inSubModule( const std::string& file, const std::string& projectDir ); - Git::Branch parseLocalBranch( const std::string_view& raw, - const std::unordered_map& headOrigins, - const std::string& projectDir = "" ); + Git::Branch parseLocalBranch( const std::string_view& raw, const std::string& projectDir ); }; } // namespace ecode diff --git a/src/tools/ecode/plugins/git/gitplugin.cpp b/src/tools/ecode/plugins/git/gitplugin.cpp index 3e92f4eed..9f51bee13 100644 --- a/src/tools/ecode/plugins/git/gitplugin.cpp +++ b/src/tools/ecode/plugins/git/gitplugin.cpp @@ -888,6 +888,39 @@ void GitPlugin::checkout( Git::Branch branch ) { checkOutFn( false ); } +void GitPlugin::branchRename( Git::Branch branch ) { + if ( !mGit ) + return; + + UIMessageBox* msgBox = UIMessageBox::New( + UIMessageBox::INPUT, + String::format( + i18n( "git_rename_branch_ask", "Enter the new name for the branch: '%s'" ).toUtf8(), + branch.name ) ); + msgBox->on( Event::OnConfirm, [this, branch, msgBox]( const Event* ) { + std::string newName( msgBox->getTextInput()->getText().toUtf8() ); + if ( newName.empty() || branch.name == newName ) + return; + + mLoader->setVisible( true ); + msgBox->closeWindow(); + mThreadPool->run( [this, branch, newName] { + auto res = mGit->renameBranch( branch.name, newName ); + if ( res.fail() ) { + showMessage( LSPMessageType::Warning, res.result ); + return; + } + updateBranches(); + getUISceneNode()->runOnMainThread( [this] { mLoader->setVisible( false ); } ); + } ); + } ); + msgBox->setCloseShortcut( { KEY_ESCAPE, KEYMOD_NONE } ); + msgBox->setTitle( i18n( "git_rename_branch", "Rename Branch" ) ); + msgBox->center(); + msgBox->getTextInput()->setText( branch.name ); + msgBox->showWhenReady(); +} + void GitPlugin::branchDelete( Git::Branch branch ) { if ( !mGit ) return; @@ -962,6 +995,7 @@ void GitPlugin::discard( const std::string& file ) { updateStatus( true ); } ); } ); + msgBox->setCloseShortcut( { KEY_ESCAPE, KEYMOD_NONE } ); msgBox->setTitle( i18n( "git_confirm", "Confirm" ) ); msgBox->center(); msgBox->showWhenReady(); @@ -1199,6 +1233,7 @@ void GitPlugin::openBranchMenu( const Git::Branch& branch ) { if ( mGitBranch != branch.name ) { addFn( "git-checkout", "Check Out..." ); if ( branch.type == Git::RefType::Head ) { + addFn( "git-branch-rename", "Rename" ); addFn( "git-branch-delete", "Delete" ); } } else { @@ -1216,6 +1251,8 @@ void GitPlugin::openBranchMenu( const Git::Branch& branch ) { pull(); } else if ( id == "git-branch-delete" ) { branchDelete( branch ); + } else if ( id == "git-branch-rename" ) { + branchRename( branch ); } } ); diff --git a/src/tools/ecode/plugins/git/gitplugin.hpp b/src/tools/ecode/plugins/git/gitplugin.hpp index 40ca32f9e..958aa3346 100644 --- a/src/tools/ecode/plugins/git/gitplugin.hpp +++ b/src/tools/ecode/plugins/git/gitplugin.hpp @@ -122,6 +122,8 @@ class GitPlugin : public PluginBase { void checkout( Git::Branch branch ); + void branchRename( Git::Branch branch ); + void branchDelete( Git::Branch branch ); void pull();