diff --git a/CHANGELOG.md b/CHANGELOG.md index 0249bee..283d2f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] + +## [0.8.0] - 05-29-2024 +- Properly set local HEAD to fetched git repo `crates.io-index` when updating from previous zerus invocation + ## [0.7.0] - 04-11-2024 - Add automatic crates.io git clone and fetch for mirror diff --git a/Cargo.lock b/Cargo.lock index cfa14ea..0ef8034 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1542,7 +1542,7 @@ checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" [[package]] name = "zerus" -version = "0.7.0" +version = "0.8.0" dependencies = [ "anyhow", "clap", diff --git a/Cargo.toml b/Cargo.toml index 6bff328..241b26d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zerus" -version = "0.7.0" +version = "0.8.0" edition = "2021" authors = ["wcampbell"] description = "Lightweight binary to download only project required crates for offline crates.io mirror" diff --git a/src/git.rs b/src/git.rs index 3add8da..cb343d8 100644 --- a/src/git.rs +++ b/src/git.rs @@ -98,7 +98,7 @@ pub fn clone(repo_path: &Path) -> Result<(), git2::Error> { Ok(()) } -pub fn fetch(repo: &Path) -> Result<(), git2::Error> { +pub fn pull(repo: &Path) -> Result<(), git2::Error> { let repo = Repository::open(repo)?; let remote = "origin"; @@ -188,5 +188,50 @@ pub fn fetch(repo: &Path) -> Result<(), git2::Error> { // needed objects are available locally. remote.update_tips(None, true, AutotagOption::Unspecified, None)?; + let fetch_head = repo.find_reference("FETCH_HEAD")?; + let fetch_commit = repo.reference_to_annotated_commit(&fetch_head)?; + + let refname = "refs/heads/master"; + match repo.find_reference(refname) { + Ok(mut r) => { + fast_forward(&repo, &mut r, &fetch_commit)?; + } + Err(_) => { + // The branch doesn't exist so just set the reference to the + // commit directly. Usually this is because you are pulling + // into an empty repository. + repo.reference( + refname, + fetch_commit.id(), + true, + &format!("Setting master to {}", fetch_commit.id()), + )?; + repo.set_head(refname)?; + repo.checkout_head(Some( + git2::build::CheckoutBuilder::default() + .allow_conflicts(true) + .conflict_style_merge(true) + .force(), + ))?; + } + } + + Ok(()) +} + +fn fast_forward( + repo: &Repository, + lb: &mut git2::Reference, + rc: &git2::AnnotatedCommit, +) -> Result<(), git2::Error> { + let name = match lb.name() { + Some(s) => s.to_string(), + None => String::from_utf8_lossy(lb.name_bytes()).to_string(), + }; + let msg = format!("Fast-Forward: Setting {} to id: {}", name, rc.id()); + println!("{}", msg); + lb.set_target(rc.id(), &msg)?; + repo.set_head(&name)?; + repo.checkout_head(None)?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index 49513be..f134c3c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ use guppy::MetadataCommand; use rayon::prelude::*; use reqwest::blocking::Client; -use crate::git::{clone, fetch}; +use crate::git::{clone, pull}; mod git; @@ -54,7 +54,7 @@ fn main() { println!("[-] Syncing git index crates.io"); let repo = args.mirror_path.join("crates.io-index"); if repo.exists() { - fetch(Path::new(&repo)).unwrap(); + pull(Path::new(&repo)).unwrap(); } else { clone(Path::new(&repo)).unwrap(); }