Skip to content

Commit 1e4b207

Browse files
wesmclaude
andauthored
Move rebase detection and quiet mode into roborev enqueue (#10)
Old hooks automatically get new behavior - no reinstall required. Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent f095466 commit 1e4b207

File tree

2 files changed

+49
-22
lines changed

2 files changed

+49
-22
lines changed

cmd/roborev/main.go

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -262,14 +262,7 @@ func initCmd() *cobra.Command {
262262
hookPath := filepath.Join(hooksDir, "post-commit")
263263
hookContent := `#!/bin/sh
264264
# RoboRev post-commit hook - auto-reviews every commit
265-
266-
# Skip during rebase to avoid reviewing every replayed commit
267-
git_dir=$(git rev-parse --git-dir 2>/dev/null)
268-
if [ -d "$git_dir/rebase-merge" ] || [ -d "$git_dir/rebase-apply" ]; then
269-
exit 0
270-
fi
271-
272-
roborev enqueue --sha HEAD 2>/dev/null &
265+
roborev enqueue --quiet &
273266
`
274267
// Ensure hooks directory exists
275268
if err := os.MkdirAll(hooksDir, 0755); err != nil {
@@ -368,6 +361,7 @@ func enqueueCmd() *cobra.Command {
368361
repoPath string
369362
sha string
370363
agent string
364+
quiet bool
371365
)
372366

373367
cmd := &cobra.Command{
@@ -381,11 +375,6 @@ Examples:
381375
roborev enqueue abc123 def456 # Review range from abc123 to def456 (inclusive)
382376
`,
383377
RunE: func(cmd *cobra.Command, args []string) error {
384-
// Ensure daemon is running
385-
if err := ensureDaemon(); err != nil {
386-
return err
387-
}
388-
389378
// Default to current directory
390379
if repoPath == "" {
391380
repoPath = "."
@@ -394,9 +383,25 @@ Examples:
394383
// Get repo root
395384
root, err := git.GetRepoRoot(repoPath)
396385
if err != nil {
386+
if quiet {
387+
return nil // Silent exit in quiet mode
388+
}
397389
return fmt.Errorf("not a git repository: %w", err)
398390
}
399391

392+
// Skip during rebase to avoid reviewing every replayed commit
393+
if git.IsRebaseInProgress(root) {
394+
return nil // Silent exit
395+
}
396+
397+
// Ensure daemon is running
398+
if err := ensureDaemon(); err != nil {
399+
if quiet {
400+
return nil
401+
}
402+
return err
403+
}
404+
400405
var gitRef string
401406
if len(args) >= 2 {
402407
// Range: START END -> START^..END (inclusive)
@@ -430,14 +435,17 @@ Examples:
430435
var job storage.ReviewJob
431436
json.Unmarshal(body, &job)
432437

433-
fmt.Printf("Enqueued job %d for %s (agent: %s)\n", job.ID, shortRef(job.GitRef), job.Agent)
438+
if !quiet {
439+
fmt.Printf("Enqueued job %d for %s (agent: %s)\n", job.ID, shortRef(job.GitRef), job.Agent)
440+
}
434441
return nil
435442
},
436443
}
437444

438445
cmd.Flags().StringVar(&repoPath, "repo", "", "path to git repository (default: current directory)")
439446
cmd.Flags().StringVar(&sha, "sha", "HEAD", "commit SHA to review (used when no positional args)")
440447
cmd.Flags().StringVar(&agent, "agent", "", "agent to use (codex, claude-code, gemini, copilot, opencode)")
448+
cmd.Flags().BoolVarP(&quiet, "quiet", "q", false, "suppress output (for use in hooks)")
441449

442450
return cmd
443451
}
@@ -733,14 +741,7 @@ func installHookCmd() *cobra.Command {
733741

734742
hookContent := `#!/bin/sh
735743
# RoboRev post-commit hook - auto-reviews every commit
736-
737-
# Skip during rebase to avoid reviewing every replayed commit
738-
git_dir=$(git rev-parse --git-dir 2>/dev/null)
739-
if [ -d "$git_dir/rebase-merge" ] || [ -d "$git_dir/rebase-apply" ]; then
740-
exit 0
741-
fi
742-
743-
roborev enqueue --sha HEAD 2>/dev/null &
744+
roborev enqueue --quiet &
744745
`
745746

746747
if err := os.WriteFile(hookPath, []byte(hookContent), 0755); err != nil {

internal/git/git.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package git
33
import (
44
"bytes"
55
"fmt"
6+
"os"
67
"os/exec"
78
"path/filepath"
89
"strings"
@@ -217,6 +218,31 @@ func GetRangeStart(repoPath, rangeRef string) (string, error) {
217218
return ResolveSHA(repoPath, start)
218219
}
219220

221+
// IsRebaseInProgress returns true if a rebase operation is in progress
222+
func IsRebaseInProgress(repoPath string) bool {
223+
cmd := exec.Command("git", "rev-parse", "--git-dir")
224+
cmd.Dir = repoPath
225+
226+
out, err := cmd.Output()
227+
if err != nil {
228+
return false
229+
}
230+
231+
gitDir := strings.TrimSpace(string(out))
232+
if !filepath.IsAbs(gitDir) {
233+
gitDir = filepath.Join(repoPath, gitDir)
234+
}
235+
236+
// Check for rebase-merge (interactive rebase) or rebase-apply (git am, regular rebase)
237+
for _, dir := range []string{"rebase-merge", "rebase-apply"} {
238+
if info, err := os.Stat(filepath.Join(gitDir, dir)); err == nil && info.IsDir() {
239+
return true
240+
}
241+
}
242+
243+
return false
244+
}
245+
220246
// GetHooksPath returns the path to the hooks directory, respecting core.hooksPath
221247
func GetHooksPath(repoPath string) (string, error) {
222248
cmd := exec.Command("git", "rev-parse", "--git-path", "hooks")

0 commit comments

Comments
 (0)