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

Lines changed: 80 additions & 135 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy