girt 0.11.2

An incremental, idiomatic Rust implementation of Git
Documentation
//! Emit inferred relationships for two stored trees using the default rename policy.
//! Run `cargo run --example rewrites -- REPOSITORY OLD_TREE NEW_TREE`.
//! Each NUL-delimited record contains an `R` or `C` marker, a three-digit similarity score, and
//! source and target byte paths.
use std::error::Error;
use std::io::{self, Write};
use std::path::PathBuf;
use std::sync::atomic::AtomicBool;

use clap::Parser;
use girt::rewrites::{Kind, Limits, Options};
use girt::{ObjectId, PackLimits, Repository};

#[derive(Parser)]
#[command(about, long_about = None)]
struct Args {
    /// Repository to open.
    repository: PathBuf,
    /// ID of the old tree.
    old_tree: ObjectId,
    /// ID of the new tree.
    new_tree: ObjectId,
}

fn main() -> Result<(), Box<dyn Error>> {
    let args = Args::parse();
    let repo = Repository::open(args.repository)?;
    let objects = repo.objects(PackLimits::default())?;
    let records = objects.detect_rewrites(
        Some(args.old_tree),
        Some(args.new_tree),
        Options::default(),
        Limits::default(),
        None,
        &AtomicBool::new(false),
    )?;
    let mut output = io::stdout().lock();
    for record in records {
        let marker = match record.kind {
            Kind::Rename => 'R',
            Kind::Copy => 'C',
            _ => return Err("unsupported rewrite kind".into()),
        };
        write!(output, "{marker}{:03}\0", record.similarity)?;
        output.write_all(&record.source)?;
        output.write_all(&[0])?;
        output.write_all(&record.target)?;
        output.write_all(&[0])?;
    }
    Ok(())
}