mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-03-12 17:37:24 +00:00
feat(git): add revert latest local commit action in git panel
Add a complete revert-local-commit flow so users can undo the most recent local commit directly from the Git header, placed before the refresh icon. Backend - add POST /api/git/revert-local-commit endpoint in server/routes/git.js - validate project input and repository state before executing git operations - revert latest commit with `git reset --soft HEAD~1` to keep changes staged - handle initial-commit edge case by deleting HEAD ref when no parent exists - return clear success and error responses for UI consumption Frontend - add useRevertLocalCommit hook to encapsulate API call and loading state - wire hook into GitPanel and refresh git data after successful revert - add new toolbar action in GitPanelHeader before refresh icon - route action through existing confirmation modal flow - disable action while request is in flight and show activity indicator Shared UI and typing updates - extend ConfirmActionType with `revertLocalCommit` - add confirmation title, label, and style mappings for new action - render RotateCcw icon for revert action in ConfirmActionModal Result - users can safely undo the latest local commit from the UI - reverted commit changes remain staged for immediate recommit/edit workflows
This commit is contained in:
@@ -420,6 +420,53 @@ router.post('/commit', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Revert latest local commit (keeps changes staged)
|
||||
router.post('/revert-local-commit', async (req, res) => {
|
||||
const { project } = req.body;
|
||||
|
||||
if (!project) {
|
||||
return res.status(400).json({ error: 'Project name is required' });
|
||||
}
|
||||
|
||||
try {
|
||||
const projectPath = await getActualProjectPath(project);
|
||||
await validateGitRepository(projectPath);
|
||||
|
||||
try {
|
||||
await spawnAsync('git', ['rev-parse', '--verify', 'HEAD'], { cwd: projectPath });
|
||||
} catch (error) {
|
||||
return res.status(400).json({
|
||||
error: 'No local commit to revert',
|
||||
details: 'This repository has no commit yet.',
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
// Soft reset rewinds one commit while preserving all file changes in the index.
|
||||
await spawnAsync('git', ['reset', '--soft', 'HEAD~1'], { cwd: projectPath });
|
||||
} catch (error) {
|
||||
const errorDetails = `${error.stderr || ''} ${error.message || ''}`;
|
||||
const isInitialCommit = errorDetails.includes('HEAD~1') &&
|
||||
(errorDetails.includes('unknown revision') || errorDetails.includes('ambiguous argument'));
|
||||
|
||||
if (!isInitialCommit) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Initial commit has no parent; deleting HEAD uncommits it and keeps files staged.
|
||||
await spawnAsync('git', ['update-ref', '-d', 'HEAD'], { cwd: projectPath });
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
output: 'Latest local commit reverted successfully. Changes were kept staged.',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Git revert local commit error:', error);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Get list of branches
|
||||
router.get('/branches', async (req, res) => {
|
||||
const { project } = req.query;
|
||||
|
||||
Reference in New Issue
Block a user