AI Compose Commit: Using AI to Intelligently Refactor the Git Commit Workflow
AI Compose Commit: Using AI to Intelligently Refactor the Git Commit Workflow
Section titled “AI Compose Commit: Using AI to Intelligently Refactor the Git Commit Workflow”Introduction
Section titled “Introduction”In the software development process, committing code is a routine task every programmer faces every day. But have you ever run into this situation: at the end of a workday, you open Git, see dozens of unstaged modified files, and have no idea how to organize them into sensible commits?
The traditional approach is to manually stage files in batches, commit them one by one, and write commit messages. This process is both time-consuming and error-prone. We often waste quite a bit of time on this, and after all, nobody wants to worry about these tedious chores late at night when they are already tired.
In the HagiCode project, we introduced a new feature - AI Compose Commit - designed to completely transform this workflow. By using AI to intelligently analyze all uncommitted changes in the working tree, it automatically groups them into multiple logical commits and performs standards-compliant commit operations. In this article, we will take a deep dive into the implementation principles, technical architecture, and the challenges and solutions we encountered in practice.
About HagiCode
Section titled “About HagiCode”The approach shared in this article comes from our practical experience in the HagiCode project.
Background
Section titled “Background”Pain Points of Traditional Git Commits
Section titled “Pain Points of Traditional Git Commits”As a version control system, Git gives developers powerful code management capabilities. But in real-world usage, committing often becomes a bottleneck in the development workflow:
- Manual grouping is time-consuming: When there are many file changes, developers need to inspect each file one by one and decide which changes belong to the same feature. That takes a lot of mental effort.
- Inconsistent commit message quality: Writing commit messages that follow the Conventional Commits specification requires experience and skill, and beginners often produce non-standard commits.
- Complex multi-repository management: In a monorepo environment, switching between different repositories adds operational complexity.
- Interrupted workflow: Committing code interrupts your train of thought and hurts coding efficiency.
These issues are especially obvious in large projects and collaborative team environments. A good development tool should let developers focus on core coding work instead of getting bogged down in a cumbersome commit workflow.
The Trend of AI-Assisted Development
Section titled “The Trend of AI-Assisted Development”In recent years, AI has been used more and more widely in software development. From code completion and bug detection to automatic documentation generation, AI is gradually reaching every stage of the development process. In Git workflows, while some tools already support commit message generation, most are limited to single-commit scenarios and lack the ability to intelligently analyze and group changes across the entire working tree.
HagiCode encountered these pain points during development as well. We tried many tools, but each had one limitation or another. Either the functionality was incomplete, or the user experience was not good enough. That is why we ultimately decided to implement AI Compose Commit ourselves.
HagiCode’s AI Compose Commit feature was created to fill that gap. It does not just generate commit messages - it takes over the entire process from file analysis to commit execution.
Problem
Section titled “Problem”Technical Challenges
Section titled “Technical Challenges”While implementing AI Compose Commit, we faced several technical challenges:
-
File semantic understanding: The AI needs to understand semantic relationships between file changes and decide which files belong to the same functional module. This requires deep analysis of file content, directory structure, and change context.
-
Commit grouping strategy: How should a reasonable grouping standard be defined? By feature, by module, or by file type? Different projects may need different strategies.
-
Real-time feedback and asynchronous processing: Git operations can take a long time, especially when handling a large number of files. How can we complete complex operations while preserving a good user experience?
-
Multi-repository support: In a monorepo architecture, operations need to be routed correctly between the main repository and sub-repositories.
-
Error handling and rollback: If one commit fails, how should already executed commits be handled? Do already staged files need to be rolled back?
-
Commit message consistency: Generated commit messages need to match the project’s existing style and remain consistent with historical commits.
Performance Considerations
Section titled “Performance Considerations”AI processing over a large number of file changes consumes significant time and compute resources. We needed to optimize in the following areas:
- Reduce unnecessary AI calls
- Optimize how file context is constructed
- Implement efficient Git operation batching
These issues all appeared in real HagiCode usage, and we only arrived at a relatively complete solution through repeated iteration and optimization. If you are building a similar tool, we hope our experience gives you some inspiration.
Solution
Section titled “Solution”Overall Architecture Design
Section titled “Overall Architecture Design”We adopted a layered architecture to implement AI Compose Commit, ensuring good scalability and maintainability:
1. API Layer (Web Layer)
Section titled “1. API Layer (Web Layer)”GitController provides the POST /api/git/auto-compose-commit endpoint as the entry point. To optimize user experience, we adopted a fire-and-forget asynchronous pattern:
- After the client sends a request, the server immediately returns HTTP 202 Accepted
- The actual AI processing runs asynchronously in the background
- When processing finishes, the client is notified through SignalR
This design ensures that even if AI processing takes several minutes, users still get an immediate response and do not feel that the system is frozen.
2. Application Service Layer (Application Layer)
Section titled “2. Application Service Layer (Application Layer)”GitAppService is responsible for the core business logic:
- Repository detection: supports multi-repository management in a monorepo
- Lock management: prevents conflicts caused by concurrent operations
- File staging coordination: interacts with the AI processing flow
- Error rollback: restores state when failures occur
3. Distributed Computing Layer (Orleans Grains)
Section titled “3. Distributed Computing Layer (Orleans Grains)”AIGrain serves as the core execution unit for AI operations. It implements the AutoComposeCommitAsync method from the IAIGrain interface:
// Define the interface method for AI-powered automatic commit composition// Parameter notes:// - projectId: unique project identifier// - unstagedFiles: list of unstaged files, including file paths and status information// - projectPath: project root directory path (optional), used to access project context// Return value: a response object containing execution results, including success/failure status and detailed information[Alias("AutoComposeCommitAsync")][ResponseTimeout("00:20:00")] // 20-minute timeout, suitable for handling large change setsTask<AutoComposeCommitResponseDto> AutoComposeCommitAsync( string projectId, GitFileStatusDto[] unstagedFiles, string? projectPath = null);This method sets a 20-minute timeout to handle large change sets. In real-world HagiCode usage, we found that some projects can involve hundreds of changed files in a single pass, requiring more processing time.
4. AI Service Layer
Section titled “4. AI Service Layer”Through the abstract IAIService interface, we implemented a pluggable AI service architecture. We currently use the Claude Helper service, but it can be easily switched to other AI providers.
Core Implementation Logic
Section titled “Core Implementation Logic”File Context Construction
Section titled “File Context Construction”The AI needs to understand the state of each file before it can make intelligent decisions. We build file context through the BuildFileChangesXml method:
/// <summary>/// Build an XML representation of file changes to provide the AI with complete file context information/// </summary>/// <param name="stagedFiles">List of staged files, including file path, status, and old path (for rename operations)</param>/// <returns>A formatted XML string containing metadata for all files</returns>private static string BuildFileChangesXml(GitFileStatusDto[] stagedFiles){ var sb = new StringBuilder(); sb.AppendLine("<files>");
foreach (var file in stagedFiles) { sb.AppendLine(" <file>"); // Use XML escaping to ensure special characters do not break the XML structure sb.AppendLine($" <path>{System.Security.SecurityElement.Escape(file.Path)}</path>"); sb.AppendLine($" <status>{System.Security.SecurityElement.Escape(file.Status)}</status>");
// Handle file rename scenarios and record the old path so the AI can understand change relationships if (!string.IsNullOrEmpty(file.OldPath)) { sb.AppendLine($" <oldPath>{System.Security.SecurityElement.Escape(file.OldPath)}</oldPath>"); }
sb.AppendLine(" </file>"); }
sb.AppendLine("</files>"); return sb.ToString();}This XML-based context includes file paths, statuses, and old paths for rename operations, giving the AI complete metadata. With a structured XML format, we ensure that the AI can accurately understand the state and change type of each file.
AI Permission Management
Section titled “AI Permission Management”To let the AI execute Git operations directly, we configured comprehensive tool permissions:
// Define the set of tools the AI can use, including file operations and Git command execution permissions// Read/Write/Edit: file reading, writing, and editing capabilities// Bash(git:*): permission to execute all Git commands// Other Bash commands: used to inspect file contents and directory structure so the AI can understand contextvar allowedTools = new[]{ "Read", "Write", "Edit", "Bash(git:*)", "Bash(cat:*)", "Bash(ls:*)", "Bash(find:*)", "Bash(grep:*)", "Bash(head:*)", "Bash(tail:*)", "Bash(wc:*)"};
// Build the complete AI request objectvar request = new AIRequest{ Prompt = prompt, // Complete prompt template, including task instructions and constraints WorkingDirectory = projectPath ?? GetTempDirectory(), // Working directory, ensuring the AI runs in the correct project context AllowedTools = allowedTools, // Allowed tool set PermissionMode = PermissionMode.bypassPermissions, // Bypass permission checks so Git operations can run directly LanguagePreference = languagePreference // Language preference setting, ensuring commit messages match user expectations};Here we use PermissionMode.bypassPermissions, which allows the AI to execute Git commands directly without user confirmation. This is central to the feature design, but it also requires strict input validation to prevent abuse. In HagiCode’s production deployment, we ensured the safety of this mechanism through backend parameter validation and log monitoring.
Commit Result Parsing
Section titled “Commit Result Parsing”After the AI finishes execution, it returns structured results. We implemented a dual parsing strategy to ensure compatibility:
/// <summary>/// Parse commit execution results returned by the AI, supporting both delimiter format and regex format/// </summary>/// <param name="aiResponse">Raw response content returned by the AI</param>/// <returns>A parsed list of commit results, where each result includes the commit hash and execution status</returns>private List<CommitResultDto> ParseCommitExecutionResults(string aiResponse){ var results = new List<CommitResultDto>();
// Prefer delimiter-based parsing (new format), which is more explicit and reliable if (aiResponse.Contains("---")) { logger.LogDebug("Using delimiter-based parsing for AI response"); results = ParseDelimitedFormat(aiResponse);
if (results.Count > 0) { return results; // Successfully parsed, return the results directly }
logger.LogWarning("Delimiter-based parsing produced no results, falling back to regex"); } else { logger.LogDebug("No delimiter found, using legacy regex-based parsing"); }
// Fall back to regex parsing (old format) to ensure backward compatibility return ParseLegacyFormat(aiResponse);}The delimiter format uses --- to separate commits, making the structure clear and easy to parse:
---Commit 1: abc123def456feat(auth): add user login functionality
Implement JWT-based authentication with login form and API endpoints.
Co-Authored-By: Hagicode <noreply@hagicode.com>---Commit 2: 789ghi012jkldocs(readme): update installation instructions
Add new setup steps for Docker environment.
Co-Authored-By: Hagicode <noreply@hagicode.com>---This format makes parsing simple and reliable, while also remaining easy for humans to read.
Lock Management Mechanism
Section titled “Lock Management Mechanism”To prevent state conflicts caused by concurrent operations, we implemented a repository lock mechanism:
// Acquire the repository lock to prevent concurrent operations// Parameter notes:// - fullPath: full repository path, used to identify different repository instances// - requestedBy: requester identifier, used for tracking and loggingawait _autoComposeLockService.AcquireLockAsync(fullPath, requestedBy);
try{ // Execute the AI Compose Commit operation // This section calls an Orleans Grain method to perform the actual AI processing and Git operations await aiGrain.AutoComposeCommitAsync(projectId, unstagedFiles, projectPath);}finally{ // Ensure the lock is released whether the operation succeeds or fails // Using a finally block guarantees lock release even when exceptions occur, preventing deadlocks await _autoComposeLockService.ReleaseLockAsync(fullPath);}The lock has a 20-minute timeout, matching the timeout used for AI operations. If the operation fails or times out, the system automatically releases the lock to avoid permanent blocking. In real HagiCode usage, we found this lock mechanism to be extremely important, especially in collaborative environments where multiple developers may trigger AI Compose Commit at the same time.
SignalR Real-Time Notifications
Section titled “SignalR Real-Time Notifications”After processing completes, the system sends a notification to the frontend through SignalR:
/// <summary>/// Send a notification when automatic commit composition is complete/// </summary>/// <param name="projectId">Project identifier, used to route the notification to the correct client</param>/// <param name="totalCount">Total number of commits, including successes and failures</param>/// <param name="successCount">Number of successful commits</param>/// <param name="failureCount">Number of failed commits</param>/// <param name="success">Whether the overall operation succeeded</param>/// <param name="error">Error message (if the operation failed)</param>private async Task SendAutoComposeCommitNotificationAsync( string projectId, int totalCount, int successCount, int failureCount, bool success, string? error){ try { // Build the notification DTO containing detailed execution results var notification = new AutoComposeCommitCompletedDto { ProjectId = projectId, TotalCount = totalCount, SuccessCount = successCount, FailureCount = failureCount, Success = success, Error = error };
// Broadcast the notification to all connected clients through the SignalR Hub await messageService.SendAutoComposeCommitCompletedAsync(notification);
logger.LogInformation( "Auto compose commit notification sent for project {ProjectId}: {SuccessCount}/{TotalCount} succeeded", projectId, successCount, totalCount); } catch (Exception ex) { // Log notification errors without affecting the main operation flow // A notification failure should not cause the entire operation to fail logger.LogError(ex, "Failed to send auto compose commit notification for project {ProjectId}", projectId); }}After the frontend receives the notification, it can update the UI to show whether the commit succeeded or failed, improving the user experience. This real-time feedback mechanism received strong feedback from HagiCode users, who can clearly see when the operation finishes and what the outcome is.
Implementation
Section titled “Implementation”Prompt Engineering Design
Section titled “Prompt Engineering Design”AI behavior is entirely determined by the prompt, so we carefully designed the prompt template for Auto Compose Commit. Taking the Chinese version as an example (auto-compose-commit.zh-CN.hbs):
Non-Interactive Mode Support
Section titled “Non-Interactive Mode Support”At the beginning of the prompt, we explicitly declare support for non-interactive execution mode, which is a critical requirement for CI/CD and automation scripts:
**Important Note**: This prompt may run in a non-interactive environment (such as CI/CD or automation scripts).
**Non-Interactive Mode**:- Do not use AskUserQuestion or any interactive tools- When user input is required: - Use sensible defaults (for example, use feat as the commit type) - Skip optional confirmation steps - Record any assumptions madeThis design ensures that AI Compose Commit can be used not only in interactive IDE environments, but also integrated into CI/CD pipelines to deliver a fully automated commit workflow.
Branch Protection Mechanism
Section titled “Branch Protection Mechanism”To prevent the AI from executing dangerous operations, we added strict branch protection rules to the prompt:
**Branch Protection**:- Do not perform any branch switching operations (git checkout, git switch)- All `git commit` commands must run on the current branch- Do not create, delete, or rename branches- Do not modify untracked files or unstaged changes- If branch switching is required to complete the operation, return an error instead of executing itBy constraining the AI’s tool usage scope, these rules ensure operational safety. In HagiCode’s practical testing, we verified the effectiveness of these constraints: when the AI encounters a situation that would require a branch switch, it safely returns an error instead of taking dangerous action.
Intelligent Grouping Decision Tree
Section titled “Intelligent Grouping Decision Tree”The prompt defines the decision logic for file grouping in detail:
**File Grouping Decision Tree**:├── Is it a configuration file (package.json, tsconfig.json, .env, etc.)?│ ├── Yes -> separate commit (type: chore or build)│ └── No -> continue├── Is it a documentation file (README.md, *.md, docs/**)?│ ├── Yes -> separate commit (type: docs)│ └── No -> continue├── Is it related to the same feature?│ ├── Yes -> merge into the same commit│ └── No -> commit separately└── Is it a cross-module change? ├── Yes -> group by module └── No -> group by featureThis decision tree gives the AI clear grouping logic, ensuring the generated commits remain semantically reasonable. In real HagiCode usage, we found that this decision tree can handle the vast majority of common scenarios, and the grouping results match developer expectations.
Historical Format Consistency Analysis
Section titled “Historical Format Consistency Analysis”To keep commit messages consistent with project history, the prompt requires the AI to analyze recent commit history before generation:
**Historical Format Consistency**: Before generating commit messages, you **must** analyze the current repository's commit history to match the existing style.
1. Use `git log -n 15 --pretty=format:"%H|%s|%b%n---%n"` to get the recent commit history2. Analyze the commits to identify: - Structural patterns: does the project use multi-paragraph messages? Are there `Changes:` or `Capabilities:` sections? - Language patterns: are commit messages in English, Chinese, or mixed? - Common types: which commit types are most often used (`feat`, `fix`, `docs`, etc.)? - Special formatting: are there `Co-Authored-By` lines? Any other project-specific conventions?3. Generate commit messages that follow the detected patternsThis analysis ensures that AI-generated commit messages do not feel out of place, but instead remain stylistically aligned with the project’s history. In HagiCode’s multilingual projects, this feature is especially important because it can automatically choose the appropriate language and format based on commit history.
Co-Authored-By Requirement
Section titled “Co-Authored-By Requirement”Every commit must include Co-Authored-By information:
**Important**: Every commit must include Co-Authored-By information- Use the following format: `git commit -m "type(scope): subject" -m "" -m "Co-Authored-By: Hagicode <noreply@hagicode.com>"`- Or include the `Co-Authored-By` line directly in the commit messageThis is not only for contribution compliance, but also for tracing AI-assisted commit history. HagiCode treats this as a mandatory rule to ensure that all AI-generated commits carry a clear source marker.
Workflow Walkthrough
Section titled “Workflow Walkthrough”The full AI Compose Commit workflow is as follows:
- User trigger: The user clicks the “AI Auto Compose Commit” button in the Git Status panel or Quick Actions Zone.
- API request: The frontend sends a POST request to the
/api/git/auto-compose-commitendpoint. - Immediate response: The server returns HTTP 202 Accepted without waiting for processing to finish.
- Background processing:
- GitAppService acquires the repository lock
- Calls
AIGrain.AutoComposeCommitAsync - Builds the file context XML
- Executes the AI prompt so the AI can analyze and perform commits
- AI execution:
- Uses Git commands to obtain all unstaged changes
- Reads file contents to understand the nature of the changes
- Groups files by semantic relationship
- Executes
git addandgit commitfor each group
- Result parsing: Parses the execution results returned by the AI.
- Notification delivery: Notifies the frontend through SignalR.
- Lock release: Releases the repository lock whether the operation succeeds or fails.
This workflow is designed so that users can continue with other work immediately after initiating the operation, without waiting for the AI to finish. Feedback from HagiCode users shows that this asynchronous processing model greatly improves the workflow experience.
Error Handling Mechanism
Section titled “Error Handling Mechanism”We implemented multi-layer error handling:
1. Input Validation
Section titled “1. Input Validation”// Validate request parameters to prevent invalid requests from reaching backend processing logicif (request.UnstagedFiles == null || request.UnstagedFiles.Count == 0){ return BadRequest(new { message = "No unstaged files provided. Please make changes in the working directory first.", status = "validation_failed" });}2. Error Rollback
Section titled “2. Error Rollback”If an error occurs during AI processing, the system performs a rollback operation and unstages files that were already staged, preventing an inconsistent state from being left behind. In real HagiCode usage, this mechanism saved us from multiple unexpected interruptions and ensured repository state integrity.
3. Timeout Handling
Section titled “3. Timeout Handling”The 20-minute timeout ensures that long-running operations do not block resources indefinitely. After a timeout, the system releases the lock and notifies the user that the operation failed. In real HagiCode usage, we found that most operations complete within 2 to 5 minutes, and only extremely large change sets approach the timeout limit.
Best Practices
Section titled “Best Practices”Best Practices for Using AI Compose Commit
Section titled “Best Practices for Using AI Compose Commit”1. Choose the Right Moments
Section titled “1. Choose the Right Moments”AI Compose Commit is best suited for the following scenarios:
- At the end of a workday, when you need to process changes across many files in one batch
- After a refactoring operation, when several related files need to be committed separately
- After a feature is completed, when related changes need to be grouped into commits
It is not suitable for the following scenarios:
- Quick commits for a single file (a normal commit is faster)
- Scenarios requiring precise control over commit content
- Commits containing sensitive information that require human review
2. Review AI-Generated Commits
Section titled “2. Review AI-Generated Commits”Although AI-powered intelligent grouping is powerful, developers should still review the generated commits:
- Check whether the grouping matches expectations
- Verify the accuracy of commit messages
- Confirm that no files were omitted or incorrectly included
If you find an unreasonable grouping, you can use git reset --soft HEAD~N to undo it and regroup. HagiCode’s experience shows that even when AI grouping is smart, manual review is still valuable, especially for important feature commits.
3. Align with Project Standards
Section titled “3. Align with Project Standards”Make sure your project’s Git configuration supports Conventional Commits:
# Install commitlintnpm install -g @commitlint/cli @commitlint/config-conventional
# Configure commitlintecho "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.jsThis lets you validate commit message format in CI/CD workflows and keeps it aligned with the format generated by AI Compose Commit.
Suggestions for Building Similar Features
Section titled “Suggestions for Building Similar Features”If you want to implement a similar AI-assisted commit feature in your own project, here are our suggestions:
1. Start Small
Section titled “1. Start Small”Begin with single commit message generation, then gradually expand to multi-commit grouping. This makes it easier to validate and iterate. HagiCode followed the same path: early versions only supported single commits, and later expanded to intelligent grouping across multiple commits.
2. Use a Mature AI SDK
Section titled “2. Use a Mature AI SDK”Do not implement AI invocation logic from scratch. Using an existing SDK reduces development time and potential bugs. We used the Claude Helper service, which provides a stable interface and robust error handling.
3. Invest in Prompt Design
Section titled “3. Invest in Prompt Design”Prompt quality directly determines output quality. Spend time designing a detailed prompt, including:
- Clear task descriptions
- Specific output format requirements
- Rules for handling edge cases
- Illustrative examples
HagiCode invested heavily in prompt design, and this was one of the key reasons the feature succeeded.
4. Implement Comprehensive Error Handling
Section titled “4. Implement Comprehensive Error Handling”AI operations can fail for many reasons, such as network issues, API rate limits, or content moderation. Make sure your system can handle these errors gracefully and provide meaningful error information.
5. Provide Manual Intervention Mechanisms
Section titled “5. Provide Manual Intervention Mechanisms”Do not automate everything completely. Leave users in control. Provide options to review grouping results, adjust groups, and manually edit commit messages to balance automation and flexibility. Although HagiCode supports automatic execution, it still preserves preview and adjustment capabilities.
Performance Optimization Tips
Section titled “Performance Optimization Tips”1. File Filtering
Section titled “1. File Filtering”When constructing file context, filter out files that do not need AI analysis:
// Filter out generated files and excessively large files to reduce the AI processing burdenvar relevantFiles = stagedFiles .Where(f => !IsGeneratedFile(f.Path)) .Where(f => !IsLargeFile(f.Path)) .ToArray();2. Parallel Processing
Section titled “2. Parallel Processing”If multiple independent repositories are supported, commits in different repositories can be processed in parallel to improve overall efficiency.
3. Cache Optimization
Section titled “3. Cache Optimization”Cache project commit history analysis results to avoid re-analyzing them every time. Historical format preferences can be stored in configuration files to reduce AI calls.
Conclusion
Section titled “Conclusion”AI Compose Commit represents a deep application of AI technology in software development tools. By intelligently analyzing file changes, automatically grouping commits, and generating standards-compliant commit messages, it significantly improves the efficiency of Git workflows and allows developers to focus more on core coding work.
During implementation, we learned several important lessons:
- User feedback is critical: Early versions used synchronous waiting, and users reported a poor experience. After switching to a fire-and-forget model, satisfaction improved significantly.
- Prompt design determines quality: A carefully designed prompt does more to guarantee AI output quality than a complex algorithm.
- Safety always comes first: Granting the AI permission to execute Git commands directly improves efficiency, but it must be paired with strict constraints and validation.
- Progressive improvement works best: Starting with simple scenarios and gradually increasing complexity is more likely to succeed than trying to implement everything at once.
In the future, we plan to further optimize AI Compose Commit, including:
- Supporting more commit grouping strategies (by time, by developer, and so on)
- Integrating code review workflows to trigger review automatically before commits
- Supporting custom commit message templates to meet the personalized needs of different projects
If you find the approach shared in this article valuable, give HagiCode a try and experience how this feature works in real development. After all, practice is the only criterion for testing truth.
Thank you for reading. If you found this article helpful, please click the like button below so more people can discover it.
This content was created with AI-assisted collaboration, reviewed by me, and reflects my own views and positions.
- Author: newbe36524
- Article link: https://docs.hagicode.com/blog/2026-02-26-ai-compose-commit-implementation/
- Copyright notice: Unless otherwise stated, all articles on this blog are licensed under BY-NC-SA. Please cite the source when reposting.