-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add autocommit commit messages #4049
base: master
Are you sure you want to change the base?
Conversation
WIP(copilot): support for login with device code WIP(copilot): separate copilot client_id into const variable WIP(copilot): load AccessToken from cache WIP(copilot): login flow and chat
…ot's access token" This reverts commit 98073dc. The reason being, I just found out we can use the `RerfreshToken` from the `~/.config/github-copilot/hosts.json`.
I was just looking at a way to do that using custom commands, but there is no good way to use the current prompts to do that ... |
I have contributed an improved version of this implementation to mods (a way of using LLMs in the CLI).
But there are some interesting considerations like tokenization, we might need to discuss. I'm working in a POC. In the meantime, I hacked together a custom command integration it with LazyGit and mods that already addresses all these issues. If someone else finds it useful, here is my workflow: Important considerations
How to useFlow
Shortcuts Requirements
apis:
copilot:
base-url: https://api.githubcopilot.com
models:
gpt-4o-2024-05-13:
aliases: ["4o-2024", "4o", "gpt-4o"]
max-input-chars: 392000
gpt-4:
aliases: ["4"]
max-input-chars: 24500
gpt-3.5-turbo:
aliases: ["35t"]
max-input-chars: 12250
o1-preview-2024-09-12:
aliases: ["o1-preview", "o1p"]
max-input-chars: 128000
o1-mini-2024-09-12:
aliases: ["o1-mini", "o1m"]
max-input-chars: 128000
claude-3.5-sonnet:
aliases: ["claude3.5-sonnet", "sonnet-3.5", "claude-3-5-sonnet"]
max-input-chars: 680000 Custom commands
customCommands:
- key: '<c-g>'
context: 'global'
description: 'AI Commit Message'
loadingText: 'Generating commit message'
prompts:
- type: 'menu'
title: 'AI Commit Options'
key: 'action'
options:
- name: 'Generate'
description: 'Generate new commit message'
value: 'generate'
- name: 'Commit'
description: 'Use current message'
value: 'commit'
- name: 'View'
description: 'View current message'
value: 'view'
- name: 'Clear'
description: 'Remove current message'
value: 'clear'
command: |
{{if eq .Form.action "generate"}}
gen-commit-lazygit | tee /tmp/lazygit-commit-msg
{{else if eq .Form.action "view"}}
test -f /tmp/lazygit-commit-msg && cat /tmp/lazygit-commit-msg || echo "No commit message generated yet"
{{else if eq .Form.action "clear"}}
test -f /tmp/lazygit-commit-msg && rm /tmp/lazygit-commit-msg || echo "No commit message file exists"
{{else}}
git commit -m "$(cat /tmp/lazygit-commit-msg)" && rm /tmp/lazygit-commit-msg
{{end}}
showOutput: true
- key: '<c-N>'
context: 'global'
description: 'Refine commit message'
prompts:
- type: 'input'
title: 'Enter feedback for refinement'
key: 'feedback'
command: "cat /tmp/lazygit-commit-msg | mods -q -C \"feedback: {{.Form.feedback}}\""
showOutput: true Message generator
#!/bin/bash
base_prompt="Create a conventional commit message for these changes. If there are multiple features or changes, list them with bullet points ('-') on separate lines. For scope, as prefix: use 'backend' for Go or other backend files, 'frontend' for Svelte or other frontend specific files, and if both are changed use the general feature scope instead. Eg: 'feat(backend/git): add new API endpoint'. If previous commits don't follow conventional format, maintain their style instead. Use the same idiom for the commit message as the previous commits"
if [ "$1" = "wip" ]; then
prompt="$base_prompt Prefix with wip() to indicate work in progress."
else
prompt="$base_prompt"
fi
context=$(
echo -e "=== Last commits ===\n"
git log -5 | sed 's/[^[:print:]]//g'
echo -e "\n=== Staged Changes ===\n"
changed_files=$(git diff --staged --name-only | sed 's/[^[:print:]]//g')
staged_changes=""
# Ignore some changes to avoid noise
# lock files, binary, in those cases, just send their names
# Define array of ignored file patterns
ignore_patterns=(".lock" ".bin" ".exe" ".dll" ".so" ".jpg" ".jpeg" ".png" ".gif" ".bmp" ".ico" ".svg" ".webp" ".mp4" ".mov" ".avi")
# Loop through each changed file
while IFS= read -r file; do
# Check if file matches any ignore pattern
should_ignore=false
for pattern in "${ignore_patterns[@]}"; do
if [[ "$file" == *"$pattern"* ]]; then
should_ignore=true
break
fi
done
if [ "$should_ignore" = true ]; then
# Just append filename for ignored files
staged_changes+="$(echo "$file" | sed 's/[^[:print:]]//g')\n"
else
# Append full diff for non-ignored files
diff=$(git diff --cached "$file" | sed 's/[^[:print:]]//g')
staged_changes+="$diff\n"
fi
done <<< "$changed_files"
# Translit to utf-8
staged_changes=$(echo "$staged_changes" | iconv -c -f utf-8 -t utf-8 | sed 's/[^[:print:]]//g')
echo -e "$staged_changes"
)
full_prompt=\
''"$prompt Just the commit message, multiple
lines if necessary . Just the commit message NOTHING ELSE. If no data is shown
or if you only see file paths with no diff content making it difficult to
understand the changes, just write the '\'\'\'' (empty string) character: '\'\'\''
<gencommit_prompt_context>
$context
</gencommit_prompt_context>
"''
message=$(echo $full_prompt | mods -q)
echo -e "$message" |
I'll try this next week, looks like this could work. |
PR Description
Please check if the PR fulfills these requirements
go generate ./...
)This PR adds the ability to generate commit messages using AI, primarily through GitHub Copilot integration, with potential support for OpenAI-compatible APIs.
Background
This aims to implement #3763, adding AI-assisted commit message generation similar to VS Code's Copilot feature.
While the GitHub Copilot API is not officially public, the implementation doesn't appear to violate the terms of service. However, I understand introducing AI features like this may be a significant direction change for the project, so I'm open to discussion about whether this aligns with lazygit's goals.
This initial scope focuses solely on commit message generation to keep the implementation focused and manageable. Future possibilities like generating release notes, improving squash commit messages, or crafting PR descriptions could be considered later once this core functionality is proven.
The implementation is based on the flow from
Zed
andCopilot.lua
.I would appreciate some feedback on both the implementation approach and whether this feature could be added to the project.
Current Implementation Status
This is very much a work in progress. Just a proof of concept at the moment
Proposed configuration