GitWhisper seamlessly integrates with your configured Git editor, allowing you to review and edit AI-generated commit messages before finalizing them.
How Editor Integration Works
When using GitWhisper’s interactive confirmation mode, you can choose to edit the generated commit message. GitWhisper opens your configured Git editor with the message pre-filled, just like a standard git commit workflow.
From git_utils.dart:314-377, the implementation:
static Future<String?> openGitEditor(String initialMessage) async {
// Get the configured Git editor
final editorResult = await Process.run('git', ['var', 'GIT_EDITOR']);
String editor;
if (editorResult.exitCode == 0 &&
(editorResult.stdout as String).trim().isNotEmpty) {
editor = (editorResult.stdout as String).trim();
} else {
// Fall back to EDITOR environment variable or vi
editor = Platform.environment['EDITOR'] ?? 'vi';
}
// Create a temporary file for the commit message
final tempDir = Directory.systemTemp;
final tempFile = File(
'${tempDir.path}/GITWHISPER_EDITMSG_${DateTime.now().millisecondsSinceEpoch}');
try {
// Write the initial message to the temp file
await tempFile.writeAsString(initialMessage);
// Open the editor
final process = await Process.start(
'/bin/sh',
['-c', '$editor "${tempFile.path}"'],
mode: ProcessStartMode.inheritStdio,
);
final exitCode = await process.exitCode;
if (exitCode != 0) {
return null;
}
// Read the edited message
final editedMessage = await tempFile.readAsString();
// Clean up: remove comment lines (lines starting with #) and trim
final cleanedLines = editedMessage
.split('\n')
.where((line) => !line.trimLeft().startsWith('#'))
.toList();
final cleaned = cleanedLines.join('\n').trim();
return cleaned.isNotEmpty ? cleaned : null;
} finally {
// Clean up the temp file
if (await tempFile.exists()) {
await tempFile.delete();
}
}
}
Interactive Confirmation Workflow
Enable interactive confirmation to get the option to edit messages:
# Enable confirmation for this commit
gw commit --confirm
# Use short flag
gw commit -c
When enabled, GitWhisper presents you with options:
---------------------------------
feat: ✨ Add user authentication
---------------------------------
What would you like to do with this commit message?
[commit] commit
[edit] edit
[retry] retry
[discard] discard
Choose edit to open your Git editor.
Configuring Your Git Editor
GitWhisper respects your Git editor configuration in this order:
- Git’s
core.editor configuration
$EDITOR environment variable
- Default fallback:
vi
Setting Your Git Editor
VS Code
git config --global core.editor "code --wait"
Vim
git config --global core.editor "vim"
Nano
git config --global core.editor "nano"
Emacs
git config --global core.editor "emacs"
Sublime Text
git config --global core.editor "subl -n -w"
Atom
git config --global core.editor "atom --wait"
Neovim
git config --global core.editor "nvim"
The --wait flag (or equivalent) is important for GUI editors. It tells the editor to wait until you close the file before returning control to GitWhisper.
Editor Workflow Example
Here’s a complete workflow using editor integration:
# 1. Stage your changes
git add .
# 2. Generate commit with confirmation
gw commit --confirm
# 3. GitWhisper generates a message:
# feat: ✨ Add user authentication system
# 4. Choose to edit
# [E] Edit commit message
# 5. Your editor opens with:
# feat: ✨ Add user authentication system
#
# You can now edit the message manually
# 6. Save and close the editor
# 7. GitWhisper shows the updated message and asks for confirmation again
Message Cleanup
GitWhisper automatically cleans up the edited message:
- Removes comment lines: Lines starting with
# are stripped (like standard git commit)
- Trims whitespace: Leading and trailing whitespace is removed
- Validates content: Empty messages are rejected
From git_utils.dart:362-369:
// Clean up: remove comment lines (lines starting with #) and trim
final cleanedLines = editedMessage
.split('\n')
.where((line) => !line.trimLeft().startsWith('#'))
.toList();
final cleaned = cleanedLines.join('\n').trim();
Advanced Editing Scenarios
Adding Multi-Line Descriptions
While GitWhisper generates concise single-line commits, you can add detailed multi-line descriptions in the editor:
feat: ✨ Add user authentication system
Implemented JWT-based authentication with the following features:
- Login and registration endpoints
- Token refresh mechanism
- Role-based access control
- Password hashing with bcrypt
Closes #123
Editing with Prefixes
When using ticket prefixes, the prefix is already included in the generated message:
gw commit --prefix "JIRA-456" --confirm
# Generated message:
JIRA-456 -> feat: ✨ Add dashboard
# You can edit to:
JIRA-456 -> feat: ✨ Add user analytics dashboard
Implemented comprehensive analytics dashboard with:
- Real-time user metrics
- Customizable date ranges
- Export to CSV functionality
Retry Options
If you’re not satisfied with the edited message, you can retry:
What would you like to do with this commit message?
[commit] commit
[edit] edit
[retry] retry ← Choose this
[discard] discard
How would you like to retry?
[same model] same model
[different model] different model
[add context] add context
This generates a fresh message that you can edit again.
Terminal-Based Editors
GitWhisper works seamlessly with terminal-based editors:
Vim/Neovim
# The file opens in vim/nvim
# Press 'i' to enter insert mode
# Edit the message
# Press 'Esc' then ':wq' to save and exit
Nano
# The file opens in nano
# Edit the message
# Press 'Ctrl+X', then 'Y', then 'Enter' to save and exit
Emacs
# The file opens in emacs
# Edit the message
# Press 'Ctrl+X Ctrl+S' to save
# Press 'Ctrl+X Ctrl+C' to exit
GUI Editor Best Practices
Use --wait flag: Always configure GUI editors with the --wait flag so they block until you close the file:git config --global core.editor "code --wait"
Close the tab/window: After editing, close the specific tab or window (not the entire editor) to signal completion.
Canceling Edits
You can cancel the edit in several ways:
- Empty the file: Delete all content and save (GitWhisper rejects empty messages)
- Exit without saving: Use your editor’s quit-without-saving command
- Choose discard: After editing, you can still choose “discard” in the confirmation menu
Combining with Other Features
Editor + Auto-Push
gw commit --confirm --auto-push
# Edit the message, then it's committed and pushed automatically
gw commit --confirm --tag v1.0.0
# Edit the message, commit is created with tag
Editor + Prefix
gw commit --confirm --prefix "PROJ-123"
# Edit the prefixed message
Best Practices
Use confirmation mode for important commits: Enable --confirm for releases, major features, or any commit you want to carefully review.
Set a comfortable editor: Choose an editor you’re familiar with. Don’t use vi if you prefer VS Code or nano.
Keep conventional format: When editing, maintain the conventional commit format (type: emoji description) for consistency.
Editor integration is non-blocking: GitWhisper waits for you to finish editing. Take your time to craft the perfect commit message.
Troubleshooting
Editor doesn’t open
Check your Git editor configuration:
git config --global core.editor
echo $EDITOR
Set it if not configured:
git config --global core.editor "nano"
Ensure you’re using the --wait flag:
# Wrong
git config --global core.editor "code"
# Correct
git config --global core.editor "code --wait"
Changes aren’t saved
Make sure you’re using the save command for your editor:
- Vim:
:wq or ZZ
- Nano:
Ctrl+X, then Y
- Emacs:
Ctrl+X Ctrl+S
- VS Code:
Ctrl+S (Cmd+S on Mac), then close the tab