mirror of
https://github.com/microsoft/vscode.git
synced 2026-02-15 07:28:05 +00:00
Merge pull request #285750 from microsoft/285744
Allow git `ls-files` and `--no-pager`/`-C <path>` args before sub-command
This commit is contained in:
@@ -197,22 +197,24 @@ export const terminalChatAgentToolsConfiguration: IStringDictionary<IConfigurati
|
||||
//
|
||||
// Safe and common sub-commands
|
||||
|
||||
'git status': true,
|
||||
'git log': true,
|
||||
'git show': true,
|
||||
'git diff': true,
|
||||
// Note: These patterns support `-C <path>` and `--no-pager` immediately after `git`
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+status\\b/': true,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+log\\b/': true,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+show\\b/': true,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+diff\\b/': true,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+ls-files\\b/': true,
|
||||
|
||||
// git grep
|
||||
// - `--open-files-in-pager`: This is the configured pager, so no risk of code execution
|
||||
// - See notes on `grep`
|
||||
'git grep': true,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+grep\\b/': true,
|
||||
|
||||
// git branch
|
||||
// - `-d`, `-D`, `--delete`: Prevent branch deletion
|
||||
// - `-m`, `-M`: Prevent branch renaming
|
||||
// - `--force`: Generally dangerous
|
||||
'git branch': true,
|
||||
'/^git branch\\b.*-(d|D|m|M|-delete|-force)\\b/': false,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+branch\\b/': true,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+branch\\b.*-(d|D|m|M|-delete|-force)\\b/': false,
|
||||
|
||||
// #endregion
|
||||
|
||||
|
||||
@@ -202,6 +202,62 @@ suite('CommandLineAutoApprover', () => {
|
||||
ok(!await isAutoApproved('kill process'));
|
||||
});
|
||||
|
||||
test('should handle git patterns with -C and --no-pager', async () => {
|
||||
setAutoApprove({
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+status\\b/': true,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+log\\b/': true,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+show\\b/': true,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+diff\\b/': true,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+ls-files\\b/': true,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+grep\\b/': true,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+branch\\b/': true,
|
||||
'/^git(\\s+(-C\\s+\\S+|--no-pager))*\\s+branch\\b.*-(d|D|m|M|-delete|-force)\\b/': false,
|
||||
});
|
||||
|
||||
// Basic commands
|
||||
ok(await isAutoApproved('git status'));
|
||||
ok(await isAutoApproved('git log'));
|
||||
ok(await isAutoApproved('git show HEAD'));
|
||||
ok(await isAutoApproved('git diff'));
|
||||
ok(await isAutoApproved('git ls-files'));
|
||||
ok(await isAutoApproved('git grep pattern'));
|
||||
ok(await isAutoApproved('git branch'));
|
||||
|
||||
// ls-files with options
|
||||
ok(await isAutoApproved('git ls-files --cached'));
|
||||
ok(await isAutoApproved('git -C /path ls-files'));
|
||||
ok(await isAutoApproved('git --no-pager ls-files'));
|
||||
|
||||
// With -C path
|
||||
ok(await isAutoApproved('git -C /some/path status'));
|
||||
ok(await isAutoApproved('git -C ../relative log'));
|
||||
ok(await isAutoApproved('git -C . diff'));
|
||||
|
||||
// With --no-pager
|
||||
ok(await isAutoApproved('git --no-pager status'));
|
||||
ok(await isAutoApproved('git --no-pager log'));
|
||||
ok(await isAutoApproved('git --no-pager diff HEAD~1'));
|
||||
|
||||
// With both -C and --no-pager
|
||||
ok(await isAutoApproved('git -C /path --no-pager status'));
|
||||
ok(await isAutoApproved('git --no-pager -C /path log'));
|
||||
ok(await isAutoApproved('git -C /path1 -C /path2 status'));
|
||||
ok(await isAutoApproved('git --no-pager --no-pager log'));
|
||||
|
||||
// Branch deletion should be denied
|
||||
ok(!await isAutoApproved('git branch -d feature'));
|
||||
ok(!await isAutoApproved('git branch -D feature'));
|
||||
ok(!await isAutoApproved('git branch --delete feature'));
|
||||
ok(!await isAutoApproved('git -C /path branch -d feature'));
|
||||
ok(!await isAutoApproved('git --no-pager branch -D feature'));
|
||||
ok(!await isAutoApproved('git -C /path --no-pager branch --force'));
|
||||
|
||||
// Branch rename should be denied
|
||||
ok(!await isAutoApproved('git branch -m old new'));
|
||||
ok(!await isAutoApproved('git branch -M old new'));
|
||||
ok(!await isAutoApproved('git -C /path branch -m old new'));
|
||||
});
|
||||
|
||||
suite('flags', () => {
|
||||
test('should handle case-insensitive regex patterns with i flag', async () => {
|
||||
setAutoApprove({
|
||||
|
||||
Reference in New Issue
Block a user