started work on git module.
This commit is contained in:
		
							parent
							
								
									437a4bfa13
								
							
						
					
					
						commit
						d113289fd2
					
				
					 5 changed files with 65 additions and 12 deletions
				
			
		
							
								
								
									
										8
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							| 
						 | 
					@ -284,9 +284,9 @@ dependencies = [
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "git2"
 | 
					name = "git2"
 | 
				
			||||||
version = "0.18.1"
 | 
					version = "0.18.2"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "fbf97ba92db08df386e10c8ede66a2a0369bd277090afd8710e19e38de9ec0cd"
 | 
					checksum = "1b3ba52851e73b46a4c3df1d89343741112003f0f6f13beb0dfac9e457c3fdcd"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "bitflags 2.4.2",
 | 
					 "bitflags 2.4.2",
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
| 
						 | 
					@ -377,9 +377,9 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "libgit2-sys"
 | 
					name = "libgit2-sys"
 | 
				
			||||||
version = "0.16.1+1.7.1"
 | 
					version = "0.16.2+1.7.2"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "f2a2bb3680b094add03bb3732ec520ece34da31a8cd2d633d1389d0f0fb60d0c"
 | 
					checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "cc",
 | 
					 "cc",
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@ description = "Utility to modify commit timestamps of a git repository"
 | 
				
			||||||
chrono = "0.4.33"
 | 
					chrono = "0.4.33"
 | 
				
			||||||
chrono-tz = "0.8.5"
 | 
					chrono-tz = "0.8.5"
 | 
				
			||||||
clap = { version = "4.4.18", features = ["derive"] }
 | 
					clap = { version = "4.4.18", features = ["derive"] }
 | 
				
			||||||
git2 = "0.18.1"
 | 
					git2 = "0.18.2"
 | 
				
			||||||
iana-time-zone = "0.1.60"
 | 
					iana-time-zone = "0.1.60"
 | 
				
			||||||
itertools = "0.12.1"
 | 
					itertools = "0.12.1"
 | 
				
			||||||
once_cell = "1.19.0"
 | 
					once_cell = "1.19.0"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										47
									
								
								src/git.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/git.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,47 @@
 | 
				
			||||||
 | 
					use chrono::Duration;
 | 
				
			||||||
 | 
					use git2::{Commit, Repository};
 | 
				
			||||||
 | 
					use itertools::Itertools;
 | 
				
			||||||
 | 
					use thiserror::Error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::time::{distribute_across_ranges_with_jitter, TimeRange};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Error)]
 | 
				
			||||||
 | 
					pub(crate) enum GitErrors {
 | 
				
			||||||
 | 
					    #[error("end is not a parent of start")]
 | 
				
			||||||
 | 
					    NotAParent,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[error("{0} is not a commit hash in the repo")]
 | 
				
			||||||
 | 
					    NotACommit(String),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// find the number of commits between start and end,
 | 
				
			||||||
 | 
					/// where end is a parent commit of start
 | 
				
			||||||
 | 
					fn get_no_of_commits(start: &Commit, end: &Commit) -> Result<u32, GitErrors> {
 | 
				
			||||||
 | 
					    match start.parent_ids().find_position(|sha| sha == &end.id()) {
 | 
				
			||||||
 | 
					        Some(tuple) => Ok(tuple.0.try_into().expect("commit has over 2^32 parents")),
 | 
				
			||||||
 | 
					        None => Err(GitErrors::NotAParent),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// will need to do an in memory rebase, ammending each commit with a new signature.
 | 
				
			||||||
 | 
					pub fn rebase_commits_across_timerange<Tz: chrono::TimeZone>(
 | 
				
			||||||
 | 
					    repo: &Repository,
 | 
				
			||||||
 | 
					    start_sha: &str,
 | 
				
			||||||
 | 
					    end_sha: &str,
 | 
				
			||||||
 | 
					    ranges: &[TimeRange<Tz>],
 | 
				
			||||||
 | 
					    max_jitter: &Duration,
 | 
				
			||||||
 | 
					) -> Result<(), GitErrors> {
 | 
				
			||||||
 | 
					    let start_commit = if let Ok(commit) = repo.find_commit_by_prefix(start_sha) {
 | 
				
			||||||
 | 
					        commit
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return Err(GitErrors::NotACommit(start_sha.to_string()));
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    let end_commit = if let Ok(commit) = repo.find_commit_by_prefix(end_sha) {
 | 
				
			||||||
 | 
					        commit
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return Err(GitErrors::NotACommit(end_sha.to_string()));
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    let num_commits = get_no_of_commits(&start_commit, &end_commit)?;
 | 
				
			||||||
 | 
					    let times = distribute_across_ranges_with_jitter(ranges, num_commits, max_jitter);
 | 
				
			||||||
 | 
					    todo!()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										19
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								src/main.rs
									
										
									
									
									
								
							| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
mod args;
 | 
					mod args;
 | 
				
			||||||
mod err;
 | 
					mod err;
 | 
				
			||||||
 | 
					mod git;
 | 
				
			||||||
mod time;
 | 
					mod time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use chrono::prelude::*;
 | 
					use chrono::prelude::*;
 | 
				
			||||||
| 
						 | 
					@ -9,13 +10,19 @@ use clap::Parser;
 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
    let cli = args::Cli::parse();
 | 
					    let cli = args::Cli::parse();
 | 
				
			||||||
    println!("{:#?}", cli);
 | 
					    println!("{:#?}", cli);
 | 
				
			||||||
    let start_time = match cli.timezone {
 | 
					    let tz = cli
 | 
				
			||||||
        Some(tz) => tz.from_local_datetime(&cli.start_time).unwrap(),
 | 
					        .timezone
 | 
				
			||||||
        None => get_local_timezone()
 | 
					        .unwrap_or_else(|| get_local_timezone().expect("Could not get local timezone"));
 | 
				
			||||||
            .expect("Could not get local timezone")
 | 
					    let start_time = tz.from_local_datetime(&cli.start_time).unwrap();
 | 
				
			||||||
            .from_local_datetime(&cli.start_time)
 | 
					    let end_time = if let Some(time) = cli.end_time {
 | 
				
			||||||
            .unwrap(),
 | 
					        tz.from_local_datetime(&time).unwrap()
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        Utc::now().with_timezone(&tz)
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					    println!(
 | 
				
			||||||
 | 
					        "start_time = {:#?}, end_time = {:#?}, tz = {:#?}",
 | 
				
			||||||
 | 
					        start_time, end_time, tz
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn get_local_timezone() -> Result<Tz, String> {
 | 
					fn get_local_timezone() -> Result<Tz, String> {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,6 @@ pub struct TimeRange<Tz: chrono::TimeZone> {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<Tz: chrono::TimeZone> TimeRange<Tz> {
 | 
					impl<Tz: chrono::TimeZone> TimeRange<Tz> {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// whether a time instance lies within the time range
 | 
					    /// whether a time instance lies within the time range
 | 
				
			||||||
    pub fn is_in_range<Otz: chrono::TimeZone>(&self, other: &DateTime<Otz>) -> bool {
 | 
					    pub fn is_in_range<Otz: chrono::TimeZone>(&self, other: &DateTime<Otz>) -> bool {
 | 
				
			||||||
        (self.start <= *other) && (other <= &self.end)
 | 
					        (self.start <= *other) && (other <= &self.end)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue