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