Git: Show error when pull fails due to unstaged changes

When git pull fails due to unstaged changes in the working directory,
show an informative error message instead of silently failing.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20363

(cherry picked from commit 0b116673ab)
This commit is contained in:
Seth Hillbrand
2026-02-05 23:01:37 -08:00
parent b395c31c91
commit a8ecaf2cc9
2 changed files with 53 additions and 0 deletions
+50
View File
@@ -378,6 +378,14 @@ PullResult GIT_PULL_HANDLER::handleFastForward()
PullResult GIT_PULL_HANDLER::handleMerge( const git_annotated_commit** aMergeHeads,
size_t aMergeHeadsCount )
{
if( hasUnstagedChanges( GetRepo() ) )
{
AddErrorString(
_( "Cannot merge: you have unstaged changes. "
"Please commit or stash them before pulling." ) );
return PullResult::DirtyWorkdir;
}
git_merge_options merge_opts;
git_merge_options_init( &merge_opts, GIT_MERGE_OPTIONS_VERSION );
@@ -481,6 +489,14 @@ PullResult GIT_PULL_HANDLER::handleMerge( const git_annotated_commit** aMergeHea
PullResult GIT_PULL_HANDLER::handleRebase( const git_annotated_commit** aMergeHeads, size_t aMergeHeadsCount )
{
if( hasUnstagedChanges( GetRepo() ) )
{
AddErrorString(
_( "Cannot rebase: you have unstaged changes. "
"Please commit or stash them before pulling." ) );
return PullResult::DirtyWorkdir;
}
// Get the current branch reference
git_reference* head_ref = nullptr;
@@ -563,6 +579,40 @@ PullResult GIT_PULL_HANDLER::handleRebase( const git_annotated_commit** aMergeHe
}
bool GIT_PULL_HANDLER::hasUnstagedChanges( git_repository* aRepo )
{
if( !aRepo )
return false;
git_status_options opts;
git_status_init_options( &opts, GIT_STATUS_OPTIONS_VERSION );
opts.show = GIT_STATUS_SHOW_WORKDIR_ONLY;
opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED;
git_status_list* status_list = nullptr;
if( git_status_list_new( &status_list, aRepo, &opts ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to get status list: %s", KIGIT_COMMON::GetLastGitError() );
return false;
}
KIGIT::GitStatusListPtr status_list_ptr( status_list );
size_t count = git_status_list_entrycount( status_list );
for( size_t ii = 0; ii < count; ++ii )
{
const git_status_entry* entry = git_status_byindex( status_list, ii );
if( entry->status & ( GIT_STATUS_WT_MODIFIED | GIT_STATUS_WT_DELETED | GIT_STATUS_WT_TYPECHANGE ) )
return true;
}
return false;
}
void GIT_PULL_HANDLER::UpdateProgress( int aCurrent, int aTotal, const wxString& aMessage )
{