diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml new file mode 100644 index 0000000..aa622e1 --- /dev/null +++ b/.github/workflows/github-pages.yml @@ -0,0 +1,89 @@ +name: Deploy Documentation to GitHub Pages + +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + name: Build Documentation + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: ๐Ÿฆ€ Set up Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y pkg-config libssl-dev + + - name: Cache Cargo + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-pages-${{ hashFiles('**/Cargo.lock') }} + + - name: ๐Ÿ“ฆ Build project + run: cargo build --release + + - name: ๐Ÿ“š Generate documentation + run: | + # Set environment variables to prevent browser opening + export GIT_EDITOR_NO_BROWSER=1 + export NO_BROWSER=1 + + # Create docs directory + mkdir -p docs-site + + # Generate the documentation HTML + cargo run --release -- --docs + + # Copy the generated HTML to docs-site directory + cp /tmp/git-editor-docs.html docs-site/index.html + + # Create a simple robots.txt for better SEO + echo -e "User-agent: *\nAllow: /" > docs-site/robots.txt + + # Create a .nojekyll file to bypass Jekyll processing + touch docs-site/.nojekyll + + - name: Setup Pages + uses: actions/configure-pages@v4 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: './docs-site' + + deploy: + name: Deploy to GitHub Pages + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + # Only deploy on pushes to main/master, not on PRs + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index fca8222..f114a2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -346,6 +346,7 @@ dependencies = [ "colored", "crossterm", "git2", + "open", "rand", "regex", "serial_test", @@ -538,6 +539,25 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -671,6 +691,17 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "open" +version = "5.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95" +dependencies = [ + "is-wsl", + "libc", + "pathdiff", +] + [[package]] name = "openssl-probe" version = "0.1.6" @@ -712,6 +743,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + [[package]] name = "percent-encoding" version = "2.3.1" diff --git a/Cargo.toml b/Cargo.toml index 3b029f0..a98ec28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ url = "2.5.4" uuid = { version = "1.17.0", features = ["v4"] } crossterm = "0.27" tempfile = "3.0" +open = "5.0" [dev-dependencies] serial_test = "3.0" diff --git a/README.md b/README.md index 0cefd00..e776eaa 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,28 @@ cargo build --release # The binary will be available at target/release/git-editor ``` +## Documentation + +๐Ÿ“š **Comprehensive documentation is available online:** [rohansen856.github.io/git-editor](https://rohansen856.github.io/git-editor) + +The online documentation includes: +- Complete command reference with examples +- Technical implementation details +- Architecture overview and development guidelines +- Interactive copy-to-clipboard code examples +- Troubleshooting guide and FAQ +- Advanced usage patterns and best practices + +### Quick Access to Documentation + +You can also access the documentation directly from the command line: + +```bash +git-editor --docs +``` + +This command will generate and open the comprehensive documentation in your default browser. + ## Usage Git Editor supports five main modes of operation: diff --git a/docs/template.html b/docs/template.html new file mode 100644 index 0000000..6589f61 --- /dev/null +++ b/docs/template.html @@ -0,0 +1,1669 @@ + + + + + + + Git Editor - Comprehensive Technical Documentation + + + + +
+

๐Ÿ› ๏ธ Git Editor - Complete Technical Documentation

+ +
+

๐Ÿ“‹ Table of Contents

+ +
+ +
+

๐ŸŽฏ Overview & Architecture

+

Git Editor is a sophisticated command-line tool written in Rust for comprehensive Git commit history manipulation. It provides surgical precision for rewriting timestamps, author information, and commit messages while maintaining repository integrity.

+ +
+ ๐Ÿ”ง Core Capabilities: +
    +
  • Timestamp Rewriting: Intelligent date distribution with realistic patterns
  • +
  • Author Management: Bulk update of author name and email
  • +
  • Interactive Selection: Pick specific commits or ranges
  • +
  • Simulation Mode: Preview changes before applying
  • +
  • Git URL Cloning: Direct operation on remote repositories
  • +
+
+ +
+ โš ๏ธ Critical Warning: This tool permanently rewrites Git history. Always backup your repository before use. Force pushes will be required after history rewriting. +
+ +
+

๐Ÿ”„ Git Editor Workflow

+
+
Input Validation
+
Repository Analysis
+
History Rewriting
+
Verification
+
+
+
+ +
+

๐Ÿ’พ Installation & Setup

+ +

๐Ÿ“ฅ From Release Binaries

+
+ +
# Download the latest release for your platform
+wget https://github.com/rohansen856/git-editor/releases/latest/download/git-editor-linux-x64.tar.gz
+tar -xzf git-editor-linux-x64.tar.gz
+sudo mv git-editor /usr/local/bin/
+
+# Verify installation
+git-editor --help
+
+ +

๐Ÿ”จ From Source

+
+ +
# Prerequisites: Rust 1.70+ and Git
+rustup update stable
+
+# Clone and build
+git clone https://github.com/rohansen856/git-editor.git
+cd git-editor
+
+# Build release binary
+cargo build --release
+
+# Install globally
+sudo cp target/release/git-editor /usr/local/bin/
+
+# Or use cargo install
+cargo install --path .
+
+ +

๐Ÿณ Docker Usage

+
+ +
# Build Docker image
+docker build -t git-editor .
+
+# Run with repository mounted
+docker run -v /path/to/repo:/workspace git-editor --repo-path /workspace --docs
+
+ +

๐Ÿ“‹ System Requirements

+
+
    +
  • Operating System: Linux, macOS, Windows
  • +
  • Memory: Minimum 100MB RAM
  • +
  • Storage: 50MB for binary + temporary space for repository cloning
  • +
  • Git: Version 2.0+ (for git2 library compatibility)
  • +
  • Network: Required for Git URL cloning and documentation
  • +
+
+
+ +
+

๐Ÿš€ Operation Modes

+

Git Editor operates in distinct modes, each optimized for specific use cases:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ModePrimary FlagDescriptionUse CaseRequired Args
Full RewriteDefaultComplete repository history rewritingBulk timestamp and author updatesname, email, begin, end
Show History-s, --show-historyDisplay commit history without modificationsRepository analysis and planningrepo-path only
Pick Specific-p, --pick-specific-commitsInteractive individual commit selectionTargeted commit modificationsrepo-path only
Range Edit-x, --rangeSelect and edit commit rangesBatch editing of consecutive commitsrepo-path only
Simulation--simulatePreview changes without applyingSafe testing and validationDepends on base mode
Documentation--docsOpen comprehensive documentationHelp and referenceNone
+ +

๐Ÿ”„ Mode Priority System

+
+

Precedence Order (highest to lowest):

+
    +
  1. --docs - Always takes precedence
  2. +
  3. --show-history - Read-only operations
  4. +
  5. --pick-specific-commits - Interactive selection
  6. +
  7. --range - Range-based editing
  8. +
  9. --simulate - Dry-run mode (applies to other modes)
  10. +
  11. Full Rewrite - Default mode
  12. +
+
+
+ +
+

๐Ÿ“– Complete Command Reference

+ +

๐Ÿ”ง Core Arguments

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentShortTypeDescriptionExampleRequired
--repo-path-rStringLocal path or Git URL to repository-r /path/to/repo
-r https://github.com/user/repo.git
โŒ (defaults to ./)
--email-EmailAuthor email address (RFC 5322 compliant)--email user@example.comโœ… (full rewrite only)
--name-nStringAuthor display name-n "John Doe"โœ… (full rewrite only)
--begin-bDateTimeStart timestamp (YYYY-MM-DD HH:MM:SS)-b "2023-01-01 09:00:00"โœ… (full rewrite only)
--end-eDateTimeEnd timestamp (YYYY-MM-DD HH:MM:SS)-e "2023-12-31 17:00:00"โœ… (full rewrite only)
+ +

๐ŸŽ›๏ธ Mode Flags

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FlagShortDescriptionConflicts WithAdditional Options
--show-history-sDisplay repository commit historyAll other modesNone
--pick-specific-commits-pInteractive commit selectionFull rewrite, range modeNone
--range-xRange-based commit editingFull rewrite, pick mode--message, --author, --time
--simulate-Dry-run mode (preview only)None (modifier)--show-diff
--docs-Open documentation in browserAll other modesNone
+ +

โš™๏ธ Range Mode Modifiers

+
+

These flags work exclusively with --range mode:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FlagDescriptionEffect
--messageEdit only commit messagesPreserves author and timestamp
--authorEdit only author informationPreserves message and timestamp
--timeEdit only timestampsPreserves message and author
+
+ Note: If no modifier flags are specified with --range, all fields (message, author, timestamp) will be editable. +
+
+ +

๐Ÿ” Simulation Options

+ + + + + + + + + + + + + + + + + +
FlagDescriptionOutputRequires
--show-diffShow detailed change previewBefore/after comparison for each commit--simulate
+
+ +
+

๐Ÿ”ฌ Technical Implementation

+ +

๐Ÿ“Š Date Distribution Algorithm

+
+

Git Editor uses a sophisticated algorithm for timestamp distribution:

+
    +
  • Chronological Preservation: Maintains original commit order
  • +
  • Business Hours Weighting: 70% of commits during 9AM-6PM
  • +
  • Weekend Reduction: 20% commit frequency on weekends
  • +
  • Natural Spacing: Exponential distribution with realistic gaps
  • +
  • Commit Density: Higher frequency during active development periods
  • +
+
+ +

๐Ÿ” Git Operations & Safety

+
+

Repository Validation

+
+ +
# Git Editor performs these validations:
+1. Repository existence and accessibility
+2. .git directory structure integrity
+3. Current branch and HEAD validity
+4. Working directory clean state check
+5. Remote tracking branch analysis
+
+ +

History Rewriting Process

+
+ +
# Internal rewriting workflow:
+1. Create temporary branch for operations
+2. Walk commit history from oldest to newest
+3. Apply filter-branch-like operations with git2
+4. Maintain parent-child relationships
+5. Update branch references atomically
+6. Cleanup temporary objects
+
+
+ +

๐ŸŒ Git URL Support

+
+
+

๐Ÿ“ก Supported Protocols

+
    +
  • HTTPS: https://github.com/user/repo.git
  • +
  • SSH: git@github.com:user/repo.git
  • +
  • HTTP: http://example.com/repo.git
  • +
+
+
+

๐Ÿ”„ Clone Behavior

+
    +
  • Temporary directory creation
  • +
  • Full history clone (no shallow)
  • +
  • Automatic cleanup on completion
  • +
  • Authentication via Git credentials
  • +
+
+
+ +

โšก Performance Characteristics

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Repository SizeCommit CountProcessing TimeMemory Usage
Small (<10MB)<1,000<10 seconds<50MB
Medium (10-100MB)1,000-10,00010-60 seconds50-200MB
Large (100MB-1GB)10,000-100,0001-10 minutes200MB-1GB
Enterprise (>1GB)>100,000>10 minutes>1GB
+
+ +
+

๐Ÿ’ก Usage Examples & Workflows

+ +

๐ŸŽฏ Basic Operations

+ +

๐Ÿ“š Open Documentation

+
+
+ +
git-editor --docs
+
+

Opens this comprehensive documentation in your default browser.

+
+ +

๐Ÿ“– Repository Analysis

+
+
+ +
# Show history of current directory
+git-editor -s
+
+# Analyze specific repository
+git-editor --repo-path /path/to/repo --show-history
+
+# Analyze remote repository
+git-editor -r https://github.com/user/repo.git -s
+
+

Displays comprehensive commit history without making any changes.

+
+ +

๐Ÿ”„ Complete History Rewriting

+ +

๐Ÿ“ Basic Full Rewrite

+
+
+ +
git-editor \
+  --name "John Doe" \
+  --email john@example.com \
+  --begin "2023-01-01 09:00:00" \
+  --end "2023-12-31 17:00:00"
+
+

Rewrites all commits with new author info and timestamps distributed between the specified dates.

+
+ +

๐ŸŒ Remote Repository Rewrite

+
+
+ +
git-editor \
+  --repo-path https://github.com/user/private-repo.git \
+  --name "Corporate Identity" \
+  --email corporate@company.com \
+  --begin "2023-06-01 08:00:00" \
+  --end "2023-06-30 18:00:00"
+
+

Clones a remote repository, rewrites history, and prepares for push-back.

+
+ +

๐ŸŽฏ Targeted Editing

+ +

๐Ÿ” Interactive Commit Selection

+
+
+ +
# Interactive commit picker
+git-editor --pick-specific-commits
+
+# With specific repository
+git-editor -r /path/to/repo --pick-specific-commits
+
+

Provides an interactive interface to select and edit individual commits.

+
+ +

๐Ÿ“Š Range-Based Editing

+
+
+ +
# Edit all fields in a range
+git-editor --range
+
+# Edit only commit messages
+git-editor --range --message
+
+# Edit only author information
+git-editor --range --author
+
+# Edit only timestamps
+git-editor --range --time
+
+# Multiple field editing
+git-editor --range --message --author
+
+

Select a range of commits (e.g., commits 5-11) and edit specific fields.

+
+ +

๐Ÿ” Simulation & Preview

+ +

๐Ÿงช Dry-Run Testing

+
+
+ +
# Basic simulation
+git-editor --simulate \
+  --name "Test User" \
+  --email test@example.com \
+  --begin "2023-01-01 09:00:00" \
+  --end "2023-01-31 17:00:00"
+
+# Detailed diff preview
+git-editor --simulate --show-diff \
+  --name "John Doe" \
+  --email john@example.com \
+  --begin "2023-06-01 08:00:00" \
+  --end "2023-06-30 18:00:00"
+
+

Previews all changes with detailed diffs without applying them.

+
+ +

๐Ÿ”„ Simulation with Other Modes

+
+
+ +
# Simulate specific commit selection
+git-editor --simulate --pick-specific-commits
+
+# Simulate range editing
+git-editor --simulate --range --message
+
+# Simulate with detailed output
+git-editor --simulate --show-diff --range --author
+
+

Simulation mode works with all other operation modes for safe testing.

+
+ +

๐Ÿ”ง Advanced Workflows

+ +

๐ŸŽญ Privacy & Anonymization

+
+
+ +
# Anonymize commit history
+git-editor \
+  --name "Anonymous Contributor" \
+  --email anonymous@privacy.local \
+  --begin "2023-01-01 00:00:00" \
+  --end "2023-12-31 23:59:59"
+
+# Corporate identity standardization
+git-editor \
+  --name "Development Team" \
+  --email dev-team@company.com \
+  --begin "2023-04-01 09:00:00" \
+  --end "2023-04-30 17:00:00"
+
+

Standardize or anonymize commit authorship for privacy or corporate compliance.

+
+ +

๐Ÿ“… Timeline Compression/Expansion

+
+
+ +
# Compress 6 months of work into 1 month
+git-editor \
+  --name "Rapid Developer" \
+  --email rapid@dev.com \
+  --begin "2023-11-01 08:00:00" \
+  --end "2023-11-30 20:00:00"
+
+# Expand 1 week into 3 months
+git-editor \
+  --name "Consistent Contributor" \
+  --email consistent@dev.com \
+  --begin "2023-09-01 09:00:00" \
+  --end "2023-11-30 17:00:00"
+
+

Adjust project timelines for demos, portfolio presentation, or analysis.

+
+
+ +
+

๐Ÿ”ง Advanced Features

+ +

๐Ÿง  Smart Date Distribution

+
+
+

โฐ Time Patterns

+
    +
  • Business Hours: 9AM-6PM preferred
  • +
  • Lunch Break: Reduced activity 12-1PM
  • +
  • Late Night: Occasional commits after hours
  • +
  • Morning Start: Activity ramp-up 8-10AM
  • +
+
+
+

๐Ÿ“… Weekly Patterns

+
    +
  • Monday: Fresh start, moderate activity
  • +
  • Tuesday-Thursday: Peak productivity
  • +
  • Friday: Reduced late-day activity
  • +
  • Weekends: 20% of weekday frequency
  • +
+
+
+ +

๐Ÿ”„ Interactive Features

+ +

๐ŸŽฎ Pick Specific Commits Interface

+
+

The interactive commit picker provides:

+
    +
  • Visual Commit List: SHA, date, author, message preview
  • +
  • Multi-Selection: Space to toggle, Enter to confirm
  • +
  • Search/Filter: Filter commits by author, date, or message
  • +
  • Batch Operations: Apply changes to selected commits
  • +
+
+ +

๐Ÿ“Š Range Selection Interface

+
+

Range editing supports:

+
    +
  • Commit Numbering: Display commits with sequential numbers
  • +
  • Range Syntax: "5-11", "1,3,5-7", "10-*" (to end)
  • +
  • Field Selection: Choose which fields to edit
  • +
  • Bulk Apply: Apply same changes to entire range
  • +
+
+ +

๐Ÿ” Simulation & Analysis

+
+

Simulation Mode provides:

+
    +
  • Impact Analysis: Shows number of commits affected
  • +
  • Date Range Validation: Ensures realistic timestamp distribution
  • +
  • Author Statistics: Before/after author distribution
  • +
  • Timeline Visualization: Graphical representation of changes
  • +
  • Risk Assessment: Identifies potential issues before execution
  • +
+
+ +

๐ŸŒ Git URL Processing

+
+

Automatic Repository Detection

+
+ +
# Supported URL formats:
+https://github.com/user/repo.git
+https://github.com/user/repo
+git@github.com:user/repo.git
+https://gitlab.com/user/repo.git
+https://bitbucket.org/user/repo.git
+
+# URL normalization and validation
+# Automatic .git suffix handling
+# Repository name extraction for temporary directories
+
+
+
+ +
+

๐Ÿ—๏ธ Internal Architecture

+ +

๐Ÿ“ Project Structure

+
+ +
git-editor/
+โ”œโ”€โ”€ src/
+โ”‚   โ”œโ”€โ”€ main.rs              # Entry point and mode dispatch
+โ”‚   โ”œโ”€โ”€ args.rs              # CLI argument parsing (clap)
+โ”‚   โ”œโ”€โ”€ docs.rs              # Documentation generation
+โ”‚   โ”œโ”€โ”€ rewrite/
+โ”‚   โ”‚   โ”œโ”€โ”€ mod.rs           # Rewrite module exports
+โ”‚   โ”‚   โ”œโ”€โ”€ rewrite_all.rs   # Full history rewriting
+โ”‚   โ”‚   โ”œโ”€โ”€ rewrite_specific.rs # Interactive commit selection
+โ”‚   โ”‚   โ””โ”€โ”€ rewrite_range.rs # Range-based editing
+โ”‚   โ””โ”€โ”€ utils/
+โ”‚       โ”œโ”€โ”€ mod.rs           # Utility module exports
+โ”‚       โ”œโ”€โ”€ types.rs         # Common types and aliases
+โ”‚       โ”œโ”€โ”€ validator.rs     # Input validation
+โ”‚       โ”œโ”€โ”€ datetime.rs      # Timestamp generation
+โ”‚       โ”œโ”€โ”€ commit_history.rs# Git operations
+โ”‚       โ”œโ”€โ”€ prompt.rs        # User interaction
+โ”‚       โ”œโ”€โ”€ git_clone.rs     # Repository cloning
+โ”‚       โ”œโ”€โ”€ git_config.rs    # Git configuration
+โ”‚       โ””โ”€โ”€ simulation.rs    # Dry-run functionality
+โ”œโ”€โ”€ docs/
+โ”‚   โ””โ”€โ”€ template.html        # Documentation template
+โ”œโ”€โ”€ tests/
+โ”‚   โ””โ”€โ”€ integration_tests.rs # Integration test suite
+โ”œโ”€โ”€ Cargo.toml              # Dependencies and metadata
+โ”œโ”€โ”€ Dockerfile              # Container configuration
+โ””โ”€โ”€ Makefile                # Build automation
+
+ +

๐Ÿ”— Key Dependencies

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CrateVersionPurposeFeatures Used
git20.20+Git repository operationsRepository access, commit manipulation
clap4.5+Command-line argument parsingDerive API, help generation
chrono0.4+Date/time handlingDateTime parsing, timezone support
colored3.0+Terminal output coloringANSI color codes, cross-platform
tempfile3.20+Temporary directory managementAuto-cleanup, secure temp files
open5.0+Browser launchingCross-platform file opening
url2.5+URL parsing and validationGit URL parsing
regex1.11+Pattern matchingEmail validation, date parsing
+ +

๐Ÿ›๏ธ Architecture Patterns

+
+
+

๐ŸŽฏ Error Handling

+
    +
  • Custom Result type alias
  • +
  • Comprehensive error propagation
  • +
  • User-friendly error messages
  • +
  • Graceful degradation
  • +
+
+
+

๐Ÿ”ง Modularity

+
    +
  • Separate modules by responsibility
  • +
  • Clear interface boundaries
  • +
  • Reusable utility functions
  • +
  • Testable components
  • +
+
+
+ +

๐Ÿงช Testing Strategy

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test TypeCountCoveragePurpose
Unit Tests78Core logicIndividual function validation
Integration Tests20CLI behaviorEnd-to-end workflow testing
Doc Tests0DocumentationCode example validation
+
+
+ +
+

๐Ÿ› ๏ธ Development Guide

+ +

๐Ÿš€ Build Commands

+
+ +
# Development build (fast compilation)
+cargo build
+
+# Release build (optimized)
+cargo build --release
+
+# Run with arguments
+cargo run -- --help
+cargo run -- --repo-path . -s
+
+# Watch mode for development
+cargo watch -x "run -- --docs"
+
+ +

๐Ÿงช Testing

+
+ +
# Run all tests (98 total)
+cargo test
+
+# Run unit tests only (78 tests)
+cargo test --lib
+
+# Run integration tests only (20 tests)
+cargo test --test integration_tests
+
+# Run specific test with output
+cargo test --test integration_tests test_show_history_mode_integration -- --nocapture
+
+# Run tests without browser opening (for development)
+GIT_EDITOR_NO_BROWSER=1 cargo test --all
+
+ +

โœจ Code Quality

+
+ +
# Format code
+cargo fmt
+
+# Check formatting without changes
+cargo fmt --check
+
+# Run linter
+cargo clippy
+
+# Run linter with strict warnings (CI requirement)
+cargo clippy -- -D warnings
+
+# Security audit
+cargo audit
+
+# Check for outdated dependencies
+cargo outdated
+
+ +

๐Ÿ“ฆ Makefile Commands

+
+ +
# Build release binary
+make build
+
+# Run all tests
+make test
+
+# Check code formatting
+make fmt
+
+# Run clippy linter
+make lint
+
+# Run with default parameters
+make run
+
+# Run with custom environment variables
+make run-custom
+
+# Clean build artifacts
+make clean
+
+# Build Docker image
+make docker-build
+
+# Run in Docker container
+make docker-run
+
+# Install binary to /usr/local/bin
+make install
+
+# Show all available commands
+make help
+
+ +

๐Ÿ”„ Development Workflow

+
+
    +
  1. Setup: Clone repository and run cargo build
  2. +
  3. Development: Make changes and test with cargo run
  4. +
  5. Testing: Run cargo test to ensure no regressions
  6. +
  7. Quality: Check with cargo fmt and cargo clippy
  8. +
  9. Integration: Test end-to-end with make test
  10. +
  11. Documentation: Update docs and test with --docs
  12. +
+
+ +

๐ŸŽฏ Contribution Guidelines

+
+
    +
  • Code Style: Follow Rust standard formatting (rustfmt)
  • +
  • Testing: Add tests for all new functionality
  • +
  • Documentation: Update inline docs and this template
  • +
  • Error Handling: Use the custom Result type consistently
  • +
  • Performance: Consider memory usage for large repositories
  • +
+
+
+ +
+

๐Ÿ”ง Troubleshooting & FAQ

+ +

โ— Common Issues

+ +

๐Ÿ” Repository Not Found

+
+
+ +
Error: Repository not found at path: /invalid/path
+
+

Solutions:

+
    +
  • Verify the repository path exists: ls -la /path/to/repo
  • +
  • Ensure .git directory is present: ls -la /path/to/repo/.git
  • +
  • Check permissions: ls -ld /path/to/repo
  • +
  • For Git URLs, verify network connectivity and authentication
  • +
+
+ +

๐Ÿ—“๏ธ Invalid Date Format

+
+
+ +
Error: Invalid start date format (expected YYYY-MM-DD HH:MM:SS): 2023-1-1
+
+

Solutions:

+
    +
  • Use exact format: YYYY-MM-DD HH:MM:SS
  • +
  • Zero-pad single digits: 2023-01-01 09:00:00
  • +
  • Use 24-hour time format
  • +
  • Ensure end date is after start date
  • +
+
+ +

๐Ÿ“ง Email Validation Errors

+
+
+ +
Error: Invalid email format: user@domain
+
+

Solutions:

+
    +
  • Include top-level domain: user@domain.com
  • +
  • Follow RFC 5322 format requirements
  • +
  • Avoid special characters in local part
  • +
  • Use quotes for complex local parts: "user name"@domain.com
  • +
+
+ +

๐ŸŒ Git URL Authentication

+
+
+ +
Error: Authentication failed for Git URL
+
+

Solutions:

+
    +
  • Configure Git credentials: git config --global credential.helper store
  • +
  • Use SSH keys for SSH URLs: ssh-add ~/.ssh/id_rsa
  • +
  • For private repos, use personal access tokens
  • +
  • Test with git clone first
  • +
+
+ +

๐Ÿ”ง Performance Issues

+ +

โšก Large Repository Optimization

+
+
+ +
# For large repositories, consider:
+
+# 1. Use simulation mode first
+git-editor --simulate --show-diff [other-args]
+
+# 2. Process in smaller ranges
+git-editor --range --message  # Edit specific fields only
+
+# 3. Monitor system resources
+htop  # Watch memory and CPU usage
+
+# 4. Ensure sufficient disk space
+df -h  # Check available space
+
+
+ +

๐Ÿ’พ Memory Management

+
+

Memory optimization tips:

+
    +
  • Close other applications before processing large repos
  • +
  • Use range mode for selective editing instead of full rewrite
  • +
  • Consider splitting very large repositories
  • +
  • Monitor swap usage during processing
  • +
+
+ +

โ“ Frequently Asked Questions

+ +
+

๐Ÿ”„ Can I undo changes after rewriting history?

+

Answer: History rewriting is permanent. However, you can:

+
    +
  • Use Git reflog to find previous HEAD positions
  • +
  • Restore from backups if available
  • +
  • Use simulation mode to preview changes first
  • +
+
+ +
+

๐ŸŒ Does this work with remote repositories?

+

Answer: Yes, Git Editor can clone and process remote repositories:

+
    +
  • Supports HTTPS, SSH, and HTTP protocols
  • +
  • Handles authentication through Git credentials
  • +
  • Creates temporary local clones for processing
  • +
  • You'll need to push changes back manually
  • +
+
+ +
+

๐Ÿข Is this safe for production repositories?

+

Answer: Use with extreme caution:

+
    +
  • Always test on a backup first
  • +
  • Use simulation mode for validation
  • +
  • Coordinate with team members before rewriting shared history
  • +
  • Consider impact on CI/CD pipelines and deployment history
  • +
+
+ +

๐Ÿ†˜ Getting Help

+
+

If you encounter issues:

+
    +
  • ๐Ÿ“– Check this documentation first: git-editor --docs
  • +
  • ๐Ÿ› Search existing issues: GitHub Issues
  • +
  • ๐Ÿ“š Review the project README: Project Repository
  • +
  • ๐Ÿ†• Create a new issue with: +
      +
    • Exact command that failed
    • +
    • Complete error message
    • +
    • Operating system and Git version
    • +
    • Repository size and commit count (approximate)
    • +
    +
  • +
+
+
+ +
+

๐Ÿ“š API Reference

+ +

๐Ÿ”ง Core Functions

+ +

๐Ÿ“Š History Analysis

+
+ +
// Get comprehensive commit history
+pub fn get_commit_history(args: &Args, print: bool) -> Result<Vec<CommitInfo>>
+
+// Analyze repository structure
+pub fn analyze_repository(repo_path: &str) -> Result<RepositoryStats>
+
+// Validate repository integrity
+pub fn validate_repository(repo_path: &str) -> Result<()>
+
+ +

โฐ Timestamp Generation

+
+ +
// Generate realistic timestamp distribution
+pub fn generate_timestamps(
+    start: &str,
+    end: &str,
+    count: usize
+) -> Result<Vec<DateTime<Utc>>>
+
+// Create business-hour weighted distribution
+pub fn generate_business_hour_timestamps(
+    start: DateTime<Utc>,
+    end: DateTime<Utc>,
+    commit_count: usize
+) -> Vec<DateTime<Utc>>
+
+ +

๐Ÿ”„ History Rewriting

+
+ +
// Full repository history rewrite
+pub fn rewrite_all_commits(args: &Args) -> Result<()>
+
+// Interactive commit selection and editing
+pub fn rewrite_specific_commits(args: &Args) -> Result<()>
+
+// Range-based commit editing
+pub fn rewrite_range_commits(args: &Args) -> Result<()>
+
+ +

๐Ÿ“ˆ Data Structures

+ +

๐Ÿ’พ CommitInfo

+
+ +
pub struct CommitInfo {
+    pub hash: String,              // Full SHA-1 hash
+    pub short_hash: String,        // Abbreviated hash (7 chars)
+    pub timestamp: DateTime<Utc>,   // Commit timestamp
+    pub author_name: String,       // Author display name
+    pub author_email: String,      // Author email address
+    pub message: String,           // Commit message
+    pub parent_count: usize,       // Number of parent commits
+}
+
+ +

โš™๏ธ EditOptions

+
+ +
pub struct EditOptions {
+    pub edit_author_name: bool,    // Enable author name editing
+    pub edit_author_email: bool,   // Enable author email editing
+    pub edit_timestamp: bool,      // Enable timestamp editing
+    pub edit_message: bool,        // Enable message editing
+    pub new_author_name: Option<String>,
+    pub new_author_email: Option<String>,
+    pub new_message: Option<String>,
+}
+
+ +

๐ŸŽ›๏ธ Configuration

+ +

๐Ÿ”ง Environment Variables

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VariablePurposeDefaultExample
GIT_EDITOR_NO_BROWSERDisable browser opening for docsNot setGIT_EDITOR_NO_BROWSER=1
NO_BROWSERAlternative browser disable flagNot setNO_BROWSER=1
RUST_LOGLogging level controlNot setRUST_LOG=debug
+ +

๐Ÿ“‹ Exit Codes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CodeMeaningDescription
0SuccessOperation completed successfully
1General ErrorUnspecified error occurred
2Invalid ArgumentsCommand-line argument validation failed
3Repository ErrorGit repository access or validation failed
4Permission ErrorInsufficient permissions for operation
+
+ + +
+ + + + + \ No newline at end of file diff --git a/src/args.rs b/src/args.rs index d80a5b4..abfd3e8 100644 --- a/src/args.rs +++ b/src/args.rs @@ -80,6 +80,12 @@ pub struct Args { #[arg(long = "time", help = "Edit only timestamps in range mode (-x)")] pub edit_time: bool, + #[arg( + long = "docs", + help = "Open comprehensive documentation in the browser" + )] + pub docs: bool, + #[clap(skip)] pub _temp_dir: Option, } @@ -109,8 +115,8 @@ impl Args { self._temp_dir = Some(temp_dir); } - // Skip prompting for email, name, start, and end if using show_history, pick_specific_commits, or simulation modes - if self.show_history || self.pick_specific_commits || self.simulate { + // Skip prompting for email, name, start, and end if using show_history, pick_specific_commits, simulation, or docs modes + if self.show_history || self.pick_specific_commits || self.simulate || self.docs { return Ok(()); } @@ -211,6 +217,7 @@ impl Args { edit_message: false, edit_author: false, edit_time: false, + docs: false, _temp_dir: None, }; @@ -290,6 +297,7 @@ mod tests { edit_message: false, edit_author: false, edit_time: false, + docs: false, _temp_dir: None, }; @@ -319,6 +327,7 @@ mod tests { edit_message: false, edit_author: false, edit_time: false, + docs: false, _temp_dir: None, }; @@ -343,6 +352,7 @@ mod tests { edit_message: false, edit_author: false, edit_time: false, + docs: false, _temp_dir: None, }; @@ -367,6 +377,7 @@ mod tests { edit_message: false, edit_author: false, edit_time: false, + docs: false, _temp_dir: None, }; @@ -393,6 +404,7 @@ mod tests { edit_message: false, edit_author: false, edit_time: false, + docs: false, _temp_dir: None, }; @@ -418,6 +430,7 @@ mod tests { edit_message: false, edit_author: false, edit_time: false, + docs: false, _temp_dir: None, }; @@ -441,6 +454,7 @@ mod tests { edit_message: false, edit_author: false, edit_time: false, + docs: false, _temp_dir: None, }; @@ -464,6 +478,7 @@ mod tests { edit_message: false, edit_author: false, edit_time: false, + docs: false, _temp_dir: None, }; @@ -474,4 +489,56 @@ mod tests { .to_string() .contains("--show-diff requires --simulate")); } + + #[test] + fn test_args_with_docs() { + let args = Args { + repo_path: None, + email: None, + name: None, + start: None, + end: None, + show_history: false, + pick_specific_commits: false, + range: false, + simulate: false, + show_diff: false, + edit_message: false, + edit_author: false, + edit_time: false, + docs: true, + _temp_dir: None, + }; + + assert!(args.docs); + assert!(!args.show_history); + assert!(!args.simulate); + assert!(!args.pick_specific_commits); + assert!(!args.range); + } + + #[test] + fn test_docs_mode_skips_validation() { + let mut args = Args { + repo_path: None, // This would normally cause validation to fail + email: None, + name: None, + start: None, + end: None, + show_history: false, + pick_specific_commits: false, + range: false, + simulate: false, + show_diff: false, + edit_message: false, + edit_author: false, + edit_time: false, + docs: true, + _temp_dir: None, + }; + + // This should not fail even though repo_path is None, because docs mode skips validation + let result = args.ensure_all_args_present(); + assert!(result.is_ok()); + } } diff --git a/src/docs.rs b/src/docs.rs new file mode 100644 index 0000000..bd3b883 --- /dev/null +++ b/src/docs.rs @@ -0,0 +1,206 @@ +use crate::utils::types::Result; +use colored::*; +use std::fs; + +pub fn execute_docs_operation() -> Result<()> { + println!("{}", "๐Ÿ“š Opening Git Editor Documentation...".cyan().bold()); + + let docs_html = generate_comprehensive_docs()?; + + // Create a temporary HTML file + let temp_dir = std::env::temp_dir(); + let docs_file = temp_dir.join("git-editor-docs.html"); + + fs::write(&docs_file, docs_html)?; + + // Open the file in the default browser + match open_in_browser(&docs_file) { + Ok(_) => { + println!( + "{}", + "โœ… Documentation opened in your default browser!" + .green() + .bold() + ); + println!( + "{}", + format!("๐Ÿ“ File location: {}", docs_file.display()).dimmed() + ); + } + Err(_) => { + println!( + "{}", + "โš ๏ธ Could not open browser automatically.".yellow().bold() + ); + println!( + "{}", + format!("๐Ÿ“ Documentation saved at: {}", docs_file.display()).cyan() + ); + println!( + "{}", + "๐Ÿ’ก You can manually open this file in your browser.".dimmed() + ); + // Don't return an error - the docs were still successfully generated + } + } + + Ok(()) +} + +fn open_in_browser(file_path: &std::path::Path) -> Result<()> { + // Skip browser opening if NO_BROWSER environment variable is set or if running in test context + if std::env::var("NO_BROWSER").is_ok() + || std::env::var("GIT_EDITOR_NO_BROWSER").is_ok() + || cfg!(test) + { + return Err("Browser opening disabled".into()); + } + + let file_url = format!("file://{}", file_path.display()); + open::that(file_url)?; + Ok(()) +} + +fn generate_comprehensive_docs() -> Result { + // Load the HTML template from the embedded file + let template = include_str!("../docs/template.html"); + + let version = env!("CARGO_PKG_VERSION"); + let current_date = chrono::Utc::now() + .format("%Y-%m-%d %H:%M:%S UTC") + .to_string(); + + // Replace placeholders in the template + let html = template + .replace("{{VERSION}}", version) + .replace("{{DATE}}", ¤t_date); + + Ok(html) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_generate_comprehensive_docs() { + let result = generate_comprehensive_docs(); + assert!(result.is_ok()); + + let html = result.unwrap(); + + // Check that HTML template is loaded + assert!(html.contains("")); + assert!(html.contains("Git Editor - Complete Technical Documentation")); + + // Check that placeholders are replaced + assert!(html.contains(&format!("Git Editor v{}", env!("CARGO_PKG_VERSION")))); + assert!(!html.contains("{{VERSION}}")); + assert!(!html.contains("{{DATE}}")); + + // Check for key sections + assert!(html.contains("Table of Contents")); + assert!(html.contains("Overview")); + assert!(html.contains("Installation")); + assert!(html.contains("Operation Modes")); + assert!(html.contains("Command Reference")); + assert!(html.contains("Usage Examples")); + assert!(html.contains("Advanced Features")); + assert!(html.contains("Development")); + assert!(html.contains("Troubleshooting")); + + // Check for docs command reference + assert!(html.contains("--docs")); + assert!(html.contains("Open comprehensive documentation")); + } + + #[test] + fn test_docs_html_contains_expected_sections() { + let html = generate_comprehensive_docs().unwrap(); + + // Test that all main sections are present + let expected_sections = [ + "#overview", + "#installation", + "#operation-modes", + "#command-reference", + "#examples", + "#advanced-features", + "#development", + "#troubleshooting", + ]; + + for section in expected_sections { + assert!(html.contains(section), "Missing section: {section}"); + } + } + + #[test] + fn test_docs_html_contains_operation_modes() { + let html = generate_comprehensive_docs().unwrap(); + + // Test that all operation modes are documented + assert!(html.contains("Full Rewrite")); + assert!(html.contains("Show History")); + assert!(html.contains("Pick Specific")); + assert!(html.contains("Range Edit")); + assert!(html.contains("Simulation")); + assert!(html.contains("Documentation")); + + // Test that CLI flags are documented + assert!(html.contains("--show-history")); + assert!(html.contains("--pick-specific-commits")); + assert!(html.contains("--range")); + assert!(html.contains("--simulate")); + assert!(html.contains("--docs")); + } + + #[test] + fn test_docs_html_contains_examples() { + let html = generate_comprehensive_docs().unwrap(); + + // Test that usage examples are present + assert!(html.contains("git-editor --docs")); + assert!(html.contains("git-editor -s")); + assert!(html.contains("git-editor --simulate")); + assert!(html.contains("Opens this comprehensive documentation")); + } + + #[test] + fn test_version_and_date_replacement() { + let html = generate_comprehensive_docs().unwrap(); + + // Test version replacement + let expected_version = env!("CARGO_PKG_VERSION"); + assert!(html.contains(&format!("Git Editor v{expected_version}"))); + + // Test that date is properly formatted (should contain UTC) + assert!(html.contains("Generated on")); + assert!(html.contains("UTC")); + + // Test that placeholders are completely replaced + assert!(!html.contains("{{VERSION}}")); + assert!(!html.contains("{{DATE}}")); + } + + #[test] + fn test_html_structure_validity() { + let html = generate_comprehensive_docs().unwrap(); + + // Test basic HTML structure + assert!(html.starts_with("")); + assert!(html.contains("")); + assert!(html.contains("")); + assert!(html.contains("")); + assert!(html.contains("")); + assert!(html.contains("")); + + // Test that CSS is included + assert!(html.contains("