Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 60 additions & 2 deletions src/git/refs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,51 @@ pub fn grep_ai_notes(repo: &Repository, pattern: &str) -> Result<Vec<String>, Gi
// If we have multiple results, sort by commit date (newest first)
if shas.len() > 1 {
let sha_vec: Vec<String> = shas.into_iter().collect();

eprintln!("[DEBUG] Found {} commits with pattern '{}' in git notes", sha_vec.len(), pattern);
for sha in &sha_vec {
eprintln!("[DEBUG] - {}", sha);
}

// FILTER OUT NON-EXISTENT COMMITS using git cat-file -e
let existing_shas: Vec<String> = sha_vec
.into_iter()
.filter(|sha| {
let mut args = repo.global_args_for_exec();
args.push("cat-file".to_string());
args.push("-e".to_string());
args.push(sha.clone());

let exists = exec_git(&args).is_ok();
if !exists {
eprintln!("[DEBUG] Filtering out non-existent commit: {}", sha);
}
exists
})
.collect();

eprintln!("[DEBUG] After filtering: {} existing commits", existing_shas.len());
for sha in &existing_shas {
eprintln!("[DEBUG] - {}", sha);
}
Comment on lines +329 to +354
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Debug output unconditionally printed to stderr in production

The new code uses raw eprintln! statements to print debug messages, but the rest of the codebase uses debug_log() which only prints when debug mode is enabled via is_debug_enabled().

Root Cause and Impact

The function grep_ai_notes now contains multiple eprintln! calls at lines 329-331, 345, 351-353, and 394 that will always print debug output to stderr, regardless of whether debug mode is enabled.

For comparison, other functions in the same file use debug_log() (lines 277-280, 292) which is conditional:

// From src/utils.rs
pub fn debug_log(msg: &str) {
    if is_debug_enabled() {
        eprintln!("\x1b[1;33m[git-ai]\x1b[0m {}", msg);
    }
}

Impact: In production, users will see debug messages like [DEBUG] Found X commits with pattern 'Y' in git notes printed to stderr every time grep_ai_notes is called with multiple results. This pollutes the terminal output and may confuse users or break scripts that parse stderr.

Prompt for agents
Replace all eprintln! calls in the grep_ai_notes function with debug_log calls to match the existing pattern in the codebase. The debug_log function is already imported at line 5 of src/git/refs.rs.

Specifically, replace:
- Line 329: eprintln!("[DEBUG] Found {} commits...") -> debug_log(&format!("Found {} commits..."))
- Lines 330-332: The for loop with eprintln! -> wrap in debug_log or remove
- Line 345: eprintln!("[DEBUG] Filtering out...") -> debug_log(&format!("Filtering out..."))
- Lines 351-354: eprintln! calls -> debug_log calls
- Line 394: eprintln!("[DEBUG] Single commit...") -> debug_log(&format!("Single commit..."))

Note: The [DEBUG] prefix is not needed when using debug_log since it already adds a [git-ai] prefix.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


if existing_shas.is_empty() {
return Err(GitAiError::Generic(
"No existing commits found in git notes for pattern".to_string()
));
}

if existing_shas.len() == 1 {
return Ok(existing_shas);
}

// Sort only existing commits by date
let mut args = repo.global_args_for_exec();
args.push("log".to_string());
args.push("--format=%H".to_string());
args.push("--date-order".to_string());
args.push("--no-walk".to_string());
for sha in &sha_vec {
for sha in &existing_shas {
args.push(sha.clone());
}

Expand All @@ -340,6 +379,25 @@ pub fn grep_ai_notes(repo: &Repository, pattern: &str) -> Result<Vec<String>, Gi

Ok(stdout.lines().map(|s| s.to_string()).collect())
} else {
Ok(shas.into_iter().collect())
// Single or no result - verify it exists
let sha_vec: Vec<String> = shas.into_iter().collect();
if !sha_vec.is_empty() {
let sha = &sha_vec[0];
let mut args = repo.global_args_for_exec();
args.push("cat-file".to_string());
args.push("-e".to_string());
args.push(sha.clone());

if exec_git(&args).is_ok() {
Ok(sha_vec)
} else {
eprintln!("[DEBUG] Single commit {} does not exist", sha);
Err(GitAiError::Generic(
"Commit referenced in git notes does not exist".to_string()
))
}
} else {
Ok(sha_vec)
}
}
}