[LS] [AI Context] Local Git Diff Provider - Language Server
Please see the epic for the product requirements.
Problem to Solve
We need to enable users to add git diffs as context in Duo Chat to allow them to ask questions about their local changes. While we initially considered using isomorphic-git for handling git operations, performance testing against the GitLab monolith repository showed significant performance issues that would impact user experience.
Proposed Solution
Implement a Language Server-based git diff provider that will:
- Create a custom RPC request channel between the Language Server and editor clients (like VSCode) for fetching git diffs
- Determine the main/default branch deterministically using the following priority order:
- Check remote HEAD reference file (
.git/refs/remotes/<remote>/HEAD) - Query remote repository info if reference file not available
- Look for common branch names in local branches (
main,master,trunk,development) - Default to "main" if no other method succeeds
- Check remote HEAD reference file (
- Expose git diff options to the user:
- Diff from main branch (default)
- Diff from HEAD (working state)
- Diff from any other local branch
Note: Fetching commit content is out of scope for this issue and will be handled separately.
API Flow
sequenceDiagram
participant DC as DuoChat UI
participant LS as Language Server
participant VS as VSCode Extension
participant Git as Git (VSCode API)
DC->>LS: User selects git diff context
LS->>VS: Request: $/gitlab/ai-context/git-diff
Note over LS,VS: Contains repositoryUri and optional branch
VS->>Git: getDiffWithHead() or getDiffWithBranch()
Git-->>VS: Diff content
VS-->>LS: Diff string
LS-->>DC: Context item with diff content
Technical Details
- The Language Server will implement a
LocalGitContextProviderthat handles git context operations - Instead of using isomorphic-git for diff operations, we'll rely on editor-specific git implementations via RPC
- The VSCode extension will implement the RPC endpoint using the built-in Git extension API
- Diffs will be fetched on-demand when context items are added to chat
Main Branch Resolution Logic
Based on the implementation in the diff, the provider will resolve the main branch in this order:
- Check
.git/refs/remotes/<remote>/HEADfor the default branch reference - If not found, attempt to get remote repository info (for public repos)
- If remote info unavailable, check local branches for common names in priority order:
mainmastertrunkdevelopment
- Default to "main" if no other method succeeds
This implementation allows for reliable branch resolution while avoiding the performance issues encountered with isomorphic-git.