1use std::path::Path;
2
3use git2::{Commit, Direction, ObjectType, Repository};
4
5pub fn find_last_commit(repo: &Repository) -> Result<Option<Commit>, git2::Error> {
6 let head = repo.head();
7
8 let obj = match head {
9 Ok(head_ref) => head_ref.resolve()?.peel(ObjectType::Commit)?,
10 Err(_) => return Ok(None),
11 };
12
13 Ok(Some(obj.into_commit().map_err(|_| {
14 git2::Error::from_str("Couldn't find commit") })?))
16}
17
18pub fn add_and_commit(
19 repo: &Repository,
20 file_path: &Path,
21 message: &str,
22) -> Result<(), git2::Error> {
23 let mut index = repo.index()?;
24 index.add_path(file_path)?;
25 index.write()?;
26 let oid = index.write_tree()?;
27 let signature = Repository::signature(repo)?;
28 let tree = repo.find_tree(oid)?;
29
30 let last_commit = find_last_commit(repo)?;
31
32 if let Some(reference) = last_commit {
33 repo.commit(
34 Some("HEAD"),
35 &signature,
36 &signature,
37 message,
38 &tree,
39 &[&reference],
40 )?;
41 } else {
42 repo.commit(Some("HEAD"), &signature, &signature, message, &tree, &[])?;
43 }
44 Ok(())
45}
46
47pub fn push_to_origin(repo: &Repository) -> Result<(), git2::Error> {
48 let mut remote = repo.find_remote("origin")?;
49 remote.connect(Direction::Push)?; remote.push(&["refs/heads/master:refs/heads/master"], None) }
52
53#[cfg(test)]
54mod test {
55 use git2::Repository;
56
57 use super::find_last_commit;
58 use crate::ops::testing;
59
60 #[test]
61 fn no_commit() {
62 let dir = testing::temp_path();
63
64 let repo = Repository::init(dir).unwrap();
65
66 let last_commit = find_last_commit(&repo).unwrap();
67
68 assert!(last_commit.is_none())
69 }
70}