Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Oct 5, 2025

  • Analyze current codebase structure and understand what needs to be extracted
  • Verify current build and test status (all tests passing)
  • Identify code to move from src/hook.rs (traits: FilePath, Utf8String, DiffDeltaPath)
  • Identify code to move from src/multi_step_integration.rs (ParsedFile struct, parse_diff function, extract_file_path_from_diff_parts function, and tests)
  • Create src/diff/ module structure with mod.rs, parser.rs, traits.rs
  • Move diff parsing logic from multi_step_integration.rs to parser.rs
  • Move utility traits from hook.rs to traits.rs
  • Update lib.rs to expose new diff module
  • Update imports in hook.rs and multi_step_integration.rs
  • Remove moved code from original files
  • Fix import issues in examples and tests
  • Verify all tests pass and code builds (9 unit tests + 53 integration tests passing)
  • Verify hook.rs line count reduction (632 → 565 lines, 67 line reduction)
  • All diff parsing tests moved to new module and still passing
  • Created clean module separation between diff processing and hook logic
  • Fixed CI clippy warnings - Removed needless borrows in model validation test

Verification Results

Module Structure: src/diff/ created with mod.rs, parser.rs, traits.rs
Code Movement: All diff parsing logic successfully extracted from multi_step_integration.rs
Trait Extraction: FilePath, Utf8String, DiffDeltaPath moved from hook.rs to diff/traits.rs
Import Updates: All affected files updated to use new module structure
Tests: All 4 parse_diff tests moved to new module, all tests still pass (9 unit + 53 integration)
Build: Project builds successfully with no compilation errors
Size Reduction: hook.rs reduced from 632 to 565 lines (67 line reduction)
Functionality: All existing functionality preserved, clean module boundaries established
CI Fix: Clippy warnings resolved by removing needless borrows in test code

Original prompt

This section details on the original issue you should resolve

<issue_title>[Refactor] Extract diff parsing into src/diff module</issue_title>
<issue_description>## Context
src/hook.rs is 725 lines and mixes multiple concerns. This extracts diff parsing into a dedicated module as the first step in breaking it apart.

Priority

🟡 HIGH - Reduces large file, improves organization

Steps

1. Create module structure

mkdir -p src/diff
touch src/diff/mod.rs
touch src/diff/parser.rs
touch src/diff/traits.rs

2. Create src/diff/traits.rs

Extract utility traits from hook.rs:

//! Utility traits for diff processing.

use std::path::PathBuf;
use anyhow::Result;

/// Extension trait for PathBuf to support file operations needed for commits
pub trait FilePath {
    fn is_empty(&self) -> Result<bool>;
    fn write(&self, msg: String) -> Result<()>;
    fn read(&self) -> Result<String>;
}

// Move implementations from hook.rs lines 88-109

/// Extension trait for converting bytes to UTF-8 strings
pub trait Utf8String {
    fn to_utf8(&self) -> String;
}

// Move implementations from hook.rs lines 128-152

/// Extension trait for git2::DiffDelta to get file paths
pub trait DiffDeltaPath {
    fn path(&self) -> PathBuf;
}

// Move implementations from hook.rs lines 112-125

3. Create src/diff/parser.rs

Extract diff parsing logic from multi_step_integration.rs:

//! Git diff parsing utilities.

use std::path::PathBuf;
use anyhow::Result;

/// Represents a parsed file from a git diff
#[derive(Debug, Clone)]
pub struct ParsedFile {
    pub path: String,
    pub operation: String,
    pub diff_content: String,
}

/// Parse git diff into individual file changes.
///
/// Handles various diff formats including:
/// - Standard git diff output
/// - Diffs with commit hashes
/// - Diffs with various path prefixes (a/, b/, c/, i/)
/// - Deleted files (/dev/null paths)
///
/// # Arguments
/// * `diff_content` - Raw git diff text
///
/// # Returns
/// * `Result<Vec<ParsedFile>>` - Parsed files or error
pub fn parse_diff(diff_content: &str) -> Result<Vec<ParsedFile>> {
    // Move implementation from multi_step_integration.rs lines 212-402
}

/// Extracts file path from diff header parts
fn extract_file_path_from_diff_parts(parts: &[&str]) -> Option<String> {
    // Move from multi_step_integration.rs lines 186-209
}

#[cfg(test)]
mod tests {
    // Move tests from multi_step_integration.rs lines 639-810
}

4. Create src/diff/mod.rs

//! Diff processing and parsing utilities.
//!
//! This module handles parsing git diffs into structured data
//! and provides utilities for working with diff content.

pub mod parser;
pub mod traits;

pub use parser::{ParsedFile, parse_diff};
pub use traits::{FilePath, Utf8String, DiffDeltaPath};

5. Update src/lib.rs

pub mod diff;

6. Update imports in affected files

In src/hook.rs:

// Add at top
use crate::diff::traits::{FilePath, Utf8String, DiffDeltaPath};

// Remove old trait definitions (lines 88-152)

In src/multi_step_integration.rs:

// Add at top
use crate::diff::parser::parse_diff;

// Remove parse_diff function and helpers (lines 186-402)
// Keep the call sites

7. Remove moved code from original files

Delete the code that was moved to avoid duplication.

Verification Criteria

Pass:

  • src/diff/ module exists with mod.rs, parser.rs, traits.rs
  • All diff parsing logic moved from multi_step_integration.rs
  • All utility traits moved from hook.rs
  • No duplicate code remains in original files
  • All imports updated correctly
  • cargo build succeeds
  • cargo test passes all tests
  • All existing diff parsing tests still pass
  • cargo clippy shows no warnings
  • hook.rs reduced in size (should be ~600 lines)

Test manually

# Run the diff parsing tests specifically
cargo test --test multi_step -- parse_diff

# Test with actual git repo
cd test-repo
echo "test" > test.txt
git add test.txt
# Trigger hook to test parsing
git commit --no-edit

Estimated Time

4-5 hours

Dependencies

Labels

  • refactor
  • module-structure
  • diff-processing</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #66

💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Co-authored-by: oleander <220827+oleander@users.noreply.github.com>
@Copilot Copilot AI changed the title [WIP] [Refactor] Extract diff parsing into src/diff module [Refactor] Extract diff parsing into src/diff module Oct 5, 2025
@Copilot Copilot AI requested a review from oleander October 5, 2025 22:09
Copilot finished work on behalf of oleander October 5, 2025 22:09
@oleander oleander force-pushed the copilot/fix-54bae479-fd01-4562-8f45-56a7c3cda9e2 branch from 931692b to 0029022 Compare October 5, 2025 23:53
@oleander
Copy link
Owner

oleander commented Oct 6, 2025

@copilot Fix broken CI

…y warnings

Co-authored-by: oleander <220827+oleander@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Oct 6, 2025

@copilot Fix broken CI

Fixed clippy warnings causing CI failure by removing needless borrows in model validation tests. Commit 8410a2a.

Copilot finished work on behalf of oleander October 6, 2025 00:20
@oleander oleander marked this pull request as ready for review October 6, 2025 01:20
@oleander oleander removed their request for review October 6, 2025 01:21
@oleander oleander marked this pull request as draft October 6, 2025 01:21
@oleander oleander marked this pull request as ready for review October 6, 2025 01:22
@oleander oleander requested a review from Copilot October 6, 2025 01:22
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Refactor extracting diff parsing and related utility traits into a dedicated src/diff module to improve separation of concerns and reduce hook.rs size.

  • Created diff module (parser.rs, traits.rs, mod.rs) and moved parsing logic and utility traits.
  • Updated imports across codebase (examples, tests, integration module) to use new module structure.
  • Minor cleanup in tests (removed needless borrows) and added re-exports in diff/mod.rs for cleaner public API.

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/diff/parser.rs New module containing extracted parse_diff logic and ParsedFile struct.
src/diff/traits.rs New module containing FilePath, DiffDeltaPath, and Utf8String traits and implementations.
src/diff/mod.rs Module aggregator re-exporting parser and traits for external use.
src/multi_step_integration.rs Removed inlined parsing logic; now imports parse_diff and ParsedFile.
src/hook.rs Removed trait definitions; now imports traits from diff module.
src/lib.rs Exposes new diff module publicly.
examples/multi_step_commit.rs Updated to import parse_diff from new module (currently via internal submodule path).
tests/patch_test.rs Updated imports to use traits from new diff module.
tests/model_validation_test.rs Removed unnecessary borrows (clippy cleanup).

use async_openai::Client;
use ai::multi_step_integration::{generate_commit_message_local, generate_commit_message_multi_step, parse_diff};
use ai::multi_step_integration::{generate_commit_message_local, generate_commit_message_multi_step};
use ai::diff::parser::parse_diff;
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

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

[nitpick] Since diff::mod.rs re-exports parse_diff, prefer use ai::diff::parse_diff; to decouple the example from internal module structure and rely on the intended public API surface.

Suggested change
use ai::diff::parser::parse_diff;
use ai::diff::parse_diff;

Copilot uses AI. Check for mistakes.

@oleander oleander marked this pull request as draft October 6, 2025 01:26
@oleander oleander marked this pull request as ready for review October 6, 2025 01:26
@oleander
Copy link
Owner

oleander commented Oct 6, 2025

@copilot Implement review request comments

@oleander
Copy link
Owner

oleander commented Oct 6, 2025

@copilot Fix review comments

Copy link
Contributor Author

Copilot AI commented Oct 6, 2025

@copilot Fix review comments

I still don't have access to the specific review comments that need to be fixed. Could you please share the specific feedback or review comments that need to be addressed? I'm ready to implement the changes once I know what needs to be fixed.

Copilot finished work on behalf of oleander October 6, 2025 03:29
@oleander
Copy link
Owner

oleander commented Oct 6, 2025

@copilot Fix review comments

@oleander oleander requested a review from Copilot October 6, 2025 03:32
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

pub diff_content: String
}
use crate::diff::parser::{parse_diff, ParsedFile};

Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

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

Removing parse_diff (and ParsedFile) from this module without providing a re-export is a breaking API change for users previously calling crate::multi_step_integration::parse_diff. Consider adding a deprecated pub use parse_diff; here (or in this module) to preserve backward compatibility, or document the breaking change.

Suggested change
#[deprecated(note = "Use crate::diff::parser::{parse_diff, ParsedFile} instead")]
pub use crate::diff::parser::{parse_diff, ParsedFile};

Copilot uses AI. Check for mistakes.

Comment on lines +88 to +97
let mut _commit_hash_line: Option<&str> = None;

// First scan to detect if this is a commit message with hash
for line in diff_content.lines().take(3) {
if line.len() >= 40 && line.chars().take(40).all(|c| c.is_ascii_hexdigit()) {
_commit_hash_line = Some(line);
break;
}
}

Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

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

The variable _commit_hash_line is collected but never used; since it has no effect on parsing, it can be removed to reduce noise, or its intended purpose (e.g., future conditional logic) should be implemented.

Suggested change
let mut _commit_hash_line: Option<&str> = None;
// First scan to detect if this is a commit message with hash
for line in diff_content.lines().take(3) {
if line.len() >= 40 && line.chars().take(40).all(|c| c.is_ascii_hexdigit()) {
_commit_hash_line = Some(line);
break;
}
}

Copilot uses AI. Check for mistakes.

Copilot finished work on behalf of oleander October 6, 2025 03:33
Copilot finished work on behalf of oleander October 6, 2025 03:38
@oleander
Copy link
Owner

oleander commented Oct 6, 2025

@copilot Fix review comments

@oleander oleander removed their request for review October 6, 2025 03:38
@Copilot Copilot AI requested a review from oleander October 6, 2025 03:43
Copilot finished work on behalf of oleander October 6, 2025 03:43
@oleander oleander removed the agent label Oct 6, 2025
@oleander
Copy link
Owner

oleander commented Oct 6, 2025

@copilot Fix review comments

@oleander oleander added the agent label Oct 6, 2025
@oleander oleander removed their request for review October 6, 2025 03:48
@oleander oleander removed the agent label Oct 6, 2025
@oleander oleander self-assigned this Oct 6, 2025
@oleander oleander self-requested a review October 6, 2025 03:48
Copilot finished work on behalf of oleander October 6, 2025 03:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Refactor] Extract diff parsing into src/diff module

2 participants