diff --git a/src/cli.rs b/src/cli.rs index 3a04a99..a6f237e 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -47,6 +47,14 @@ enum Commands { #[clap(required = true)] object: String, }, + + /// Record changes to the repository + #[clap(name = "commit", arg_required_else_help = true)] + Commit { + /// Use the given as the commit message + #[clap(short, long, value_name = "msg")] + message: String, + }, } pub fn parse() -> anyhow::Result<()> { @@ -69,6 +77,7 @@ pub fn parse() -> anyhow::Result<()> { Commands::CatFile { object } => cat_file(&context, object), Commands::WriteTree => write_tree(&context), Commands::ReadTree { object } => read_tree(&context, object), + Commands::Commit { message } => commit(&context, message), }; } @@ -101,3 +110,8 @@ fn read_tree(context: &data::Context, object: String) -> anyhow::Result<()> { context.ensure_init()?; context.read_tree(OID(object), &context.work_dir) } +fn commit(context: &data::Context, message: String) -> anyhow::Result<()> { + context.ensure_init()?; + println!("{}", context.commit(message)?); + Ok(()) +} diff --git a/src/data.rs b/src/data.rs index 919ecc1..fdf9f67 100644 --- a/src/data.rs +++ b/src/data.rs @@ -22,6 +22,9 @@ pub enum ObjectType { #[strum(serialize = "tree")] Tree, + + #[strum(serialize = "commit")] + Commit, } pub struct Context { @@ -175,12 +178,32 @@ impl Context { ))?; self.read_tree(oid, &new_path)?; } + _ => { + return Err(anyhow::Error::msg(format!( + "unexpected object type '{}' found in '{}' tree", + object_type, + path.display() + ))) + } }; } Ok(()) } + pub fn commit(&self, message: String) -> anyhow::Result { + self.hash_object( + format!( + "{}\0{}\n\n{}\n", + ObjectType::Tree, + self.write_tree(&self.work_dir)?, + message + ) + .into_bytes(), + ObjectType::Commit, + ) + } + fn is_ignored(&self, path: &PathBuf) -> bool { path.starts_with(&self.repo_dir) || path.starts_with(&self.work_dir.join("target"))