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

Commit 4ea75b0

Browse files
committed
refactor(git): improve cross-platform compatibility and simplify command execution
- use OS-specific path separator for .git directory checks - redirect stderr appropriately for Windows and Unix in git commands - replace io.popen with vim.fn.system for git command execution - pass commit message via stdin instead of temporary file - handle head equivalent for get_contributors on Windows using PowerShell - improve error handling for git command execution
1 parent df82b4e commit 4ea75b0

2 files changed

Lines changed: 26 additions & 39 deletions

File tree

lua/codecompanion/_extensions/gitcommit/git.lua

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ end
7777
function Git.is_repository()
7878
-- First check for .git directory in current and parent directories
7979
local function check_git_dir(path)
80-
local git_path = path .. "/.git"
80+
local sep = package.config:sub(1, 1)
81+
local git_path = path .. sep .. ".git"
8182
local stat = vim.uv.fs_stat(git_path)
8283
return stat ~= nil
8384
end
@@ -99,7 +100,8 @@ function Git.is_repository()
99100
end
100101

101102
-- Fallback to git command if filesystem check fails
102-
local cmd = "git rev-parse --is-inside-work-tree"
103+
local redirect = (vim.loop.os_uname().sysname == "Windows_NT") and " 2>nul" or " 2>/dev/null"
104+
local cmd = "git rev-parse --is-inside-work-tree" .. redirect
103105
local result = vim.fn.system(cmd)
104106
return vim.v.shell_error == 0 and vim.trim(result) == "true"
105107
end
@@ -224,31 +226,17 @@ function Git.commit_changes(message)
224226
return false
225227
end
226228

227-
-- Create temporary file for commit message
228-
local temp_file = vim.fn.tempname()
229-
local file = io.open(temp_file, "w")
230-
if not file then
231-
vim.notify("Failed to create temporary file for commit message", vim.log.levels.ERROR)
232-
return false
233-
end
234-
235-
file:write(message)
236-
file:close()
237-
238-
-- Execute appropriate git commit command
229+
-- 直接通过 stdin 传递 commit message,无需临时文件
239230
local cmd
240231
if Git.is_amending() then
241-
cmd = string.format("git commit --amend -F %s", vim.fn.shellescape(temp_file))
232+
cmd = "git commit --amend -F -"
242233
else
243-
cmd = string.format("git commit -F %s", vim.fn.shellescape(temp_file))
234+
cmd = "git commit -F -"
244235
end
245236

246-
local result = vim.fn.system(cmd)
237+
local result = vim.fn.system(cmd, message)
247238
local exit_code = vim.v.shell_error
248239

249-
-- Clean up temporary file
250-
os.remove(temp_file)
251-
252240
if exit_code == 0 then
253241
local action = Git.is_amending() and "amended" or "committed"
254242
vim.notify(string.format("Successfully %s changes!", action), vim.log.levels.INFO)

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

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,10 @@ local GitTool = {
1111
---Check if we're in a git repository
1212
---@return boolean
1313
local function is_git_repo()
14-
local handle = io.popen("git rev-parse --is-inside-work-tree 2>nul")
15-
if not handle then
16-
return false
17-
end
18-
19-
local result = handle:read("*a")
20-
handle:close()
21-
22-
return result:match("true") ~= nil
14+
-- 使用 Neovim 内置 vim.fn.system 代替 io.popen
15+
local cmd = "git rev-parse --is-inside-work-tree"
16+
local result = vim.fn.system(cmd)
17+
return vim.v.shell_error == 0 and result:match("true") ~= nil
2318
end
2419

2520
---Execute git command safely
@@ -30,15 +25,13 @@ local function execute_git_command(cmd)
3025
return false, "Not in a git repository"
3126
end
3227

33-
local handle = io.popen(cmd .. " 2>&1")
34-
if not handle then
35-
return false, "Failed to execute command"
36-
end
37-
38-
local output = handle:read("*a")
39-
local success = handle:close()
28+
local output = vim.fn.system(cmd)
29+
local exit_code = vim.v.shell_error
4030

41-
return success, output or ""
31+
if exit_code ~= 0 or (output and output:match("fatal: ")) then
32+
return false, output
33+
end
34+
return true, output or ""
4235
end
4336

4437
---Get git status
@@ -243,8 +236,14 @@ end
243236
---@return boolean success, string output
244237
function GitTool.get_contributors(count)
245238
count = count or 10
246-
local cmd = string.format("git shortlog -sn | head -%d", count)
247-
return execute_git_command(cmd)
239+
local head_cmd
240+
if vim.loop.os_uname().sysname == "Windows_NT" then
241+
-- Use PowerShell for head equivalent
242+
head_cmd = string.format("git shortlog -sn | Select-Object -First %d", count)
243+
else
244+
head_cmd = string.format("git shortlog -sn | head -%d", count)
245+
end
246+
return execute_git_command(head_cmd)
248247
end
249248

250249
---Search commits by message

0 commit comments

Comments
 (0)