Rust git2 change dates.


Kerrigan Sara
Write rust application which uses git2 and changes date of each commit between selected dates

Here's an example of a Rust application that uses the git2 crate to change the date of each commit between two selected dates:

Copy code
extern crate git2;
use git2::{Repository, Signature, Time};
use std::path::Path;

fn main() {
    let repo_path = Path::new("path/to/repo");
    let repo = Repository::open(repo_path).unwrap();

    // The dates between which to change the commit dates
    let start_date = "2022-01-01";
    let end_date = "2022-12-31";

    let start_time = Time::new(time::strptime(start_date, "%Y-%m-%d").unwrap().to_timespec());
    let end_time = Time::new(time::strptime(end_date, "%Y-%m-%d").unwrap().to_timespec());

    let head = repo.head().unwrap();
    let mut walker = repo.revwalk().unwrap();
    walker.push(head.target().unwrap()).unwrap();

    let mut current_time = start_time;
    let time_diff = end_time.seconds() - start_time.seconds();
    let mut seconds_since_start = 0;

    // Iterate through the commits
    for oid in walker {
        let oid = oid.unwrap();
        let commit = repo.find_commit(oid).unwrap();

        let new_time = Time::new(current_time.seconds() + seconds_since_start);
        let new_signature = Signature::now("User Name", "user@example.com").unwrap();

        // Set the new commit date
        commit.update_header(|_, _| {
            Ok((new_time, new_signature))
        }).unwrap();

        let duration_to_next_commit = time::Duration::seconds(time_diff/oid.to_string().len() as i64);
        current_time = Time::new(current_time.seconds() + duration_to_next_commit.num_seconds());
        seconds_since_start += duration_to_next_commit.num_seconds();
    }
}
This application assumes that you have a Git repository located at the path path/to/repo. It uses git2 to open the repository and then uses the Repository::revwalk method to iterate through the commits.

It first defines the start and end date to be between which you would like to change the commit date.
It also defines a variable seconds_since_start to maintain the duration between current commit and the start date.
Next it use Time::new() to create the Time instance from the passed in start and end date.
Next it pushes the head target and iterate through the commits in the walker.
For each commit, it calculates the new time for the commit. The new time is obtained by adding the duration between the start and this commit to the start time.
It then uses commit.update_header function to update the commit with the new time.
Also, it update the seconds_since_start variable with the duration between current commit and the next commit, so that we can use it




Kerrigan Sara
Signature must not be changed, only timestamp 

Sure, here's an updated version of the application that only changes the timestamp of the commits and leaves the signature intact:

Copy code
extern crate git2;
use git2::{Repository, Time};
use std::path::Path;

fn main() {
    let repo_path = Path::new("path/to/repo");
    let repo = Repository::open(repo_path).unwrap();

    // The dates between which to change the commit dates
    let start_date = "2022-01-01";
    let end_date = "2022-12-31";

    let start_time = Time::new(time::strptime(start_date, "%Y-%m-%d").unwrap().to_timespec());
    let end_time = Time::new(time::strptime(end_date, "%Y-%m-%d").unwrap().to_timespec());

    let head = repo.head().unwrap();
    let mut walker = repo.revwalk().unwrap();
    walker.push(head.target().unwrap()).unwrap();

    let mut current_time = start_time;
    let time_diff = end_time.seconds() - start_time.seconds();
    let mut seconds_since_start = 0;

    // Iterate through the commits
    for oid in walker {
        let oid = oid.unwrap();
        let commit = repo.find_commit(oid).unwrap();

        let signature = commit.author();
        let new_time = Time::new(current_time.seconds() + seconds_since_start);

        // Set the new commit date
        commit.update_header(|_, old_commit| {
            Ok((new_time, signature.clone()))
        }).unwrap();

        let duration_to_next_commit = time::Duration::seconds(time_diff/oid.to_string().len() as i64);
        current_time = Time::new(current_time.seconds() + duration_to_next_commit.num_seconds());
        seconds_since_start += duration_to_next_commit.num_seconds();
    }
}

Изменить пасту