use itertools::Itertools;
use lib::core::eventlog::testing::redact_event_timestamp;
use lib::core::eventlog::EventLogDb;
use lib::git::GitVersion;
use lib::testing::{make_git, GitInitOptions};
#[test]
fn test_gc() -> eyre::Result<()> {
let git = make_git()?;
git.init_repo()?;
git.detach_head()?;
git.commit_file("test1", 1)?;
git.run(&["checkout", "HEAD^"])?;
{
let repo = git.get_repo()?;
assert!(repo.revparse_single_commit("62fc20d2").is_ok());
}
git.run(&["gc", "--prune=now"])?;
{
let stdout = git.smartlog()?;
insta::assert_snapshot!(stdout, @r###"
@ f777ecc (master) create initial.txt
|
o 62fc20d create test1.txt
"###);
}
git.branchless("hide", &["62fc20d2"])?;
{
let (stdout, _stderr) = git.branchless("gc", &[])?;
insta::assert_snapshot!(stdout, @r###"
branchless: collecting garbage
branchless: 1 dangling reference deleted
"###);
}
git.run(&["gc", "--prune=now"])?;
{
let stdout = git.smartlog()?;
insta::assert_snapshot!(stdout, @"@ f777ecc (master) create initial.txt
");
}
{
let repo = git.get_repo()?;
assert!(repo.revparse_single_commit("62fc20d2")?.is_none())
}
Ok(())
}
#[test]
fn test_gc_reference_transaction() -> eyre::Result<()> {
let git = make_git()?;
if !git.supports_reference_transactions()? {
return Ok(());
}
let git_version = git.get_version()?;
if git_version >= GitVersion(2, 35, 0) {
return Ok(());
}
git.init_repo()?;
git.commit_file("test1", 1)?;
git.detach_head()?;
git.commit_file("test2", 2)?;
git.branchless("hide", &["HEAD"])?;
git.run(&["checkout", "HEAD^"])?;
{
let (stdout, _stderr) = git.branchless("gc", &[])?;
insta::assert_snapshot!(stdout, @r###"
branchless: collecting garbage
branchless: 1 dangling reference deleted
"###);
}
git.run(&["gc", "--prune=now"])?;
let conn = git.get_repo()?.get_db_conn()?;
let event_log = EventLogDb::new(&conn)?;
let events = event_log
.get_events()?
.into_iter()
.map(redact_event_timestamp)
.collect_vec();
insta::assert_debug_snapshot!(events, @r###"
[
RefUpdateEvent {
timestamp: 0.0,
event_tx_id: Id(
1,
),
ref_name: ReferenceName(
"HEAD",
),
old_oid: f777ecc9b0db5ed372b2615695191a8a17f79f24,
new_oid: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
message: None,
},
RefUpdateEvent {
timestamp: 0.0,
event_tx_id: Id(
1,
),
ref_name: ReferenceName(
"refs/heads/master",
),
old_oid: f777ecc9b0db5ed372b2615695191a8a17f79f24,
new_oid: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
message: None,
},
CommitEvent {
timestamp: 0.0,
event_tx_id: Id(
2,
),
commit_oid: NonZeroOid(62fc20d2a290daea0d52bdc2ed2ad4be6491010e),
},
RefUpdateEvent {
timestamp: 0.0,
event_tx_id: Id(
3,
),
ref_name: ReferenceName(
"HEAD",
),
old_oid: 0000000000000000000000000000000000000000,
new_oid: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
message: None,
},
RefUpdateEvent {
timestamp: 0.0,
event_tx_id: Id(
4,
),
ref_name: ReferenceName(
"HEAD",
),
old_oid: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
new_oid: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
message: None,
},
RefUpdateEvent {
timestamp: 0.0,
event_tx_id: Id(
5,
),
ref_name: ReferenceName(
"HEAD",
),
old_oid: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
new_oid: 96d1c37a3d4363611c49f7e52186e189a04c531f,
message: None,
},
CommitEvent {
timestamp: 0.0,
event_tx_id: Id(
6,
),
commit_oid: NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
},
ObsoleteEvent {
timestamp: 0.0,
event_tx_id: Id(
7,
),
commit_oid: NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
},
RefUpdateEvent {
timestamp: 0.0,
event_tx_id: Id(
8,
),
ref_name: ReferenceName(
"HEAD",
),
old_oid: 0000000000000000000000000000000000000000,
new_oid: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
message: None,
},
RefUpdateEvent {
timestamp: 0.0,
event_tx_id: Id(
9,
),
ref_name: ReferenceName(
"HEAD",
),
old_oid: 96d1c37a3d4363611c49f7e52186e189a04c531f,
new_oid: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
message: None,
},
RefUpdateEvent {
timestamp: 0.0,
event_tx_id: Id(
10,
),
ref_name: ReferenceName(
"refs/heads/master",
),
old_oid: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
new_oid: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
message: None,
},
RefUpdateEvent {
timestamp: 0.0,
event_tx_id: Id(
11,
),
ref_name: ReferenceName(
"refs/heads/master",
),
old_oid: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
new_oid: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
message: None,
},
]
"###);
Ok(())
}
#[test]
fn test_gc_no_init() -> eyre::Result<()> {
let git = make_git()?;
if !git.supports_reference_transactions()? {
return Ok(());
}
git.init_repo_with_options(&GitInitOptions {
run_branchless_init: false,
..Default::default()
})?;
git.detach_head()?;
let test1_oid = git.commit_file("test1", 1)?;
{
let stdout = git.smartlog()?;
insta::assert_snapshot!(stdout, @r###"
O f777ecc (master) create initial.txt
|
@ 62fc20d create test1.txt
"###);
}
git.run(&["checkout", "HEAD~"])?;
{
let (stdout, stderr) = git.run(&["gc", "--prune=now"])?;
insta::assert_snapshot!(stderr, @"");
insta::assert_snapshot!(stdout, @"");
}
git.run(&["checkout", &test1_oid.to_string()])?;
{
let stdout = git.smartlog()?;
insta::assert_snapshot!(stdout, @r###"
O f777ecc (master) create initial.txt
|
@ 62fc20d create test1.txt
"###);
}
git.run(&["checkout", "HEAD~"])?;
git.branchless("gc", &[])?;
{
let (stdout, stderr) = git.run(&["gc", "--prune=now"])?;
insta::assert_snapshot!(stderr, @"");
insta::assert_snapshot!(stdout, @"");
}
git.run(&["checkout", &test1_oid.to_string()])?;
{
let stdout = git.smartlog()?;
insta::assert_snapshot!(stdout, @r###"
O f777ecc (master) create initial.txt
|
@ 62fc20d create test1.txt
"###);
}
Ok(())
}