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 if let Err(error) = tokio::task::spawn_blocking(move || super::fs::remove_symlinks(&root)).await
20 {
21 tracing::error!(repo_path = %repo_path.display(), error = %error, "failed to remove the symlinks");
22 return false;
23 }
24 true
25}
26
27#[cfg(test)]
28mod tests {
29 use super::reset_repo;
30 use std::path::Path;
31
32 fn git(repo: &Path, args: &[&str]) {
33 let status = std::process::Command::new("git")
34 .arg("-C")
35 .arg(repo)
36 .args(args)
37 .status()
38 .unwrap();
39 assert!(status.success());
40 }
41
42 #[tokio::test]
43 async fn only_the_root_of_the_repository_gets_reset() {
44 let dir = tempfile::tempdir().unwrap();
45 std::env::set_var("GIT_CONFIG_GLOBAL", dir.path().join("gitconfig"));
46
47 let repo = dir.path().join("repo");
48 std::fs::create_dir_all(repo.join("sub/deep")).unwrap();
49 git(&repo, &["init", "-q"]);
50 std::fs::write(repo.join("f.txt"), b"committed").unwrap();
51 git(&repo, &["add", "-A"]);
52 git(
53 &repo,
54 &[
55 "-c",
56 "user.email=dev@fluidattacks.com",
57 "-c",
58 "user.name=dev",
59 "commit",
60 "-q",
61 "-m",
62 "files",
63 ],
64 );
65 std::fs::write(repo.join("f.txt"), b"dirty").unwrap();
66
67 let deep = repo.join("sub/deep");
68 assert!(!reset_repo(&deep).await);
69 assert_eq!(
70 std::fs::read_to_string(repo.join("f.txt")).unwrap(),
71 "dirty"
72 );
73
74 assert!(reset_repo(&repo).await);
75 assert_eq!(
76 std::fs::read_to_string(repo.join("f.txt")).unwrap(),
77 "committed"
78 );
79 }
80}