feat: Redesign git changes to split stage/unstaged files. (#1359)

* feat: Redesign git changes to split stage/unstaged files.

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* fixup

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* fixup

Signed-off-by: Paolo Insogna <paolo@cowtech.it>

* refactor: streamline git changes panel

* fix: label staged and working diff tabs

* fix: isolate staged and working diff files

* fix: scope staged and working diff updates

* fix: scope git row revert to working changes

---------

Signed-off-by: Paolo Insogna <paolo@cowtech.it>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
Paolo Insogna
2026-05-24 00:49:38 +03:00
committed by GitHub
co-authored by Bohdan Triapitsyn
parent 9af0de0056
commit e16097b05d
42 changed files with 2987 additions and 923 deletions
+48 -3
View File
@@ -291,12 +291,12 @@ export function registerGitRoutes(app) {
return res.status(400).json({ error: 'directory parameter is required' });
}
const { path } = req.body || {};
const { path, scope } = req.body || {};
if (!path || typeof path !== 'string') {
return res.status(400).json({ error: 'path parameter is required' });
}
await revertFile(directory, path);
await revertFile(directory, path, { scope });
res.json({ success: true });
} catch (error) {
console.error('Failed to revert git file:', error);
@@ -304,6 +304,50 @@ export function registerGitRoutes(app) {
}
});
app.post('/api/git/stage', async (req, res) => {
const { stageFiles } = await getGitLibraries();
try {
const directory = req.query.directory;
if (!directory) {
return res.status(400).json({ error: 'directory parameter is required' });
}
const { path, paths } = req.body || {};
const filePaths = Array.isArray(paths) ? paths : [path];
if (!filePaths.some((value) => typeof value === 'string' && value.trim())) {
return res.status(400).json({ error: 'path parameter is required' });
}
await stageFiles(directory, filePaths);
res.json({ success: true });
} catch (error) {
console.error('Failed to stage git file:', error);
res.status(500).json({ error: error.message || 'Failed to stage git file' });
}
});
app.post('/api/git/unstage', async (req, res) => {
const { unstageFiles } = await getGitLibraries();
try {
const directory = req.query.directory;
if (!directory) {
return res.status(400).json({ error: 'directory parameter is required' });
}
const { path, paths } = req.body || {};
const filePaths = Array.isArray(paths) ? paths : [path];
if (!filePaths.some((value) => typeof value === 'string' && value.trim())) {
return res.status(400).json({ error: 'path parameter is required' });
}
await unstageFiles(directory, filePaths);
res.json({ success: true });
} catch (error) {
console.error('Failed to unstage git file:', error);
res.status(500).json({ error: error.message || 'Failed to unstage git file' });
}
});
app.post('/api/git/pull', async (req, res) => {
const { pull } = await getGitLibraries();
try {
@@ -581,7 +625,7 @@ export function registerGitRoutes(app) {
return res.status(400).json({ error: 'directory parameter is required' });
}
const { message, addAll, files } = req.body;
const { message, addAll, files, stageFiles } = req.body;
if (!message) {
return res.status(400).json({ error: 'message is required' });
}
@@ -589,6 +633,7 @@ export function registerGitRoutes(app) {
const result = await commit(directory, message, {
addAll,
files,
stageFiles,
});
res.json(result);
} catch (error) {