fluidattacks_core_git/
ops.rs1use std::path::Path;
2
3use crate::cli;
4
5pub async fn reset_repo(repo_path: &str) -> bool {
7 if let Err(error) = cli::set_safe_directory().await {
8 tracing::error!(repo_path, error = %error, "failed to add the safe directory");
9 }
10 let root = Path::new(repo_path);
11 if !root.join(".git").exists() {
12 tracing::error!(repo_path, "not the root of a repository");
13 return false;
14 }
15 if let Err(error) = cli::reset_hard(repo_path).await {
16 tracing::error!(repo_path, error = %error, "failed to reset the repository");
17 return false;
18 }
19 super::fs::remove_symlinks(root);
20 true
21}
22
23#[cfg(test)]
24mod tests {
25 use super::reset_repo;
26 use std::path::Path;
27
28 fn git(repo: &Path, args: &[&str]) {
29 let status = std::process::Command::new("git")
30 .arg("-C")
31 .arg(repo)
32 .args(args)
33 .status()
34 .unwrap();
35 assert!(status.success());
36 }
37
38 #[tokio::test]
39 async fn only_the_root_of_the_repository_gets_reset() {
40 let dir = tempfile::tempdir().unwrap();
41 std::env::set_var("GIT_CONFIG_GLOBAL", dir.path().join("gitconfig"));
42
43 let repo = dir.path().join("repo");
44 std::fs::create_dir_all(repo.join("sub/deep")).unwrap();
45 git(&repo, &["init", "-q"]);
46 std::fs::write(repo.join("f.txt"), b"committed").unwrap();
47 git(&repo, &["add", "-A"]);
48 git(
49 &repo,
50 &[
51 "-c",
52 "user.email=dev@fluidattacks.com",
53 "-c",
54 "user.name=dev",
55 "commit",
56 "-q",
57 "-m",
58 "files",
59 ],
60 );
61 std::fs::write(repo.join("f.txt"), b"dirty").unwrap();
62
63 let deep = repo.join("sub/deep");
64 assert!(!reset_repo(deep.to_str().unwrap()).await);
65 assert_eq!(
66 std::fs::read_to_string(repo.join("f.txt")).unwrap(),
67 "dirty"
68 );
69
70 assert!(reset_repo(repo.to_str().unwrap()).await);
71 assert_eq!(
72 std::fs::read_to_string(repo.join("f.txt")).unwrap(),
73 "committed"
74 );
75 }
76}