| 128 | } |
| 129 | |
| 130 | pub async fn commit(repo_path: &Path, message: &str) -> Result<(), String> { |
| 131 | tokio::task::spawn_blocking({ |
| 132 | let repo_path = repo_path.to_owned(); |
| 133 | let message = message.to_owned(); |
| 134 | move || -> Result<(), String> { |
| 135 | let output = std::process::Command::new("git") |
| 136 | .current_dir(&repo_path) |
| 137 | .arg("commit") |
| 138 | .arg("--no-verify") |
| 139 | .arg("-m") |
| 140 | .arg(&message) |
| 141 | .output() |
| 142 | .map_err(|e| format!("Failed to execute git commit: {e}"))?; |
| 143 | |
| 144 | if !output.status.success() { |
| 145 | let combined = format!( |
| 146 | "{}{}", |
| 147 | String::from_utf8_lossy(&output.stdout), |
| 148 | String::from_utf8_lossy(&output.stderr) |
| 149 | ); |
| 150 | if combined.contains("nothing to commit") { |
| 151 | return Ok(()); |
| 152 | } |
| 153 | return Err(format!("Failed to create commit: {combined}")); |
| 154 | } |
| 155 | |
| 156 | Ok(()) |
| 157 | } |
| 158 | }) |
| 159 | .await |
| 160 | .map_err(|e| format!("Task join error: {e}"))? |
| 161 | } |
| 162 | |
| 163 | pub async fn add_remote(repo_path: &Path, remote_name: &str, url: &str) -> Result<(), String> { |
| 164 | tokio::task::spawn_blocking({ |