use girt::refs::{Expected, RefEdit, Reflog, TransactionError};
use girt::{Commit, CommitFields, Repository, Signature, Tree};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let directory = tempfile::tempdir()?;
let repo = Repository::init(
girt::ObjectFormat::Sha256,
directory.path().join("repository"),
girt::InitKind::Bare,
)?;
let objects = repo.loose_objects();
let tree = objects.write_tree(&Tree::new(girt::ObjectFormat::Sha256, Vec::new())?)?;
let committer = Signature {
name: b"Example Writer".to_vec(),
email: b"writer@example.com".to_vec(),
seconds: 1700000000,
offset_minutes: 0,
};
let commit = Commit::new(CommitFields {
tree,
parents: Vec::new(),
author: committer.clone(),
committer: committer.clone(),
extra_headers: Vec::new(),
message: b"Initial commit\n".to_vec(),
})?;
let id = objects.write_commit(&commit)?;
let head = girt::refs::RefName::new("HEAD")?;
let tag = girt::refs::RefName::new("refs/tags/initial")?;
let edits = [
{
let input = RefEdit::new(
head.clone(),
Some(girt::refs::Target::Direct(id)),
Expected::Absent,
Reflog::Append {
committer: committer.clone(),
message: b"initial publication".to_vec(),
},
);
input.with_dereference(true)
},
RefEdit::new(
tag.clone(),
Some(girt::refs::Target::Direct(id)),
Expected::Absent,
Reflog::Append {
committer: committer.clone(),
message: b"mark initial".to_vec(),
},
),
];
let refs = repo.references()?;
match refs.transaction(&edits) {
Ok(outcomes) => println!("Published: {outcomes:?}"),
Err(TransactionError::Prepare { operation, source }) => {
eprintln!("No refs or logs changed; operation {operation:?}: {source}");
return Err(source.into());
}
Err(error @ TransactionError::Publish { .. }) => {
eprintln!("Partial publication: {error:?}");
return Err(error.into());
}
Err(error) => return Err(error.into()),
}
refs.transaction(&[RefEdit::new(
tag.clone(),
None,
Expected::Value(girt::refs::Target::Direct(id)),
Reflog::Append {
committer,
message: b"remove temporary tag".to_vec(),
},
)])?;
assert_eq!(refs.reflog(&head)?.unwrap().len(), 1);
assert_eq!(refs.reflog(&tag)?.unwrap().len(), 2);
assert_eq!(refs.read(&tag)?, None);
let keep = girt::refs::RefName::new("refs/jj/keep-example")?;
refs.transaction(&[RefEdit::new(
keep.clone(),
Some(girt::refs::Target::Direct(id)),
Expected::AbsentOr(girt::refs::Target::Direct(id)),
Reflog::Preserve,
)])?;
refs.transaction(&[RefEdit::new(keep, None, Expected::Exists, Reflog::Delete)])?;
Ok(())
}