Skip to content
This repository was archived by the owner on Jan 14, 2026. It is now read-only.

Commit 84fb65d

Browse files
committed
refactor(gitcommit): optimize module imports and improve glob matching
- Cache GitTool require at module level instead of per-function calls - Add proper glob-to-lua-pattern conversion with ** support - Reuse Git.is_repository() instead of duplicating is_git_repo logic - Normalize path separators for cross-platform glob matching
1 parent db78356 commit 84fb65d

3 files changed

Lines changed: 53 additions & 33 deletions

File tree

lua/codecompanion/_extensions/gitcommit/git.lua

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,51 @@ function Git._filter_diff(diff_content)
7878
return table.concat(filtered_lines, "\n")
7979
end
8080

81+
---Convert a glob pattern to a Lua pattern
82+
---Handles: * (any non-slash), ** (any including slash), ? (single char), escapes special chars
83+
---@param glob string The glob pattern (e.g., "*.lua", "**/*.js", "dist/*")
84+
---@return string lua_pattern The converted Lua pattern
85+
local function glob_to_lua_pattern(glob)
86+
local escaped = glob:gsub("([%.%+%-%^%$%(%)%[%]%%])", "%%%1")
87+
escaped = escaped:gsub("%*%*", "\0DOUBLESTAR\0")
88+
escaped = escaped:gsub("%*", "[^/]*")
89+
escaped = escaped:gsub("%?", "[^/]")
90+
escaped = escaped:gsub("\0DOUBLESTAR\0", ".*")
91+
92+
if escaped:sub(1, 1) == "/" then
93+
escaped = "^" .. escaped:sub(2)
94+
end
95+
96+
if not glob:match("/") then
97+
escaped = escaped .. "$"
98+
else
99+
escaped = escaped .. "$"
100+
end
101+
102+
return escaped
103+
end
104+
105+
---Check if filepath matches a glob pattern (handles basename matching for patterns without /)
106+
---@param filepath string The file path to check
107+
---@param pattern string The glob pattern
108+
---@return boolean matches True if filepath matches
109+
local function matches_glob(filepath, pattern)
110+
local lua_pattern = glob_to_lua_pattern(pattern)
111+
112+
if filepath:match(lua_pattern) then
113+
return true
114+
end
115+
116+
if not pattern:match("/") then
117+
local basename = filepath:match("[^/]+$") or filepath
118+
if basename:match(lua_pattern) then
119+
return true
120+
end
121+
end
122+
123+
return false
124+
end
125+
81126
---Check if file should be excluded by patterns
82127
---@param filepath string The file path to check
83128
---@return boolean should_exclude True if file should be excluded
@@ -86,10 +131,10 @@ function Git._should_exclude_file(filepath)
86131
return false
87132
end
88133

134+
local normalized_path = filepath:gsub("\\", "/")
135+
89136
for _, pattern in ipairs(config.exclude_files) do
90-
-- Convert glob pattern to Lua pattern
91-
local lua_pattern = pattern:gsub("%*", ".*"):gsub("?", ".")
92-
if filepath:match(lua_pattern) then
137+
if matches_glob(normalized_path, pattern) then
93138
return true
94139
end
95140
end

lua/codecompanion/_extensions/gitcommit/init.lua

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ local Langs = require("codecompanion._extensions.gitcommit.langs")
66
local GitRead = require("codecompanion._extensions.gitcommit.tools.git_read")
77
local GitEdit = require("codecompanion._extensions.gitcommit.tools.git_edit")
88
local Config = require("codecompanion._extensions.gitcommit.config")
9+
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
910

1011
local M = {}
1112

@@ -390,82 +391,71 @@ return
390391
---Get buffer configuration
391392
get_buffer_config = Buffer.get_config,
392393

393-
---Access to git tool functions
394+
---Access to git tool functions (uses cached GitTool module)
394395
git_tool = {
395396
---Get git status
396397
status = function()
397-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
398398
return GitTool.get_status()
399399
end,
400400

401401
---Get git log
402402
---@param count? number Number of commits
403403
---@param format? string Log format
404404
log = function(count, format)
405-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
406405
return GitTool.get_log(count, format)
407406
end,
408407

409408
---Get git diff
410409
---@param staged? boolean Show staged changes
411410
---@param file? string Specific file
412411
diff = function(staged, file)
413-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
414412
return GitTool.get_diff(staged, file)
415413
end,
416414

417415
---Get current branch
418416
current_branch = function()
419-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
420417
return GitTool.get_current_branch()
421418
end,
422419

423420
---Get all branches
424421
---@param remote_only? boolean Show only remote branches
425422
branches = function(remote_only)
426-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
427423
return GitTool.get_branches(remote_only)
428424
end,
429425

430426
---Stage files
431427
---@param files string|table Files to stage
432428
stage = function(files)
433-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
434429
return GitTool.stage_files(files)
435430
end,
436431

437432
---Unstage files
438433
---@param files string|table Files to unstage
439434
unstage = function(files)
440-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
441435
return GitTool.unstage_files(files)
442436
end,
443437

444438
---Create new branch
445439
---@param branch_name string Name of new branch
446440
---@param checkout? boolean Whether to checkout
447441
create_branch = function(branch_name, checkout)
448-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
449442
return GitTool.create_branch(branch_name, checkout)
450443
end,
451444

452445
---Checkout branch or commit
453446
---@param target string Branch or commit to checkout
454447
checkout = function(target)
455-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
456448
return GitTool.checkout(target)
457449
end,
458450

459451
---Get remotes
460452
remotes = function()
461-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
462453
return GitTool.get_remotes()
463454
end,
464455

465456
---Show commit details
466457
---@param commit_hash? string Commit hash
467458
show = function(commit_hash)
468-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
469459
return GitTool.show_commit(commit_hash)
470460
end,
471461

@@ -474,36 +464,31 @@ return
474464
---@param line_start? number Start line
475465
---@param line_end? number End line
476466
blame = function(file_path, line_start, line_end)
477-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
478467
return GitTool.get_blame(file_path, line_start, line_end)
479468
end,
480469

481470
---Stash changes
482471
---@param message? string Stash message
483472
---@param include_untracked? boolean Include untracked files
484473
stash = function(message, include_untracked)
485-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
486474
return GitTool.stash(message, include_untracked)
487475
end,
488476

489477
---List stashes
490478
stash_list = function()
491-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
492479
return GitTool.list_stashes()
493480
end,
494481

495482
---Apply stash
496483
---@param stash_ref? string Stash reference
497484
apply_stash = function(stash_ref)
498-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
499485
return GitTool.apply_stash(stash_ref)
500486
end,
501487

502488
---Reset to commit
503489
---@param commit_hash string Commit hash
504490
---@param mode? string Reset mode (soft, mixed, hard)
505491
reset = function(commit_hash, mode)
506-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
507492
return GitTool.reset(commit_hash, mode)
508493
end,
509494

@@ -512,29 +497,25 @@ return
512497
---@param commit2? string Second commit
513498
---@param file_path? string Specific file
514499
diff_commits = function(commit1, commit2, file_path)
515-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
516500
return GitTool.diff_commits(commit1, commit2, file_path)
517501
end,
518502

519503
---Get top contributors
520504
---@param count? number Number of contributors
521505
contributors = function(count)
522-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
523506
return GitTool.get_contributors(count)
524507
end,
525508

526509
---Search commits by message
527510
---@param pattern string Search pattern
528511
---@param count? number Max results
529512
search_commits = function(pattern, count)
530-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
531513
return GitTool.search_commits(pattern, count)
532514
end,
533515

534516
---Merge a branch
535517
---@param branch string The branch to merge
536518
merge = function(branch)
537-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
538519
return GitTool.merge(branch)
539520
end,
540521

@@ -546,7 +527,6 @@ return
546527
---@param tags? boolean Push all tags
547528
---@param tag_name? string Single tag to push
548529
push = function(remote, branch, force, set_upstream, tags, tag_name)
549-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
550530
return GitTool.push(remote, branch, force, set_upstream, tags, tag_name)
551531
end,
552532

@@ -559,7 +539,6 @@ return
559539
---@return string user_msg
560540
---@return string llm_msg
561541
generate_release_notes = function(from_tag, to_tag, format)
562-
local GitTool = require("codecompanion._extensions.gitcommit.tools.git").GitTool
563542
return GitTool.generate_release_notes(from_tag, to_tag, format)
564543
end,
565544
},

lua/codecompanion/_extensions/gitcommit/tools/git.lua

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
local Git = require("codecompanion._extensions.gitcommit.git")
2+
13
local M = {}
24

35
---Git tool for CodeCompanion GitCommit extension
@@ -168,13 +170,7 @@ function GitTool.is_ignored(file)
168170
end
169171

170172
local function is_git_repo()
171-
-- Use Neovim built-in vim.fn.system instead of io.popen
172-
local ok, result = pcall(function()
173-
local cmd = "git rev-parse --is-inside-work-tree"
174-
local output = vim.fn.system(cmd)
175-
return vim.v.shell_error == 0 and output:match("true") ~= nil
176-
end)
177-
return ok and result or false
173+
return Git.is_repository()
178174
end
179175

180176
local function execute_git_command(cmd)

0 commit comments

Comments
 (0)