1
0
Fork 0
mirror of https://github.com/imjasonh/cnotes synced 2026-07-11 10:21:44 +00:00
cnotes/internal/handlers/gitrebase.go
Jason Hall 7b6cdffa8a
Add git notes preservation system with backup/restore functionality
- Added WarnAboutGitNotesLoss hook that warns before destructive git operations
- Implemented comprehensive backup/restore system for conversation notes
- Added CLI commands: hooks notes backup/restore/list
- Configured git to automatically copy notes during rebase operations
- Created backup.go with full notes backup and restoration functionality

This ensures conversation context is never lost during rebasing, squashing, or other destructive git operations.
2025-07-21 12:39:13 -04:00

65 lines
2.1 KiB
Go

package handlers
import (
"context"
"fmt"
"log/slog"
"strings"
"github.com/imjasonh/hooks/internal/hooks"
)
func init() {
hooks.RegisterHook(hooks.EventPreToolUse, "Bash", WarnAboutGitNotesLoss)
}
// WarnAboutGitNotesLoss warns users about potential git notes loss during destructive operations
func WarnAboutGitNotesLoss(ctx context.Context, input hooks.HookInput) (hooks.HookOutput, error) {
bashInput, err := input.GetBashInput()
if err != nil {
return hooks.HookOutput{Decision: "approve"}, nil
}
command := strings.TrimSpace(bashInput.Command)
// Check for destructive git operations that might lose notes
destructiveOperations := []struct {
pattern string
warning string
}{
{
pattern: "git rebase",
warning: "⚠️ Git rebase can lose conversation notes attached to commits. Consider:\n" +
" • Run 'git notes --ref=claude-conversations list' to see which commits have notes\n" +
" • Use 'git -c notes.rewrite.mode=copy rebase' to preserve notes\n" +
" • Or manually backup notes before rebasing with 'git notes --ref=claude-conversations show <commit>'",
},
{
pattern: "git reset --hard",
warning: "⚠️ Hard reset will lose commits and their conversation notes permanently.\n" +
" • Consider using 'git reset --soft' or 'git reset --mixed' instead\n" +
" • Backup important notes first with 'git notes --ref=claude-conversations show <commit>'",
},
{
pattern: "git commit --amend",
warning: "⚠️ Amending commits changes their hash and may lose conversation notes.\n" +
" • Notes are attached to the original commit hash\n" +
" • Consider creating a new commit instead of amending",
},
}
for _, op := range destructiveOperations {
if strings.Contains(command, op.pattern) {
slog.Info("warning user about potential git notes loss",
"command", command,
"operation", op.pattern)
return hooks.HookOutput{
Decision: "approve", // Don't block, just warn
AdditionalContext: fmt.Sprintf("\n%s\n\nDo you want to proceed with this operation?", op.warning),
}, nil
}
}
return hooks.HookOutput{Decision: "approve"}, nil
}