Skip to content

Commit

Permalink
Add support for shallow clones (#288)
Browse files Browse the repository at this point in the history
* Add support for shallow clones to repo_util
Added check for shallow clone to gix

* rustfmt

* Fixed broken tests

* Added shallow clone tests to git2 and gitcl

* Tweaked get_commit

* Lint fix
  • Loading branch information
CraZySacX authored Jan 14, 2024
1 parent a8556fc commit 51642f6
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 32 deletions.
35 changes: 22 additions & 13 deletions repo_util/src/repo/mod.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
use anyhow::Result;
use git::{
clone::PrepareFetch,
config::CommitAutoRollback,
create::Options,
create::{Kind, Options},
interrupt::IS_INTERRUPTED,
objs::{
tree::{Entry, EntryKind},
Tree,
},
open,
path::os_str_into_bstr,
progress::Discard,
refs::transaction::PreviousValue,
remote::fetch::Shallow,
url::parse,
Id, ObjectId,
};
use gix as git;
use rand::{distributions::Alphanumeric, thread_rng, Rng};
use std::fs::File;
use std::{
env,
fs::{self, OpenOptions},
io::{BufWriter, Write},
path::PathBuf,
};
use std::{fs::File, num::NonZeroU32};

const BARE_REPO_PREFIX: &str = "vergen_tmp";
const BARE_REPO_SUFFIX: &str = ".git";
Expand All @@ -41,7 +47,7 @@ impl TestRepos {
///
/// # Errors
///
pub fn new(modify_tracked: bool, include_untracked: bool) -> Result<Self> {
pub fn new(modify_tracked: bool, include_untracked: bool, shallow_clone: bool) -> Result<Self> {
let bare_repo_path = Self::repo_path();
let clone_path = Self::clone_path();

Expand All @@ -51,7 +57,7 @@ impl TestRepos {
};

test_repo.create_repository()?;
test_repo.clone_from_bare_repo()?;
test_repo.clone_from_bare_repo(shallow_clone)?;

if modify_tracked {
test_repo.modify_tracked()?;
Expand Down Expand Up @@ -131,7 +137,7 @@ impl TestRepos {
Ok(())
}

fn clone_from_bare_repo(&mut self) -> Result<()> {
fn clone_from_bare_repo(&mut self, shallow_clone: bool) -> Result<()> {
let bare_repo_path = &self.bare_repo_path;
let clone_path = &self.clone_path;

Expand All @@ -144,20 +150,23 @@ impl TestRepos {
fs::create_dir_all(clone_path)?;

// Clone into the directory
let url = git::url::parse(git::path::os_str_into_bstr(bare_repo_path.as_os_str())?)?;
let url = parse(os_str_into_bstr(bare_repo_path.as_os_str())?)?;
let opts = open::Options::isolated()
.config_overrides(["user.name=Vergen Test", "user.email=vergen@blah.com"]);
let mut prep = git::clone::PrepareFetch::new(
let mut prep = PrepareFetch::new(
url,
clone_path,
git::create::Kind::WithWorktree,
Kind::WithWorktree,
Options::default(),
opts,
)?;
let (mut prepare_checkout, _) =
prep.fetch_then_checkout(git::progress::Discard, &git::interrupt::IS_INTERRUPTED)?;
let (_repo, _) = prepare_checkout
.main_worktree(git::progress::Discard, &git::interrupt::IS_INTERRUPTED)?;
if shallow_clone {
if let Some(one) = NonZeroU32::new(1) {
prep = prep.with_shallow(Shallow::DepthAtRemote(one));
}
}
let (mut prepare_checkout, _) = prep.fetch_then_checkout(Discard, &IS_INTERRUPTED)?;
let (_repo, _) = prepare_checkout.main_worktree(Discard, &IS_INTERRUPTED)?;

Ok(())
}
Expand Down Expand Up @@ -260,7 +269,7 @@ mod test {
fn temp_dir_works() -> Result<()> {
temp_env::with_var(RUNNER_TEMP_ENV, None::<String>, || {
let repo = || -> Result<TestRepos> {
let repo = TestRepos::new(false, false)?;
let repo = TestRepos::new(false, false, false)?;
Ok(repo)
}();
assert!(repo.is_ok());
Expand Down
16 changes: 15 additions & 1 deletion vergen/src/feature/git/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ mod test {
#[test]
#[serial_test::serial]
fn git_all_at_path() -> Result<()> {
let repo = TestRepos::new(false, false)?;
let repo = TestRepos::new(false, false, false)?;
let config = EmitBuilder::builder()
.all_git()
.test_emit_at(Some(repo.path()))?;
Expand All @@ -972,6 +972,20 @@ mod test {
Ok(())
}

#[test]
#[serial_test::serial]
fn git_all_shallow_clone() -> Result<()> {
let repo = TestRepos::new(false, false, true)?;
let emitter = EmitBuilder::builder()
.all_git()
.test_emit_at(Some(repo.path()))?;
assert_eq!(10, emitter.cargo_rustc_env_map.len());
assert_eq!(0, count_idempotent(&emitter.cargo_rustc_env_map));
assert_eq!(0, emitter.warnings.len());

Ok(())
}

#[test]
#[serial_test::serial]
fn git_all_dirty_tags_short() -> Result<()> {
Expand Down
16 changes: 15 additions & 1 deletion vergen/src/feature/git/git2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ mod test {
#[test]
#[serial_test::serial]
fn head_not_found_is_default() -> Result<()> {
let repo = TestRepos::new(false, false)?;
let repo = TestRepos::new(false, false, false)?;
let mut map = BTreeMap::new();
let mut warnings = vec![];
if let Ok(repo) = Repository::discover(env::current_dir()?) {
Expand Down Expand Up @@ -745,6 +745,20 @@ mod test {
Ok(())
}

#[test]
#[serial_test::serial]
fn git_all_shallow_clone() -> Result<()> {
let repo = TestRepos::new(false, false, true)?;
let emitter = EmitBuilder::builder()
.all_git()
.test_emit_at(Some(repo.path()))?;
assert_eq!(10, emitter.cargo_rustc_env_map.len());
assert_eq!(0, count_idempotent(&emitter.cargo_rustc_env_map));
assert_eq!(0, emitter.warnings.len());

Ok(())
}

#[test]
#[serial_test::serial]
fn git_all_idempotent_no_warn() -> Result<()> {
Expand Down
37 changes: 32 additions & 5 deletions vergen/src/feature/git/gix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ use crate::{
key::VergenKey,
utils::fns::{add_default_map_entry, add_map_entry},
};
#[cfg(test)]
use anyhow::anyhow;
use anyhow::{Error, Result};
use gix::{head::Kind, Commit, Head};
use gix::{head::Kind, Commit, Head, Id, Repository};
use std::{
env,
path::{Path, PathBuf},
Expand Down Expand Up @@ -372,8 +371,7 @@ impl EmitBuilder {
let repo = gix::discover(curr_dir)?;
let mut head = repo.head()?;
let git_path = repo.git_dir().to_path_buf();
let commit = head.peel_to_commit_in_place()?;
eprintln!("Commit ID: {}", commit.id);
let commit = Self::get_commit(&repo, &mut head)?;

if !idempotent && self.any() {
self.add_rerun_if_changed(&head, &git_path, rerun_if_changed);
Expand Down Expand Up @@ -474,6 +472,20 @@ impl EmitBuilder {
Ok(())
}

fn get_commit<'a>(repo: &Repository, head: &mut Head<'a>) -> Result<Commit<'a>> {
Ok(if repo.is_shallow() {
let id = Self::get_id(head)?.ok_or_else(|| anyhow!("Not an Id"))?;
let object = id.try_object()?.ok_or_else(|| anyhow!("Not an Object"))?;
object.try_into_commit()?
} else {
head.peel_to_commit_in_place()?
})
}

fn get_id<'a>(head: &mut Head<'a>) -> Result<Option<Id<'a>>> {
head.try_peel_to_id_in_place().map_err(Into::into)
}

fn add_git_timestamp_entries(
&self,
commit: &Commit<'_>,
Expand Down Expand Up @@ -585,6 +597,7 @@ mod test {
use crate::{emitter::test::count_idempotent, EmitBuilder};
use anyhow::Result;
use repo_util::TestRepos;
use serial_test::serial;

#[test]
#[serial_test::serial]
Expand Down Expand Up @@ -626,7 +639,7 @@ mod test {
#[test]
#[serial_test::serial]
fn git_all_at_path() -> Result<()> {
let repo = TestRepos::new(false, false)?;
let repo = TestRepos::new(false, false, false)?;
let emitter = EmitBuilder::builder()
.all_git()
.test_emit_at(Some(repo.path()))?;
Expand All @@ -636,6 +649,20 @@ mod test {
Ok(())
}

#[test]
#[serial]
fn git_all_shallow_clone() -> Result<()> {
let repo = TestRepos::new(false, false, true)?;
let emitter = EmitBuilder::builder()
.all_git()
.test_emit_at(Some(repo.path()))?;
assert_eq!(10, emitter.cargo_rustc_env_map.len());
assert_eq!(0, count_idempotent(&emitter.cargo_rustc_env_map));
assert_eq!(0, emitter.warnings.len());

Ok(())
}

#[test]
#[serial_test::serial]
fn git_error_fails() -> Result<()> {
Expand Down
24 changes: 12 additions & 12 deletions vergen/tests/git_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH";
#[test]
#[serial_test::serial]
fn git_all_flags_test_repo() -> Result<()> {
let repo = TestRepos::new(true, false)?;
let repo = TestRepos::new(true, false, false)?;
let mut stdout_buf = vec![];
let failed = EmitBuilder::builder()
.all_git()
Expand All @@ -201,7 +201,7 @@ cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH";
#[test]
#[serial_test::serial]
fn git_all_flags_test_repo_local() -> Result<()> {
let repo = TestRepos::new(true, false)?;
let repo = TestRepos::new(true, false, false)?;
let mut stdout_buf = vec![];
let result = EmitBuilder::builder()
.all_git()
Expand Down Expand Up @@ -229,7 +229,7 @@ cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH";
#[test]
#[serial_test::serial]
fn git_all_output_test_repo() -> Result<()> {
let repo = TestRepos::new(true, true)?;
let repo = TestRepos::new(true, true, false)?;
let mut stdout_buf = vec![];
let failed = EmitBuilder::builder()
.all_git()
Expand Down Expand Up @@ -258,7 +258,7 @@ cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH";
#[test]
#[serial_test::serial]
fn git_emit_at_test_repo() -> Result<()> {
let repo = TestRepos::new(true, false)?;
let repo = TestRepos::new(true, false, false)?;
assert!(EmitBuilder::builder()
.all_git()
.git_describe(true, true, None)
Expand Down Expand Up @@ -293,7 +293,7 @@ cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH";
fn git_dirty_ignore_untracked_no_modified_no_untracked() -> Result<()> {
// On a repository with no modified files and no untracked files,
// dirty should be false.
let repo = TestRepos::new(false, false)?;
let repo = TestRepos::new(false, false, false)?;

let mut stdout_buf = vec![];
EmitBuilder::builder()
Expand All @@ -311,7 +311,7 @@ cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH";
fn git_dirty_include_untracked_no_modified_no_untracked() -> Result<()> {
// On a repository with no modified files and no untracked files,
// dirty should be false.
let repo = TestRepos::new(false, false)?;
let repo = TestRepos::new(false, false, false)?;

let mut stdout_buf = vec![];
EmitBuilder::builder()
Expand All @@ -329,7 +329,7 @@ cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH";
fn git_dirty_ignore_untracked_modified_no_untracked() -> Result<()> {
// On a repository with modified files and no untracked files,
// dirty should be true.
let repo = TestRepos::new(true, false)?;
let repo = TestRepos::new(true, false, false)?;

let mut stdout_buf = vec![];
EmitBuilder::builder()
Expand All @@ -347,7 +347,7 @@ cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH";
fn git_dirty_include_untracked_modified_no_untracked() -> Result<()> {
// On a repository with modified files and no untracked files,
// dirty should be true.
let repo = TestRepos::new(true, false)?;
let repo = TestRepos::new(true, false, false)?;

let mut stdout_buf = vec![];
EmitBuilder::builder()
Expand All @@ -365,7 +365,7 @@ cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH";
fn git_dirty_ignore_untracked_no_modified_untracked() -> Result<()> {
// On a repository with no modified files and untracked files,
// dirty should be false when include_untracked is false.
let repo = TestRepos::new(false, true)?;
let repo = TestRepos::new(false, true, false)?;

let mut stdout_buf = vec![];
EmitBuilder::builder()
Expand All @@ -383,7 +383,7 @@ cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH";
fn git_dirty_include_untracked_no_modified_untracked() -> Result<()> {
// On a repository with no modified files and untracked files,
// dirty should be true when include_untracked is true.
let repo = TestRepos::new(false, true)?;
let repo = TestRepos::new(false, true, false)?;

let mut stdout_buf = vec![];
EmitBuilder::builder()
Expand All @@ -401,7 +401,7 @@ cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH";
fn git_dirty_ignore_untracked_modified_untracked() -> Result<()> {
// On a repository with modified files and untracked files,
// dirty should be true.
let repo = TestRepos::new(true, true)?;
let repo = TestRepos::new(true, true, false)?;

let mut stdout_buf = vec![];
EmitBuilder::builder()
Expand All @@ -419,7 +419,7 @@ cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH";
fn git_dirty_include_untracked_modified_untracked() -> Result<()> {
// On a repository with modified files and untracked files,
// dirty should be true.
let repo = TestRepos::new(true, true)?;
let repo = TestRepos::new(true, true, false)?;

let mut stdout_buf = vec![];
EmitBuilder::builder()
Expand Down

0 comments on commit 51642f6

Please sign in to comment.