Skip to content

Commit 7783714

Browse files
committed
feat(gitcommit): skip auto-generation on amend commits
- add skip_auto_generate_on_amend config option - improve amend detection by checking COMMIT_EDITMSG content - prevent auto-generation if editing an existing commit message - update buffer, config, and types to support new option
1 parent 2b4afbe commit 7783714

File tree

4 files changed

+67
-26
lines changed

4 files changed

+67
-26
lines changed

lua/codecompanion/_extensions/gitcommit/buffer.lua

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ local Generator = require("codecompanion._extensions.gitcommit.generator")
55
---@class CodeCompanion.GitCommit.Buffer
66
local Buffer = {}
77

8-
---@type CodeCompanion.GitCommit.ExtensionOpts.Buffer Default configuration
98
local default_config = {
109
enabled = true,
1110
keymap = "<leader>gc",
1211
auto_generate = false,
1312
auto_generate_delay = 100, -- Default delay in ms
13+
skip_auto_generate_on_amend = true, -- Skip auto-generation during git commit --amend
1414
}
1515

1616
---@type table Current configuration
@@ -32,19 +32,20 @@ function Buffer.setup(opts)
3232
Buffer._setup_gitcommit_keymap(event.buf)
3333

3434
if config.auto_generate then
35-
-- This autocommand will trigger once when the user enters the gitcommit window.
36-
-- This avoids race conditions with plugins like neogit that manage multiple windows.
35+
-- Auto-generation autocommand triggers once when entering gitcommit window
36+
-- This avoids race conditions with plugins like neogit that manage multiple windows
37+
-- Skip auto-generation during git amend to preserve user's intent to modify existing commit
3738
vim.api.nvim_create_autocmd("WinEnter", {
3839
buffer = event.buf,
3940
once = true,
4041
callback = function(args)
41-
-- Defer the execution to ensure other plugins (like neogit) have finished their UI setup.
42+
-- Defer execution to ensure other plugins (like neogit) have finished UI setup
4243
vim.defer_fn(function()
4344
if not vim.api.nvim_buf_is_valid(args.buf) then
4445
return
4546
end
4647

47-
-- Check if buffer already has a commit message (e.g., during amend)
48+
-- Check if buffer already has a commit message
4849
local lines = vim.api.nvim_buf_get_lines(args.buf, 0, -1, false)
4950
local has_message = false
5051
for _, line in ipairs(lines) do
@@ -54,9 +55,13 @@ function Buffer.setup(opts)
5455
end
5556
end
5657

57-
if not has_message then
58-
Buffer._generate_and_insert_commit_message(args.buf)
59-
end
58+
-- Skip auto-generation in the following cases:
59+
-- 1. Buffer already has a commit message
60+
-- 2. We are in a git amend operation (user may want to keep existing message)
61+
local should_skip_amend = config.skip_auto_generate_on_amend and Git.is_amending()
62+
if not has_message and not should_skip_amend then
63+
Buffer._generate_and_insert_commit_message(args.buf)
64+
end
6065
end, config.auto_generate_delay)
6166
end,
6267
desc = "Auto-generate GitCommit message",

lua/codecompanion/_extensions/gitcommit/config.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ M.default_opts = {
2323
keymap = "<leader>gc",
2424
auto_generate = true,
2525
auto_generate_delay = 200,
26+
skip_auto_generate_on_amend = true, -- Skip auto-generation during git commit --amend
2627
},
2728
add_slash_command = true,
2829
add_git_tool = true,

lua/codecompanion/_extensions/gitcommit/git.lua

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -133,22 +133,57 @@ function Git.is_amending()
133133
return false
134134
end
135135

136-
-- Check if COMMIT_EDITMSG exists and we're in a rebase/merge state
137-
local git_dir = vim.fn.system("git rev-parse --git-dir"):gsub("\n", "")
138-
if vim.v.shell_error ~= 0 then
139-
return false
140-
end
141-
142-
-- Check for COMMIT_EDITMSG file which indicates we're editing a commit
143-
local commit_editmsg = git_dir .. "/COMMIT_EDITMSG"
144-
local stat = vim.uv.fs_stat(commit_editmsg)
145-
if not stat then
146-
return false
147-
end
148-
149-
-- Additional check: see if we have HEAD commit (not initial commit)
150-
vim.fn.system("git rev-parse --verify HEAD")
151-
return vim.v.shell_error == 0
136+
-- Check if we're in an amend scenario by examining the COMMIT_EDITMSG content
137+
-- During amend, git pre-populates COMMIT_EDITMSG with the previous commit message
138+
local git_dir = vim.trim(vim.fn.system("git rev-parse --git-dir"))
139+
if vim.v.shell_error ~= 0 then
140+
return false
141+
end
142+
143+
-- Use platform-appropriate path separator
144+
local path_sep = package.config:sub(1, 1)
145+
local commit_editmsg = git_dir .. path_sep .. "COMMIT_EDITMSG"
146+
local stat = vim.uv.fs_stat(commit_editmsg)
147+
if not stat then
148+
return false
149+
end
150+
151+
-- Additional check: verify HEAD commit exists (not initial commit)
152+
local redirect = (vim.uv.os_uname().sysname == "Windows_NT") and " 2>nul" or " 2>/dev/null"
153+
vim.fn.system("git rev-parse --verify HEAD" .. redirect)
154+
if vim.v.shell_error ~= 0 then
155+
return false
156+
end
157+
158+
-- Read COMMIT_EDITMSG content and check if it contains a previous commit message
159+
-- During amend, git pre-populates this file with the previous commit message
160+
local fd = vim.uv.fs_open(commit_editmsg, "r", 438)
161+
if not fd then
162+
return false
163+
end
164+
165+
local content = vim.uv.fs_read(fd, stat.size, 0)
166+
vim.uv.fs_close(fd)
167+
168+
if not content then
169+
return false
170+
end
171+
172+
-- Check if there's non-comment content in COMMIT_EDITMSG
173+
-- During amend, this indicates we're editing an existing commit
174+
local lines = vim.split(content, "\n")
175+
local has_existing_message = false
176+
for _, line in ipairs(lines) do
177+
local trimmed = vim.trim(line)
178+
-- Skip empty lines and comment lines (starting with #)
179+
if trimmed ~= "" and not trimmed:match("^#") then
180+
has_existing_message = true
181+
break
182+
end
183+
end
184+
185+
-- If COMMIT_EDITMSG has existing content and HEAD exists, likely an amend
186+
return has_existing_message
152187
end)
153188

154189
return ok and result or false

lua/codecompanion/_extensions/gitcommit/types.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
---@field enabled boolean Enable buffer-specific keymap for git commit
99
---@field keymap string Keymap for generating commit message in git commit buffer
1010
---@field auto_generate? boolean Automatically generate commit message on entering gitcommit buffer
11-
---@field auto_generate_delay? number Delay in ms before auto-generating to avoid race conditions
1211

13-
---@field add_slash_command? boolean Add /gitcommit slash command to chat buffer
12+
---@field skip_auto_generate_on_amend? boolean Skip auto-generation during git commit --amend operations
13+
1414
---@field buffer? CodeCompanion.GitCommit.ExtensionOpts.Buffer Enable buffer-specific keymap for git commit
1515
---@field adapter? string? The adapter to use for generation
1616
---@field model? string? The model of the adapter to use for generation

0 commit comments

Comments
 (0)