Skip to content

Commit 1d53212

Browse files
committed
fixed clone and file issue
1 parent 8399fcd commit 1d53212

File tree

1 file changed

+80
-135
lines changed

1 file changed

+80
-135
lines changed

src/utils/common.rs

+80-135
Original file line numberDiff line numberDiff line change
@@ -266,121 +266,6 @@ pub async fn execute_command(command: &str, suppress_error: bool) -> String {
266266
stdout.to_string()
267267
}
268268

269-
fn save_commit_map(
270-
file_commit_map: &HashMap<String, String>,
271-
) -> Result<(), Box<dyn std::error::Error>> {
272-
let commit_map_path = "/tmp/commit_map.json";
273-
let file = File::create(commit_map_path)?;
274-
serde_json::to_writer(file, file_commit_map)?;
275-
println!("Commit map saved to: {}", commit_map_path);
276-
Ok(())
277-
}
278-
279-
fn delete_except(files: &str, base_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
280-
println!("Deleting all files except the following:");
281-
println!("__________________________________________ {:?}", files);
282-
let files_to_keep: Vec<PathBuf> = files
283-
.lines()
284-
.map(|line| base_dir.join(line.trim()))
285-
.collect();
286-
287-
traverse_and_delete(base_dir, &files_to_keep)?;
288-
289-
Ok(())
290-
}
291-
292-
fn traverse_and_delete(base_dir: &Path, files_to_keep: &[PathBuf]) -> Result<(), std::io::Error> {
293-
for entry in fs::read_dir(base_dir)? {
294-
let entry = entry?;
295-
let path = entry.path();
296-
297-
// Skip the .git directory
298-
if path.is_dir() && path.file_name().map_or(false, |name| name == ".git") {
299-
continue;
300-
}
301-
302-
if path.is_dir() {
303-
traverse_and_delete(&path, files_to_keep)?;
304-
}
305-
306-
// Check if the path should be deleted (only delete files)
307-
if path.is_file() && !files_to_keep.contains(&path.canonicalize()?) {
308-
fs::remove_file(&path)?;
309-
}
310-
}
311-
312-
Ok(())
313-
}
314-
315-
fn delete_empty_directories(start_dir: &Path) -> Result<(), std::io::Error> {
316-
for entry in fs::read_dir(start_dir)? {
317-
let entry = entry?;
318-
let path = entry.path();
319-
320-
// Skip the .git directory
321-
if path.is_dir() && path.file_name().map_or(false, |name| name == ".git") {
322-
continue;
323-
}
324-
325-
if path.is_dir() {
326-
delete_empty_directories(&path)?;
327-
if fs::read_dir(&path)?.next().is_none() {
328-
fs::remove_dir(&path)?;
329-
}
330-
}
331-
}
332-
333-
Ok(())
334-
}
335-
336-
fn get_cumulative_pr_files(
337-
base_branch: Option<&str>,
338-
pr_branch: Option<&str>,
339-
) -> Result<Vec<String>, Box<dyn std::error::Error>> {
340-
if let Some(base) = base_branch {
341-
// Step 1: Create and checkout a temporary branch from the base branch
342-
Command::new("git").args(&["checkout", base]).output()?;
343-
Command::new("git")
344-
.args(&["checkout", "-b", "temp_pr_merge_branch"])
345-
.output()?;
346-
347-
if let Some(pr) = pr_branch {
348-
// Step 2: Merge the PR branch without fast-forwarding
349-
let merge_output = Command::new("git")
350-
.args(&["merge", "--no-ff", pr])
351-
.output()?;
352-
if !merge_output.status.success() {
353-
let error_msg = String::from_utf8_lossy(&merge_output.stderr);
354-
return Err(format!("Failed to merge PR branch: {}", error_msg).into());
355-
}
356-
357-
// Step 3: Get the list of changed files in the cumulative diff
358-
let output = Command::new("git")
359-
.args(&["diff", "--name-only", base, "temp_pr_merge_branch"])
360-
.output()?;
361-
if !output.status.success() {
362-
let error_msg = String::from_utf8_lossy(&output.stderr);
363-
return Err(format!("Failed to get cumulative PR files: {}", error_msg).into());
364-
}
365-
366-
let files = String::from_utf8_lossy(&output.stdout);
367-
let file_names = files.lines().map(String::from).collect();
368-
369-
// Cleanup: Delete the temporary branch
370-
Command::new("git").args(&["checkout", base]).output()?;
371-
Command::new("git")
372-
.args(&["branch", "-D", "temp_pr_merge_branch"])
373-
.output()?;
374-
375-
Ok(file_names)
376-
} else {
377-
Err("PR branch is required when base branch is specified.".into())
378-
}
379-
} else {
380-
Err("Base branch is required.".into())
381-
}
382-
}
383-
384269
pub fn checkout(
385270
clone_url: &str,
386271
clone_path: &str,
@@ -401,16 +286,20 @@ pub fn checkout(
401286

402287
// Set the working directory to the cloned path
403288
let cloned_path = Path::new(clone_path).canonicalize()?;
289+
let repo_path = cloned_path.to_str().unwrap();
404290
env::set_current_dir(&cloned_path)?;
405291

406292
// Configure Git user for commits in this repository
407293
Command::new("git")
408-
.args(&["config", "user.email", "ci@hela.int"])
294+
.args(&["config", "user.email", "ci@example.com"])
409295
.output()?;
410296
Command::new("git")
411297
.args(&["config", "user.name", "CI Bot"])
412298
.output()?;
413299

300+
// Store the set of changed files
301+
let mut changed_files = HashSet::new();
302+
414303
// If a pr_branch is provided, fetch it as a local branch and compare with the base branch
415304
if let Some(pr_branch_name) = pr_branch {
416305
// Fetch the PR branch and create a local branch
@@ -441,16 +330,11 @@ pub fn checkout(
441330
return Err(format!("Failed to diff branches: {}", error_msg).into());
442331
}
443332

444-
// Parse the diff output
445-
let changed_files = String::from_utf8_lossy(&diff_output.stdout)
446-
.lines()
447-
.map(String::from)
448-
.collect::<Vec<String>>();
449-
450-
println!(
451-
"Changed files in PR branch '{}': {:?}",
452-
pr_branch_name, changed_files
453-
);
333+
// Parse the diff output into a set of changed files
334+
let diff_output_str = String::from_utf8_lossy(&diff_output.stdout);
335+
for line in diff_output_str.lines() {
336+
changed_files.insert(line.trim().to_string());
337+
}
454338
} else {
455339
// If no PR branch, list all files in the base branch
456340
let list_output = Command::new("git")
@@ -462,18 +346,79 @@ pub fn checkout(
462346
return Err(format!("Failed to list files in base branch: {}", error_msg).into());
463347
}
464348

465-
let files = String::from_utf8_lossy(&list_output.stdout)
466-
.lines()
467-
.map(String::from)
468-
.collect::<Vec<String>>();
349+
// Parse the list output into a set of files
350+
let list_output_str = String::from_utf8_lossy(&list_output.stdout);
351+
for line in list_output_str.lines() {
352+
changed_files.insert(line.trim().to_string());
353+
}
354+
}
355+
356+
// Print the changed files for debugging purposes
357+
println!("Changed files:\n{:#?}", changed_files);
469358

470-
println!(
471-
"Files in branch '{}': {:?}",
472-
branch.unwrap_or("default branch"),
473-
files
474-
);
359+
// Ensure the working directory is up-to-date before checking out files
360+
Command::new("git")
361+
.args(&["checkout", pr_branch.unwrap_or("HEAD")])
362+
.output()?;
363+
364+
// Ensure each changed file is checked out from the PR branch
365+
for file in &changed_files {
366+
let checkout_output = Command::new("git")
367+
.args(&["checkout", pr_branch.unwrap_or("HEAD"), "--", file])
368+
.output()?;
369+
370+
if !checkout_output.status.success() {
371+
let error_msg = String::from_utf8_lossy(&checkout_output.stderr);
372+
println!("Failed to checkout file '{}': {}", file, error_msg);
373+
}
475374
}
476375

376+
// Remove all files not in the `changed_files` set
377+
remove_unwanted_files(repo_path, &changed_files)?;
378+
379+
println!("Only the changed files have been kept locally.");
380+
381+
Ok(())
382+
}
383+
384+
/// Removes all files that are not in the `files_to_keep` set, but preserves directories.
385+
///
386+
/// # Arguments
387+
///
388+
/// * `repo_path` - The path of the repository.
389+
/// * `files_to_keep` - A set of file paths to keep relative to the `repo_path`.
390+
fn remove_unwanted_files(
391+
repo_path: &str,
392+
files_to_keep: &HashSet<String>,
393+
) -> Result<(), Box<dyn std::error::Error>> {
394+
// Recursively remove unwanted files
395+
for entry in fs::read_dir(repo_path)? {
396+
let entry = entry?;
397+
let path = entry.path();
398+
399+
// Skip the .git directory to preserve repository integrity
400+
if path.is_dir() && path.file_name().map_or(false, |name| name == ".git") {
401+
continue;
402+
}
403+
404+
// Determine the relative path
405+
let relative_path = path.strip_prefix(repo_path)?.to_str().unwrap().to_string();
406+
407+
// Check if the file should be kept or removed
408+
if path.is_file() && !files_to_keep.contains(&relative_path) {
409+
println!("Removing file: {}", relative_path);
410+
fs::remove_file(&path)?;
411+
} else if path.is_dir() {
412+
// Recursively clean up subdirectories
413+
remove_unwanted_files(path.to_str().unwrap(), files_to_keep)?;
414+
415+
// Check if the directory is empty and remove it
416+
if fs::read_dir(&path)?.next().is_none() {
417+
println!("Removing empty directory: {}", relative_path);
418+
fs::remove_dir(&path)?;
419+
}
420+
}
421+
}
477422
Ok(())
478423
}
479424

0 commit comments

Comments
 (0)