From 676dd4ceec4dc3d3e0c921c93147561f03915683 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand <seth@kipro-pcb.com> Date: Sat, 15 Mar 2025 13:05:06 -0700 Subject: [PATCH] Fix inheritance for git_common Avoids repo type pointer issues when casting from void --- common/dialogs/git/dialog_git_repository.cpp | 4 +- common/dialogs/git/panel_git_repos.cpp | 6 +- common/git/git_clone_handler.cpp | 16 +- common/git/git_clone_handler.h | 9 +- common/git/git_pull_handler.cpp | 4 +- common/git/git_pull_handler.h | 4 +- common/git/git_push_handler.cpp | 4 +- common/git/git_push_handler.h | 2 +- common/git/git_repo_mixin.h | 15 +- common/git/kicad_git_common.cpp | 165 ++++++++++++++----- common/git/kicad_git_common.h | 22 ++- kicad/project_tree_pane.cpp | 64 +++---- kicad/tools/kicad_manager_control.cpp | 8 +- pcbnew/git/kigit_pcb_merge.cpp | 7 +- 14 files changed, 208 insertions(+), 122 deletions(-) diff --git a/common/dialogs/git/dialog_git_repository.cpp b/common/dialogs/git/dialog_git_repository.cpp index 8ae7f0206f..b55ef2193c 100644 --- a/common/dialogs/git/dialog_git_repository.cpp +++ b/common/dialogs/git/dialog_git_repository.cpp @@ -289,7 +289,7 @@ void DIALOG_GIT_REPOSITORY::OnTestClick( wxCommandEvent& event ) common.SetPassword( m_txtPassword->GetValue() ); common.SetUsername( m_txtUsername->GetValue() ); common.SetSSHKey( m_fpSSHKey->GetFileName().GetFullPath() ); - common.SetConnType( static_cast<KIGIT_COMMON::GIT_CONN_TYPE>( m_ConnType->GetSelection() ) ); + wxString txtURL = m_txtURL->GetValue(); git_remote_create_with_fetchspec( &remote, m_repository, "origin", txtURL.mbc_str(), @@ -299,7 +299,7 @@ void DIALOG_GIT_REPOSITORY::OnTestClick( wxCommandEvent& event ) if( git_remote_connect( remote, GIT_DIRECTION_FETCH, &callbacks, nullptr, nullptr ) == GIT_OK ) success = true; else - error = git_error_last()->message; + error = KIGIT_COMMON::GetLastGitError(); git_remote_disconnect( remote ); diff --git a/common/dialogs/git/panel_git_repos.cpp b/common/dialogs/git/panel_git_repos.cpp index 774e8852af..fbdd57c35f 100644 --- a/common/dialogs/git/panel_git_repos.cpp +++ b/common/dialogs/git/panel_git_repos.cpp @@ -69,7 +69,7 @@ static std::pair<wxString, wxString> getDefaultAuthorAndEmail() if( git_config_open_default( &config ) != 0 ) { - wxLogTrace( traceGit, "Failed to open default Git config: %s", giterr_last()->message ); + wxLogTrace( traceGit, "Failed to open default Git config: %s", KIGIT_COMMON::GetLastGitError() ); return std::make_pair( name, email ); } @@ -77,7 +77,7 @@ static std::pair<wxString, wxString> getDefaultAuthorAndEmail() if( git_config_get_entry( &name_c, config, "user.name" ) != 0 ) { - wxLogTrace( traceGit, "Failed to get user.name from Git config: %s", giterr_last()->message ); + wxLogTrace( traceGit, "Failed to get user.name from Git config: %s", KIGIT_COMMON::GetLastGitError() ); return std::make_pair( name, email ); } @@ -85,7 +85,7 @@ static std::pair<wxString, wxString> getDefaultAuthorAndEmail() if( git_config_get_entry( &email_c, config, "user.email" ) != 0 ) { - wxLogTrace( traceGit, "Failed to get user.email from Git config: %s", giterr_last()->message ); + wxLogTrace( traceGit, "Failed to get user.email from Git config: %s", KIGIT_COMMON::GetLastGitError() ); return std::make_pair( name, email ); } diff --git a/common/git/git_clone_handler.cpp b/common/git/git_clone_handler.cpp index 5a46a549dc..32819e4456 100644 --- a/common/git/git_clone_handler.cpp +++ b/common/git/git_clone_handler.cpp @@ -31,20 +31,17 @@ #include <wx/filename.h> #include <wx/log.h> -GIT_CLONE_HANDLER::GIT_CLONE_HANDLER() : KIGIT_COMMON( nullptr ) +GIT_CLONE_HANDLER::GIT_CLONE_HANDLER( KIGIT_COMMON* aCommon ) : KIGIT_REPO_MIXIN( aCommon ) {} GIT_CLONE_HANDLER::~GIT_CLONE_HANDLER() -{ - if( m_repo ) - git_repository_free( m_repo ); -} +{} bool GIT_CLONE_HANDLER::PerformClone() { - std::unique_lock<std::mutex> lock( m_gitActionMutex, std::try_to_lock ); + std::unique_lock<std::mutex> lock( GetCommon()->m_gitActionMutex, std::try_to_lock ); if( !lock.owns_lock() ) { @@ -73,16 +70,19 @@ bool GIT_CLONE_HANDLER::PerformClone() cloneOptions.fetch_opts.callbacks.credentials = credentials_cb; cloneOptions.fetch_opts.callbacks.payload = this; - m_testedTypes = 0; + TestedTypes() = 0; ResetNextKey(); + git_repository* newRepo = nullptr; - if( git_clone( &m_repo, m_URL.ToStdString().c_str(), m_clonePath.ToStdString().c_str(), + if( git_clone( &newRepo, m_URL.ToStdString().c_str(), m_clonePath.ToStdString().c_str(), &cloneOptions ) != 0 ) { AddErrorString( wxString::Format( _( "Could not clone repository '%s'" ), m_URL ) ); return false; } + GetCommon()->SetRepo( newRepo ); + if( m_progressReporter ) m_progressReporter->Hide(); diff --git a/common/git/git_clone_handler.h b/common/git/git_clone_handler.h index 10092b91a9..9bf85fca3e 100644 --- a/common/git/git_clone_handler.h +++ b/common/git/git_clone_handler.h @@ -24,13 +24,14 @@ #ifndef GIT_CLONE_HANDLER_H_ #define GIT_CLONE_HANDLER_H_ -#include <git/kicad_git_common.h> -#include <git/git_progress.h> +#include "kicad_git_common.h" +#include "git_repo_mixin.h" +#include "git_progress.h" -class GIT_CLONE_HANDLER : public KIGIT_COMMON, public GIT_PROGRESS +class GIT_CLONE_HANDLER : public KIGIT_REPO_MIXIN { public: - GIT_CLONE_HANDLER(); + GIT_CLONE_HANDLER( KIGIT_COMMON* aCommon ); ~GIT_CLONE_HANDLER(); bool PerformClone(); diff --git a/common/git/git_pull_handler.cpp b/common/git/git_pull_handler.cpp index 9522b96243..adf95fc2a5 100644 --- a/common/git/git_pull_handler.cpp +++ b/common/git/git_pull_handler.cpp @@ -79,7 +79,7 @@ bool GIT_PULL_HANDLER::PerformFetch( bool aSkipLock ) if( git_remote_connect( remote, GIT_DIRECTION_FETCH, &remoteCallbacks, nullptr, nullptr ) ) { AddErrorString( wxString::Format( _( "Could not connect to remote '%s': %s" ), "origin", - git_error_last()->message ) ); + KIGIT_COMMON::GetLastGitError() ) ); return false; } @@ -90,7 +90,7 @@ bool GIT_PULL_HANDLER::PerformFetch( bool aSkipLock ) if( git_remote_fetch( remote, nullptr, &fetchOptions, nullptr ) ) { AddErrorString( wxString::Format( _( "Could not fetch data from remote '%s': %s" ), - "origin", git_error_last()->message ) ); + "origin", KIGIT_COMMON::GetLastGitError() ) ); return false; } diff --git a/common/git/git_pull_handler.h b/common/git/git_pull_handler.h index ab7f0f29b5..91861f78aa 100644 --- a/common/git/git_pull_handler.h +++ b/common/git/git_pull_handler.h @@ -25,8 +25,6 @@ #define _GIT_PULL_HANDLER_H_ #include <git/git_repo_mixin.h> -#include <git/git_progress.h> -#include <git/kicad_git_errors.h> #include <vector> #include <string> @@ -65,7 +63,7 @@ struct ConflictData }; -class GIT_PULL_HANDLER : public KIGIT_ERRORS, public GIT_PROGRESS, public KIGIT_REPO_MIXIN +class GIT_PULL_HANDLER : public KIGIT_REPO_MIXIN { public: GIT_PULL_HANDLER( KIGIT_COMMON* aCommon ); diff --git a/common/git/git_push_handler.cpp b/common/git/git_push_handler.cpp index 8687830370..6f521bbbf1 100644 --- a/common/git/git_push_handler.cpp +++ b/common/git/git_push_handler.cpp @@ -74,7 +74,7 @@ PushResult GIT_PUSH_HANDLER::PerformPush() if( git_remote_connect( remote, GIT_DIRECTION_PUSH, &remoteCallbacks, nullptr, nullptr ) ) { AddErrorString( wxString::Format( _( "Could not connect to remote: %s" ), - git_error_last()->message ) ); + KIGIT_COMMON::GetLastGitError() ) ); return PushResult::Error; } @@ -102,7 +102,7 @@ PushResult GIT_PUSH_HANDLER::PerformPush() if( git_remote_push( remote, &refspecs, &pushOptions ) ) { AddErrorString( wxString::Format( _( "Could not push to remote: %s" ), - git_error_last()->message ) ); + KIGIT_COMMON::GetLastGitError() ) ); git_remote_disconnect( remote ); return PushResult::Error; } diff --git a/common/git/git_push_handler.h b/common/git/git_push_handler.h index d0d8951b80..d540ba2845 100644 --- a/common/git/git_push_handler.h +++ b/common/git/git_push_handler.h @@ -37,7 +37,7 @@ enum class PushResult Error }; -class GIT_PUSH_HANDLER : public KIGIT_ERRORS, public GIT_PROGRESS, public KIGIT_REPO_MIXIN +class GIT_PUSH_HANDLER : public KIGIT_REPO_MIXIN { public: GIT_PUSH_HANDLER( KIGIT_COMMON* aCommon ); diff --git a/common/git/git_repo_mixin.h b/common/git/git_repo_mixin.h index 7a08dea3e3..f86d841ac6 100644 --- a/common/git/git_repo_mixin.h +++ b/common/git/git_repo_mixin.h @@ -15,12 +15,16 @@ #define GIT_REPO_MIXIN_H #include "kicad_git_common.h" +#include "kicad_git_errors.h" +#include "git_progress.h" -class KIGIT_REPO_MIXIN +class KIGIT_REPO_MIXIN: public KIGIT_ERRORS, public GIT_PROGRESS { public: KIGIT_REPO_MIXIN( KIGIT_COMMON* aCommon ) : m_common( aCommon ) { + // Ensure m_common is initialized + wxASSERT( aCommon != nullptr ); } virtual ~KIGIT_REPO_MIXIN() @@ -124,15 +128,6 @@ public: return m_common->GetPassword(); } - /** - * @brief Set the connection type - * @param aConnType The connection type - */ - void SetConnType( KIGIT_COMMON::GIT_CONN_TYPE aConnType ) - { - m_common->SetConnType( aConnType ); - } - /** * @brief Set the username * @param aUsername The username diff --git a/common/git/kicad_git_common.cpp b/common/git/kicad_git_common.cpp index 2c354361cb..4fb4138997 100644 --- a/common/git/kicad_git_common.cpp +++ b/common/git/kicad_git_common.cpp @@ -23,6 +23,7 @@ #include "kicad_git_common.h" #include "kicad_git_memory.h" +#include "git_repo_mixin.h" #include <git/git_progress.h> #include <kiplatform/secrets.h> @@ -36,12 +37,12 @@ #include <vector> KIGIT_COMMON::KIGIT_COMMON( git_repository* aRepo ) : - m_repo( aRepo ), m_connType( GIT_CONN_TYPE::GIT_CONN_LOCAL ), m_testedTypes( 0 ) + m_repo( aRepo ), m_connType( GIT_CONN_TYPE::GIT_CONN_LOCAL ), m_testedTypes( 0 ), + m_nextPublicKey( 0 ) {} KIGIT_COMMON::KIGIT_COMMON( const KIGIT_COMMON& aOther ) : // Initialize base class and member variables - KIGIT_ERRORS(), m_repo( aOther.m_repo ), m_connType( aOther.m_connType ), m_remote( aOther.m_remote ), @@ -171,13 +172,13 @@ std::vector<wxString> KIGIT_COMMON::GetProjectDirs() if( git_reference_name_to_id( &oid, m_repo, "HEAD" ) != GIT_OK ) { - wxLogTrace( traceGit, "An error occurred: %s", git_error_last()->message ); + wxLogTrace( traceGit, "An error occurred: %s", KIGIT_COMMON::GetLastGitError() ); return projDirs; } if( git_commit_lookup( &commit, m_repo, &oid ) != GIT_OK ) { - wxLogTrace( traceGit, "An error occurred: %s", git_error_last()->message ); + wxLogTrace( traceGit, "An error occurred: %s", KIGIT_COMMON::GetLastGitError() ); return projDirs; } @@ -185,7 +186,7 @@ std::vector<wxString> KIGIT_COMMON::GetProjectDirs() if( git_commit_tree( &tree, commit ) != GIT_OK ) { - wxLogTrace( traceGit, "An error occurred: %s", git_error_last()->message ); + wxLogTrace( traceGit, "An error occurred: %s", KIGIT_COMMON::GetLastGitError() ); return projDirs; } @@ -230,29 +231,33 @@ std::vector<wxString> KIGIT_COMMON::GetProjectDirs() std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles() const { - auto get_modified_files = [&]( git_oid* from_oid, git_oid* to_oid ) -> std::set<wxString> + auto get_modified_files = [&]( const git_oid* from_oid, const git_oid* to_oid ) -> std::set<wxString> { std::set<wxString> modified_set; git_revwalk* walker = nullptr; - if( !m_repo ) + if( !m_repo || !from_oid ) return modified_set; if( git_revwalk_new( &walker, m_repo ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to create revwalker" ); + wxLogTrace( traceGit, "Failed to create revwalker: %s", KIGIT_COMMON::GetLastGitError() ); return modified_set; } KIGIT::GitRevWalkPtr walkerPtr( walker ); - if( ( git_revwalk_push( walker, from_oid ) != GIT_OK ) - || ( git_revwalk_hide( walker, to_oid ) != GIT_OK ) ) + if( git_revwalk_push( walker, from_oid ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to push/hide commits" ); + wxLogTrace( traceGit, "Failed to set from commit: %s", KIGIT_COMMON::GetLastGitError() ); return modified_set; } + if( to_oid && git_revwalk_hide( walker, to_oid ) != GIT_OK ) + { + wxLogTrace( traceGit, "Failed to set end commit (maybe new repo): %s", KIGIT_COMMON::GetLastGitError() ); + } + git_oid oid; git_commit* commit; @@ -261,7 +266,7 @@ std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles { if( git_commit_lookup( &commit, m_repo, &oid ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to lookup commit" ); + wxLogTrace( traceGit, "Failed to lookup commit: %s", KIGIT_COMMON::GetLastGitError() ); continue; } @@ -270,7 +275,7 @@ std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles if( git_commit_tree( &tree, commit ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to get commit tree" ); + wxLogTrace( traceGit, "Failed to get commit tree: %s", KIGIT_COMMON::GetLastGitError() ); continue; } @@ -279,7 +284,16 @@ std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles // get parent commit tree to diff against if( !git_commit_parentcount( commit ) ) { - wxLogTrace( traceGit, "No parent commit" ); + git_tree_walk( + tree, GIT_TREEWALK_PRE, + []( const char* root, const git_tree_entry* entry, void* payload ) + { + std::set<wxString>* modified_set_internal = static_cast<std::set<wxString>*>( payload ); + wxString filePath = wxString::Format( "%s%s", root, git_tree_entry_name( entry ) ); + modified_set_internal->insert( filePath ); + return 0; // continue walking + }, + &modified_set ); continue; } @@ -287,7 +301,7 @@ std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles if( git_commit_parent( &parent, commit, 0 ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to get parent commit" ); + wxLogTrace( traceGit, "Failed to get parent commit: %s", KIGIT_COMMON::GetLastGitError() ); continue; } @@ -296,7 +310,7 @@ std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles if( git_commit_tree( &parent_tree, parent ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to get parent commit tree" ); + wxLogTrace( traceGit, "Failed to get parent commit tree: %s", KIGIT_COMMON::GetLastGitError() ); continue; } @@ -322,8 +336,14 @@ std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles git_diff_free( diff ); } + else + { + wxLogTrace( traceGit, "Failed to diff trees: %s", KIGIT_COMMON::GetLastGitError() ); + } } + wxLogTrace( traceGit, "Finished walking commits with end: %s", KIGIT_COMMON::GetLastGitError() ); + return modified_set; }; @@ -346,15 +366,14 @@ std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles if( git_branch_upstream( &remote_head, head ) != GIT_OK ) { wxLogTrace( traceGit, "Failed to get modified remote HEAD" ); - return modified_files; } KIGIT::GitReferencePtr remoteHeadPtr( remote_head ); - git_oid head_oid = *git_reference_target( head ); - git_oid remote_oid = *git_reference_target( remote_head ); + const git_oid* head_oid = git_reference_target( head ); + const git_oid* remote_oid = git_reference_target( remote_head ); - modified_files.first = get_modified_files( &head_oid, &remote_oid ); - modified_files.second = get_modified_files( &remote_oid, &head_oid ); + modified_files.first = get_modified_files( head_oid, remote_oid ); + modified_files.second = get_modified_files( remote_oid, head_oid ); return modified_files; } @@ -370,7 +389,7 @@ bool KIGIT_COMMON::HasLocalCommits() const if( git_repository_head( &head, m_repo ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to get HEAD" ); + wxLogTrace( traceGit, "Failed to get HEAD: %s", KIGIT_COMMON::GetLastGitError() ); return false; } @@ -378,27 +397,33 @@ bool KIGIT_COMMON::HasLocalCommits() const if( git_branch_upstream( &remote_head, head ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to get remote HEAD" ); - return false; + // No remote branch, so we have local commits (new repo?) + wxLogTrace( traceGit, "Failed to get remote HEAD: %s", KIGIT_COMMON::GetLastGitError() ); + return true; } KIGIT::GitReferencePtr remoteHeadPtr( remote_head ); - git_oid head_oid = *git_reference_target( head ); - git_oid remote_oid = *git_reference_target( remote_head ); + const git_oid* head_oid = git_reference_target( head ); + const git_oid* remote_oid = git_reference_target( remote_head ); git_revwalk* walker = nullptr; if( git_revwalk_new( &walker, m_repo ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to create revwalker" ); + wxLogTrace( traceGit, "Failed to create revwalker: %s", KIGIT_COMMON::GetLastGitError() ); return false; } KIGIT::GitRevWalkPtr walkerPtr( walker ); - if( ( git_revwalk_push( walker, &head_oid ) != GIT_OK ) - || ( git_revwalk_hide( walker, &remote_oid ) != GIT_OK ) ) + if( !head_oid || git_revwalk_push( walker, head_oid ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to push/hide commits" ); + wxLogTrace( traceGit, "Failed to push commits: %s", KIGIT_COMMON::GetLastGitError() ); + return false; + } + + if( remote_oid && git_revwalk_hide( walker, remote_oid ) != GIT_OK ) + { + wxLogTrace( traceGit, "Failed to push/hide commits: %s", KIGIT_COMMON::GetLastGitError() ); return false; } @@ -407,7 +432,7 @@ bool KIGIT_COMMON::HasLocalCommits() const // If we can't walk to the next commit, then we are at or behind the remote if( git_revwalk_next( &oid, walker ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to walk to next commit" ); + wxLogTrace( traceGit, "Failed to walk to next commit: %s", KIGIT_COMMON::GetLastGitError() ); return false; } @@ -453,23 +478,61 @@ wxString KIGIT_COMMON::GetRemotename() const if( git_repository_head( &head, m_repo ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to get remote name" ); + wxLogTrace( traceGit, "Failed to get remote name: %s", KIGIT_COMMON::GetLastGitError() ); return retval; } KIGIT::GitReferencePtr headPtr( head ); - if( git_branch_upstream( &upstream, head ) == GIT_OK ) + if( git_branch_upstream( &upstream, head ) != GIT_OK ) { - git_buf remote_name = GIT_BUF_INIT_CONST( nullptr, 0 ); + wxLogTrace( traceGit, "Failed to get upstream branch: %s", KIGIT_COMMON::GetLastGitError() ); + git_strarray remotes = { nullptr, 0 }; - if( git_branch_remote_name( &remote_name, m_repo, git_reference_name( upstream ) ) == GIT_OK ) + if( git_remote_list( &remotes, m_repo ) == GIT_OK ) { - retval = remote_name.ptr; - git_buf_dispose( &remote_name ); + if( remotes.count == 1 ) + retval = remotes.strings[0]; + + git_strarray_dispose( &remotes ); + } + else + { + wxLogTrace( traceGit, "Failed to list remotes: %s", KIGIT_COMMON::GetLastGitError() ); + + // If we can't get the remote name from the upstream branch or the list of remotes, + // just return the default remote name + + git_remote* remote = nullptr; + + if( git_remote_lookup( &remote, m_repo, "origin" ) == GIT_OK ) + { + retval = git_remote_name( remote ); + git_remote_free( remote ); + } + else + { + wxLogTrace( traceGit, "Failed to get remote name from default remote: %s", + KIGIT_COMMON::GetLastGitError() ); + } } - git_reference_free( upstream ); + return retval; + } + + KIGIT::GitReferencePtr upstreamPtr( upstream ); + git_buf remote_name = GIT_BUF_INIT_CONST( nullptr, 0 ); + + if( git_branch_remote_name( &remote_name, m_repo, git_reference_name( upstream ) ) == GIT_OK ) + { + retval = remote_name.ptr; + git_buf_dispose( &remote_name ); + } + else + { + wxLogTrace( traceGit, + "Failed to get remote name from upstream branch: %s", + KIGIT_COMMON::GetLastGitError() ); } return retval; @@ -593,6 +656,21 @@ void KIGIT_COMMON::UpdateCurrentBranchInfo() updatePublicKeys(); } +KIGIT_COMMON::GIT_CONN_TYPE KIGIT_COMMON::GetConnType() const +{ + wxString remote = m_remote; + + if( remote.IsEmpty() ) + remote = GetRemotename(); + + if( remote.StartsWith( "https://" ) || remote.StartsWith( "http://" ) ) + return GIT_CONN_TYPE::GIT_CONN_HTTPS; + else if( remote.StartsWith( "ssh://" ) || remote.StartsWith( "git@" ) || remote.StartsWith( "git+ssh://" ) ) + return GIT_CONN_TYPE::GIT_CONN_SSH; + + return GIT_CONN_TYPE::GIT_CONN_LOCAL; +} + void KIGIT_COMMON::updateConnectionType() { if( m_remote.StartsWith( "https://" ) || m_remote.StartsWith( "http://" ) ) @@ -683,7 +761,7 @@ int KIGIT_COMMON::HandleSSHKeyAuthentication( git_cred** aOut, const wxString& a password.mbc_str() ) != GIT_OK ) { wxLogTrace( traceGit, "Failed to create SSH key credential for %s: %s", - aUsername, git_error_last()->message ); + aUsername, KIGIT_COMMON::GetLastGitError() ); return GIT_ERROR; } @@ -706,7 +784,7 @@ int KIGIT_COMMON::HandleSSHAgentAuthentication( git_cred** aOut, const wxString& if( git_credential_ssh_key_from_agent( aOut, aUsername.mbc_str() ) != GIT_OK ) { wxLogTrace( traceGit, "Failed to create SSH agent credential for %s: %s", - aUsername, git_error_last()->message ); + aUsername, KIGIT_COMMON::GetLastGitError() ); return GIT_ERROR; } @@ -832,7 +910,8 @@ extern "C" int push_update_reference_cb( const char* aRefname, const char* aStat extern "C" int credentials_cb( git_cred** aOut, const char* aUrl, const char* aUsername, unsigned int aAllowedTypes, void* aPayload ) { - KIGIT_COMMON* parent = static_cast<KIGIT_COMMON*>( aPayload ); + KIGIT_REPO_MIXIN* parent = reinterpret_cast<KIGIT_REPO_MIXIN*>( aPayload ); + KIGIT_COMMON* common = parent->GetCommon(); if( parent->GetConnType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_LOCAL ) return GIT_PASSTHROUGH; @@ -849,14 +928,14 @@ extern "C" int credentials_cb( git_cred** aOut, const char* aUrl, const char* aU && !( parent->TestedTypes() & GIT_CREDENTIAL_USERPASS_PLAINTEXT ) ) { // Plaintext authentication - return parent->HandlePlaintextAuthentication( aOut, aUsername ); + return common->HandlePlaintextAuthentication( aOut, aUsername ); } else if( parent->GetConnType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_SSH && ( aAllowedTypes & GIT_CREDENTIAL_SSH_KEY ) && !( parent->TestedTypes() & GIT_CREDENTIAL_SSH_KEY ) ) { // SSH key authentication - return parent->HandleSSHKeyAuthentication( aOut, aUsername ); + return common->HandleSSHKeyAuthentication( aOut, aUsername ); } else { diff --git a/common/git/kicad_git_common.h b/common/git/kicad_git_common.h index f53c838f50..3dc64b6793 100644 --- a/common/git/kicad_git_common.h +++ b/common/git/kicad_git_common.h @@ -32,7 +32,7 @@ #include <wx/string.h> -class KIGIT_COMMON : public KIGIT_ERRORS +class KIGIT_COMMON { public: @@ -90,19 +90,12 @@ public: wxString GetUsername() const { return m_username; } wxString GetPassword() const { return m_password; } - GIT_CONN_TYPE GetConnType() const { return m_connType; } + GIT_CONN_TYPE GetConnType() const; void SetUsername( const wxString& aUsername ) { m_username = aUsername; } void SetPassword( const wxString& aPassword ) { m_password = aPassword; } void SetSSHKey( const wxString& aSSHKey ); - void SetConnType( GIT_CONN_TYPE aConnType ) { m_connType = aConnType; } - void SetConnType( unsigned aConnType ) - { - if( aConnType < static_cast<unsigned>( GIT_CONN_TYPE::GIT_CONN_LAST ) ) - m_connType = static_cast<GIT_CONN_TYPE>( aConnType ); - } - // Holds a temporary variable that can be used by the authentication callback // to remember which types of authentication have been tested so that we // don't loop forever. @@ -137,6 +130,16 @@ public: int HandleSSHAgentAuthentication( git_cred** aOut, const wxString& aUsername ); + static wxString GetLastGitError() + { + const git_error* error = git_error_last(); + + if( error == nullptr ) + return wxString( "No error" ); + + return wxString( error->message ); + } + protected: git_repository* m_repo; @@ -153,6 +156,7 @@ protected: // Make git handlers friends so they can access the mutex friend class GIT_PUSH_HANDLER; friend class GIT_PULL_HANDLER; + friend class GIT_CLONE_HANDLER; private: void updatePublicKeys(); diff --git a/kicad/project_tree_pane.cpp b/kicad/project_tree_pane.cpp index bf929af302..41b286f4fd 100644 --- a/kicad/project_tree_pane.cpp +++ b/kicad/project_tree_pane.cpp @@ -392,7 +392,7 @@ static git_repository* get_git_repository_for_file( const char* filename ) // Find the repository path for the given file if( git_repository_discover( &repo_path, filename, 0, NULL ) != GIT_OK ) { - wxLogTrace( traceGit, "Can't repo discover %s: %s", filename, git_error_last()->message ); + wxLogTrace( traceGit, "Can't repo discover %s: %s", filename, KIGIT_COMMON::GetLastGitError() ); return nullptr; } @@ -400,7 +400,7 @@ static git_repository* get_git_repository_for_file( const char* filename ) if( git_repository_open( &repo, repo_path.ptr ) != GIT_OK ) { - wxLogTrace( traceGit, "Can't open repo for %s: %s", repo_path.ptr, git_error_last()->message ); + wxLogTrace( traceGit, "Can't open repo for %s: %s", repo_path.ptr, KIGIT_COMMON::GetLastGitError() ); return nullptr; } @@ -758,7 +758,7 @@ bool PROJECT_TREE_PANE::hasChangedFiles() if( git_status_list_new( &status_list, repo, &opts ) != GIT_OK ) { - wxLogError( _( "Failed to get status list: %s" ), git_error_last()->message ); + wxLogError( _( "Failed to get status list: %s" ), KIGIT_COMMON::GetLastGitError() ); return false; } @@ -1661,7 +1661,7 @@ void PROJECT_TREE_PANE::onGitInitializeProject( wxCommandEvent& aEvent ) { m_gitLastError = git_error_last()->klass; DisplayErrorMessage( m_parent, _( "Failed to initialize Git project." ), - git_error_last()->message ); + KIGIT_COMMON::GetLastGitError() ); } return; @@ -1673,8 +1673,6 @@ void PROJECT_TREE_PANE::onGitInitializeProject( wxCommandEvent& aEvent ) } //Set up the git remote - - m_TreeProject->GitCommon()->SetConnType( dlg.GetRepoType() ); m_TreeProject->GitCommon()->SetPassword( dlg.GetPassword() ); m_TreeProject->GitCommon()->SetUsername( dlg.GetUsername() ); m_TreeProject->GitCommon()->SetSSHKey( dlg.GetRepoSSHPath() ); @@ -1721,7 +1719,7 @@ void PROJECT_TREE_PANE::onGitInitializeProject( wxCommandEvent& aEvent ) { m_gitLastError = git_error_last()->klass; DisplayErrorMessage( m_parent, _( "Failed to set default remote." ), - git_error_last()->message ); + KIGIT_COMMON::GetLastGitError() ); } return; @@ -1775,6 +1773,8 @@ void PROJECT_TREE_PANE::onGitPullProject( wxCommandEvent& aEvent ) DisplayErrorMessage( m_parent, _( "Failed to pull project" ), errorMessage ); } + + m_gitStatusTimer.Start( 500, wxTIMER_ONE_SHOT ); } @@ -1797,6 +1797,8 @@ void PROJECT_TREE_PANE::onGitPushProject( wxCommandEvent& aEvent ) DisplayErrorMessage( m_parent, _( "Failed to push project" ), errorMessage ); } + + m_gitStatusTimer.Start( 500, wxTIMER_ONE_SHOT ); } @@ -1806,7 +1808,7 @@ static int git_create_branch( git_repository* aRepo, wxString& aBranchName ) if( int error = git_reference_name_to_id( &head_oid, aRepo, "HEAD" ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to lookup HEAD reference: %s", giterr_last()->message ); + wxLogTrace( traceGit, "Failed to lookup HEAD reference: %s", KIGIT_COMMON::GetLastGitError() ); return error; } @@ -1815,7 +1817,7 @@ static int git_create_branch( git_repository* aRepo, wxString& aBranchName ) if( int error = git_commit_lookup( &commit, aRepo, &head_oid ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to lookup commit: %s", giterr_last()->message ); + wxLogTrace( traceGit, "Failed to lookup commit: %s", KIGIT_COMMON::GetLastGitError() ); return error; } @@ -1824,7 +1826,7 @@ static int git_create_branch( git_repository* aRepo, wxString& aBranchName ) if( int error = git_branch_create( &branchRef, aRepo, aBranchName.mb_str(), commit, 0 ) != GIT_OK ) { - wxLogTrace( traceGit, "Failed to create branch: %s", giterr_last()->message ); + wxLogTrace( traceGit, "Failed to create branch: %s", KIGIT_COMMON::GetLastGitError() ); return error; } @@ -1873,7 +1875,7 @@ void PROJECT_TREE_PANE::onGitSwitchBranch( wxCommandEvent& aEvent ) git_reference_dwim( &branchRef, repo, branchName.mb_str() ) != GIT_OK ) { wxString errorMessage = wxString::Format( _( "Failed to lookup branch '%s': %s" ), - branchName, giterr_last()->message ); + branchName, KIGIT_COMMON::GetLastGitError() ); DisplayError( m_parent, errorMessage ); return; } @@ -2112,7 +2114,7 @@ void PROJECT_TREE_PANE::updateGitStatusIconMap() if( git_repository_index( &index, repo ) != GIT_OK ) { m_gitLastError = giterr_last()->klass; - wxLogTrace( traceGit, wxS( "Failed to get git index: %s" ), giterr_last()->message ); + wxLogTrace( traceGit, wxS( "Failed to get git index: %s" ), KIGIT_COMMON::GetLastGitError() ); return; } @@ -2121,7 +2123,7 @@ void PROJECT_TREE_PANE::updateGitStatusIconMap() if( git_status_list_new( &status_list, repo, &status_options ) != GIT_OK ) { - wxLogTrace( traceGit, wxS( "Failed to get git status list: %s" ), giterr_last()->message ); + wxLogTrace( traceGit, wxS( "Failed to get git status list: %s" ), KIGIT_COMMON::GetLastGitError() ); return; } @@ -2191,22 +2193,22 @@ void PROJECT_TREE_PANE::updateGitStatusIconMap() else if( localChanges.count( path ) ) { auto [it, inserted] = m_gitStatusIcons.try_emplace( iter->second, - KIGIT_COMMON::GIT_STATUS::GIT_STATUS_MODIFIED ); + KIGIT_COMMON::GIT_STATUS::GIT_STATUS_AHEAD ); - if( inserted || it->second != KIGIT_COMMON::GIT_STATUS::GIT_STATUS_MODIFIED ) + if( inserted || it->second != KIGIT_COMMON::GIT_STATUS::GIT_STATUS_AHEAD ) updated = true; - it->second = KIGIT_COMMON::GIT_STATUS::GIT_STATUS_MODIFIED; + it->second = KIGIT_COMMON::GIT_STATUS::GIT_STATUS_AHEAD; } else if( remoteChanges.count( path ) ) { auto [it, inserted] = m_gitStatusIcons.try_emplace( iter->second, - KIGIT_COMMON::GIT_STATUS::GIT_STATUS_MODIFIED ); + KIGIT_COMMON::GIT_STATUS::GIT_STATUS_BEHIND ); - if( inserted || it->second != KIGIT_COMMON::GIT_STATUS::GIT_STATUS_MODIFIED ) + if( inserted || it->second != KIGIT_COMMON::GIT_STATUS::GIT_STATUS_BEHIND ) updated = true; - it->second = KIGIT_COMMON::GIT_STATUS::GIT_STATUS_MODIFIED; + it->second = KIGIT_COMMON::GIT_STATUS::GIT_STATUS_BEHIND; } else { @@ -2237,7 +2239,7 @@ void PROJECT_TREE_PANE::updateGitStatusIconMap() else { if( giterr_last()->klass != m_gitLastError ) - wxLogTrace( "git", "Failed to lookup current branch: %s", giterr_last()->message ); + wxLogTrace( "git", "Failed to lookup current branch: %s", KIGIT_COMMON::GetLastGitError() ); m_gitLastError = giterr_last()->klass; } @@ -2420,7 +2422,7 @@ void PROJECT_TREE_PANE::onGitCommit( wxCommandEvent& aEvent ) if( git_repository_index( &index, repo ) != 0 ) { wxLogTrace( traceGit, wxString::Format( _( "Failed to get repository index: %s" ), - giterr_last()->message ) ); + KIGIT_COMMON::GetLastGitError() ) ); return; } @@ -2431,7 +2433,7 @@ void PROJECT_TREE_PANE::onGitCommit( wxCommandEvent& aEvent ) if( git_index_add_bypath( index, file.mb_str() ) != 0 ) { wxMessageBox( wxString::Format( _( "Failed to add file to index: %s" ), - giterr_last()->message ) ); + KIGIT_COMMON::GetLastGitError() ) ); return; } } @@ -2439,21 +2441,21 @@ void PROJECT_TREE_PANE::onGitCommit( wxCommandEvent& aEvent ) if( git_index_write( index ) != 0 ) { wxLogTrace( traceGit, wxString::Format( _( "Failed to write index: %s" ), - giterr_last()->message ) ); + KIGIT_COMMON::GetLastGitError() ) ); return; } if( git_index_write_tree( &tree_id, index ) != 0) { wxLogTrace( traceGit, wxString::Format( _( "Failed to write tree: %s" ), - giterr_last()->message ) ); + KIGIT_COMMON::GetLastGitError() ) ); return; } if( git_tree_lookup( &tree, repo, &tree_id ) != 0 ) { wxLogTrace( traceGit, wxString::Format( _( "Failed to lookup tree: %s" ), - giterr_last()->message ) ); + KIGIT_COMMON::GetLastGitError() ) ); return; } @@ -2465,7 +2467,7 @@ void PROJECT_TREE_PANE::onGitCommit( wxCommandEvent& aEvent ) if( git_repository_head( &headRef, repo ) != 0 ) { wxLogTrace( traceGit, wxString::Format( _( "Failed to get HEAD reference: %s" ), - giterr_last()->message ) ); + KIGIT_COMMON::GetLastGitError() ) ); return; } @@ -2474,7 +2476,7 @@ void PROJECT_TREE_PANE::onGitCommit( wxCommandEvent& aEvent ) if( git_reference_peel( (git_object**) &parent, headRef, GIT_OBJECT_COMMIT ) != 0 ) { wxLogTrace( traceGit, wxString::Format( _( "Failed to get commit: %s" ), - giterr_last()->message ) ); + KIGIT_COMMON::GetLastGitError() ) ); return; } } @@ -2489,7 +2491,7 @@ void PROJECT_TREE_PANE::onGitCommit( wxCommandEvent& aEvent ) if( git_signature_now( &author, author_name.mb_str(), author_email.mb_str() ) != 0 ) { wxLogTrace( traceGit, wxString::Format( _( "Failed to create author signature: %s" ), - giterr_last()->message ) ); + KIGIT_COMMON::GetLastGitError() ) ); return; } @@ -2526,7 +2528,7 @@ void PROJECT_TREE_PANE::onGitCommit( wxCommandEvent& aEvent ) 1, parents ) != 0 ) { wxMessageBox( wxString::Format( _( "Failed to create commit: %s" ), - giterr_last()->message ) ); + KIGIT_COMMON::GetLastGitError() ) ); return; } } @@ -2551,7 +2553,7 @@ bool PROJECT_TREE_PANE::canFileBeAddedToVCS( const wxString& aFile ) if( git_repository_index( &index, repo ) != 0 ) { - wxLogTrace( traceGit, "Failed to get git index: %s", giterr_last()->message ); + wxLogTrace( traceGit, "Failed to get git index: %s", KIGIT_COMMON::GetLastGitError() ); return false; } @@ -2593,6 +2595,8 @@ void PROJECT_TREE_PANE::onGitFetch( wxCommandEvent& aEvent ) GIT_PULL_HANDLER handler( gitCommon ); handler.PerformFetch(); + + m_gitStatusTimer.Start( 500, wxTIMER_ONE_SHOT ); } diff --git a/kicad/tools/kicad_manager_control.cpp b/kicad/tools/kicad_manager_control.cpp index b45bee9fcc..dd78372575 100644 --- a/kicad/tools/kicad_manager_control.cpp +++ b/kicad/tools/kicad_manager_control.cpp @@ -49,6 +49,8 @@ #include <design_block_lib_table.h> #include "dialog_pcm.h" #include <project/project_archiver.h> +#include <project_tree_pane.h> +#include <project_tree.h> #include <launch_ext.h> #include "widgets/filedlg_new_project.h" @@ -163,11 +165,13 @@ int KICAD_MANAGER_CONTROL::NewFromRepository( const TOOL_EVENT& aEvent ) if( !pro.IsOk() ) return -1; - GIT_CLONE_HANDLER cloneHandler; + PROJECT_TREE_PANE *pane = static_cast<PROJECT_TREE_PANE*>( m_frame->GetToolCanvas() ); + + + GIT_CLONE_HANDLER cloneHandler( pane->m_TreeProject->GitCommon() ); cloneHandler.SetURL( dlg.GetRepoURL() ); cloneHandler.SetClonePath( pro.GetPath() ); - cloneHandler.SetConnType( dlg.GetRepoType() ); cloneHandler.SetUsername( dlg.GetUsername() ); cloneHandler.SetPassword( dlg.GetPassword() ); cloneHandler.SetSSHKey( dlg.GetRepoSSHPath() ); diff --git a/pcbnew/git/kigit_pcb_merge.cpp b/pcbnew/git/kigit_pcb_merge.cpp index 766be3b6ec..bffb7db102 100644 --- a/pcbnew/git/kigit_pcb_merge.cpp +++ b/pcbnew/git/kigit_pcb_merge.cpp @@ -23,6 +23,7 @@ #include "kigit_pcb_merge.h" #include <git/kicad_git_blob_reader.h> +#include <git/kicad_git_common.h> #include <git/kicad_git_memory.h> #include <board.h> @@ -95,7 +96,7 @@ int KIGIT_PCB_MERGE::Merge() if( git_blob_lookup( &ancestor_blob, repo, &ancestor->id ) != 0 ) { - wxLogTrace( traceGit, "Could not find ancestor blob: %s", git_error_last()->message ); + wxLogTrace( traceGit, "Could not find ancestor blob: %s", KIGIT_COMMON::GetLastGitError() ); return GIT_ENOTFOUND; } @@ -103,7 +104,7 @@ int KIGIT_PCB_MERGE::Merge() if( git_blob_lookup( &ours_blob, repo, &ours->id ) != 0 ) { - wxLogTrace( traceGit, "Could not find ours blob: %s", git_error_last()->message ); + wxLogTrace( traceGit, "Could not find ours blob: %s", KIGIT_COMMON::GetLastGitError() ); return GIT_ENOTFOUND; } @@ -111,7 +112,7 @@ int KIGIT_PCB_MERGE::Merge() if( git_blob_lookup( &theirs_blob, repo, &theirs->id ) != 0 ) { - wxLogTrace( traceGit, "Could not find theirs blob: %s", git_error_last()->message ); + wxLogTrace( traceGit, "Could not find theirs blob: %s", KIGIT_COMMON::GetLastGitError() ); return GIT_ENOTFOUND; }