Skip to content

Feature: Added SSH support for Git and progress reporting in Status Center #18063

Open
NyanHeart wants to merge 2 commits intofiles-community:mainfrom
NyanHeart:main
Open

Feature: Added SSH support for Git and progress reporting in Status Center #18063
NyanHeart wants to merge 2 commits intofiles-community:mainfrom
NyanHeart:main

Conversation

@NyanHeart
Copy link

Resolved / Related Issues

Closes #17692

Changes

  • SSH Support: Implemented SSH key authentication via the system OpenSSH Agent. This resolves compatibility issues with LibGit2Sharp 0.31.0 and adds support for passphrase-protected keys without custom dialogs.
  • Status Center Integration: Git Push, Fetch, and Pull operations now report real-time progress (items processed, transfer bytes) to the Status Center.
  • Real-time Refresh: Fixed the Git Status Bar (commits ahead/behind) not refreshing automatically after remote operations.
  • Performance: Refactored FetchOrigin and PullOriginAsync to use async/await and run on background threads, preventing UI freezes during network operations.
  • Cleanup: Removed the obsolete GitPassphraseDialog and custom SSH credential logic.

Steps used to test these changes

  1. SSH Push/Pull:
    • Cloned a repository using an SSH URL (git@github.com:...).
    • Verified that git push and git pull work seamlessly using the system SSH Agent (with both passphrase-protected and standard keys).
  2. Status Center Feedback:
    • Performed a long-running push operation.
    • Observed the Status Center card appearing with "Pushing..." status.
    • Verified that progress percentages and item counts updated in real-time.
    • Verified that success/failure cards are displayed correctly after completion.
  3. UI Refresh:
    • Committed a change locally.
    • Pushed the change to origin.
    • Verified that the "Commits Ahead" count in the status bar (bottom right) automatically cleared to 0 without needing a manual refresh.
  4. HTTPS Fallback:
    • Verified that standard HTTPS repositories still work correctly with username/password (Personal Access Token) authentication.

…unity#17692)

- Implemented SSH key authentication by integrating with the system OpenSSH Agent, resolving compatibility issues with LibGit2Sharp 0.31.0 and enabling support for passphrase-protected keys.
- Integrated Git Push, Fetch, and Pull operations with the Status Center to provide real-time progress feedback (items processed, transfer bytes).
- Fixed the issue where the Git Status Bar (commits ahead/behind) would not refresh automatically after remote operations.
- Refactored FetchOrigin and PullOriginAsync to use async/await and perform operations on background threads, preventing UI freezes.
- Removed the obsolete GitPassphraseDialog and custom SSH credential handling logic in favor of the native agent.
- Added GitFetch and GitPull to FileOperationType and updated Resources.resw with localized strings for these operations.
Closes files-community#17692
@yair100 yair100 added the ready for review Pull requests that are ready for review label Jan 14, 2026
yair100
yair100 previously approved these changes Jan 14, 2026
@yair100 yair100 changed the title Feature: Enhanced Git SSH Support (Agent) & Status Center Integration Feature: Added SSH support for Git and progress reporting in Status Center Jan 14, 2026
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-fetch on folder navigation silently fails due to being called from a background thread in BaseShellPage.cs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer used after the refactoring.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The older code used Prune = true in _fetchOptions, but that appears to have been removed. Is this intentional?

@workbysaran
Copy link
Contributor

workbysaran commented Jan 15, 2026

I am able to successfully pull and push using an SSH URL (and HTTPS). However, I encountered the following problems,

  1. When the Windows "OpenSSH Authentication Agent" service is not running, there is no user-friendly error message. Instead, it reports: "git pull failed due to a timeout error."
  2. The same error message is displayed when there are uncommitted changes in the working directory and a pull is attempted.
  3. Auto-fetch triggered during folder navigation fails with the following exception:
    System.AggregateException: A Task's exception was not observed by awaiting the Task or by accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread.
    ---> System.Runtime.InteropServices.COMException (0x8001010E)
    at WinRT.ExceptionHelpers.g__Throw|38_0(Int32 hr)
    at ABI.Microsoft.UI.Xaml.IApplicationMethods.get_Resources(IObjectReference _obj)
    at Files.App.Utils.StatusCenter.StatusCenterItem..ctor(...)
    at Files.App.ViewModels.UserControls.StatusCenterViewModel.AddItem(...)
    at Files.App.Utils.StatusCenter.StatusCenterHelper.AddCard_GitFetch(...)
    at Files.App.Utils.Git.GitHelpers.FetchOrigin(String repositoryPath, CancellationToken cancellationToken)

- Threading: Wrapped Status Center UI updates and dialogs in `DispatcherQueue.TryEnqueue` to prevent `COMException` (RPC_E_WRONG_THREAD) during background fetches.
- Cleanup: Removed unused `_fetchOptions` field and restored `Prune = true` for fetch operations.
- Error Handling:
  - Catch `CheckoutConflictException` specifically for uncommitted changes during pull, providing a helpful localized error message.
  - Catch generic `LibGit2SharpException` to surface authentic underlying errors (e.g. ssh-agent failures, missing files) to the user via dialog.
- Localization: Added `GitError_UncommittedChanges` resource string.
Comment on lines 623 to +626
{
Username = signature.Name,
Password = token
fsProgress.ItemsCount = total;
fsProgress.SetProcessedSize(bytes);
fsProgress.AddProcessedItemsCount(1); // Not accurate but shows activity
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The OnPushTransferProgress callback in PushToOriginAsync updates UI-bound properties from a background thread without using the dispatcher, which will cause a crash.
Severity: CRITICAL

Suggested Fix

Wrap the property updates on the fsProgress object inside the OnPushTransferProgress callback with a MainWindow.Instance.DispatcherQueue.TryEnqueue call, similar to the implementation in FetchOrigin and PullOriginAsync.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: src/Files.App/Utils/Git/GitHelpers.cs#L623-L626

Potential issue: The `OnPushTransferProgress` callback within `PushToOriginAsync`
directly updates properties of the `fsProgress` object, which is an instance of
`StatusCenterItemProgressModel`. This model raises `PropertyChanged` events, which must
occur on the UI thread. Since the operation runs on a background thread, updating these
properties without dispatching to the UI thread will cause a `COMException
(RPC_E_WRONG_THREAD)` and crash the application during a git push operation. Other git
operations in the same file, like `FetchOrigin` and `PullOriginAsync`, correctly wrap
these UI updates using `DispatcherQueue.TryEnqueue`.

Did we get this right? 👍 / 👎 to inform future reviews.

@NyanHeart
Copy link
Author

@workbysaran Thanks for the detailed review! I've pushed a fix that addresses your feedback:

  1. Threading Crash: Wrapped all Status Center UI updates and dialog calls in DispatcherQueue.TryEnqueue to safely handle background fetch operations. This should resolve the COMException 0x8001010E / RPC_E_WRONG_THREAD crash.
  2. Error Handling:
    • Added specific handling for LibGit2SharpException to surface underlying errors directly to the user via a dialog.
    • Added handling for CheckoutConflictException (uncommitted changes) with a localized error message.
  3. Logic: Restored Prune = true for fetch operations.
  4. Cleanup: Removed the unused variables as requested.

Could you please take another look? Thanks!

var remoteName = repository.Network.Remotes.FirstOrDefault()?.Name ?? "origin";

// Add Status Center Card
var banner = StatusCenterHelper.AddCard_GitFetch(remoteName, ReturnResult.InProgress);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The call to StatusCenterHelper.AddCard_GitFetch needs to be dispatched to the UI thread. An exception is thrown during auto-fetch.

@workbysaran
Copy link
Contributor

@NyanHeart

Thanks for the update. I tested again, and here are my findings.

When the Windows "OpenSSH Authentication Agent" service is not running, there is no user-friendly error message. Instead, it reports: "git pull failed due to a timeout error."

It appears that the LibGit2Sharp library hides transport-level errors, so only the generic message "could not read refs from remote repository" is returned. We may need to investigate and address this in a separate PR.

The Git CLI shows the following error:

git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

I think we should accept this behavior with the current limitation.

The same error message is displayed when there are uncommitted changes in the working directory and a pull is attempted.

Now it shows, "Please commit or stash your changes before pulling," which is good!

@Josh65-2201
Copy link
Member

Added handling for CheckoutConflictException (uncommitted changes) with a localized error message.

Does this fix #18024 ?

@yair100
Copy link
Member

yair100 commented Feb 6, 2026

@NyanHeart fyi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for review Pull requests that are ready for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Implement SSH Authentication Support for Git Integration

4 participants

Comments