Skip to content

Commit 2fe8526

Browse files
authored
Merge pull request #15 from brunoerg/2025-10-fix-upstream
git_changes: fallback to origin if upstream failed
2 parents 458db06 + 60f758e commit 2fe8526

File tree

2 files changed

+66
-17
lines changed

2 files changed

+66
-17
lines changed

src/analyze.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ async fn run_command(command: &str, timeout_secs: u64) -> Result<bool> {
200200
}
201201

202202
async fn run_build_command() -> Result<()> {
203-
let build_command = "rm -rf build && cmake -B build && cmake --build build";
204-
//println!("\n\nRunning {}", build_command);
203+
let build_command =
204+
"rm -rf build && cmake -B build -DENABLE_IPC=OFF && cmake --build build -j $(nproc)";
205205

206206
let success = run_command(build_command, 3600).await?; // 1 hour timeout for build
207207
if !success {

src/git_changes.rs

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,47 +24,98 @@ pub async fn run_git_command(args: &[&str]) -> Result<Vec<String>> {
2424
}
2525

2626
pub async fn get_changed_files(pr_number: Option<u32>) -> Result<Vec<String>> {
27+
let mut used_remote = "upstream"; // Track which remote we successfully used
28+
2729
if let Some(pr) = pr_number {
28-
// Fetch the PR
29-
let fetch_args = &["fetch", "upstream", &format!("pull/{}/head:pr/{}", pr, pr)];
30-
match run_git_command(fetch_args).await {
30+
// Try to fetch the PR from upstream first
31+
let fetch_upstream_args = &["fetch", "upstream", &format!("pull/{}/head:pr/{}", pr, pr)];
32+
match run_git_command(fetch_upstream_args).await {
3133
Ok(_) => {
34+
println!("Successfully fetched from upstream");
3235
println!("Checking out...");
3336
let checkout_args = &["checkout", &format!("pr/{}", pr)];
3437
run_git_command(checkout_args).await?;
3538
}
36-
Err(_) => {
37-
println!("Fetching and updating branch...");
38-
let rebase_args = &["rebase", &format!("pr/{}", pr)];
39-
run_git_command(rebase_args).await?;
39+
Err(upstream_err) => {
40+
println!("Failed to fetch from upstream: {:?}", upstream_err);
41+
println!("Trying to fetch from origin...");
42+
43+
// Try to fetch from origin as fallback
44+
let fetch_origin_args =
45+
&["fetch", "origin", &format!("pull/{}/head:pr/{}", pr, pr)];
46+
match run_git_command(fetch_origin_args).await {
47+
Ok(_) => {
48+
println!("Successfully fetched from origin");
49+
used_remote = "origin";
50+
println!("Checking out...");
51+
let checkout_args = &["checkout", &format!("pr/{}", pr)];
52+
run_git_command(checkout_args).await?;
53+
}
54+
Err(origin_err) => {
55+
println!("Failed to fetch from origin: {:?}", origin_err);
56+
println!("Attempting to rebase existing pr/{} branch...", pr);
57+
let rebase_args = &["rebase", &format!("pr/{}", pr)];
58+
run_git_command(rebase_args).await?;
59+
// In rebase case, we don't know which remote was used originally
60+
// Try upstream first, fall back to origin if it fails
61+
}
62+
}
4063
}
4164
}
4265
}
4366

44-
let diff_args = &["diff", "--name-only", "upstream/master...HEAD"];
45-
run_git_command(diff_args).await
67+
// Try diff with the appropriate remote
68+
let diff_args = &[
69+
"diff",
70+
"--name-only",
71+
&format!("{}/master...HEAD", used_remote),
72+
];
73+
match run_git_command(diff_args).await {
74+
Ok(result) => Ok(result),
75+
Err(_) if used_remote == "upstream" => {
76+
// If upstream diff failed, try origin
77+
println!("Diff with upstream/master failed, trying origin/master...");
78+
let diff_args_origin = &["diff", "--name-only", "origin/master...HEAD"];
79+
run_git_command(diff_args_origin).await
80+
}
81+
Err(e) => Err(e),
82+
}
4683
}
4784

4885
pub async fn get_lines_touched(file_path: &str) -> Result<Vec<usize>> {
49-
let diff_args = &[
86+
// Try upstream first
87+
let diff_args_upstream = &[
5088
"diff",
5189
"--unified=0",
5290
"upstream/master...HEAD",
5391
"--",
5492
file_path,
5593
];
56-
let diff_output = run_git_command(diff_args).await?;
94+
95+
let diff_output = match run_git_command(diff_args_upstream).await {
96+
Ok(output) => output,
97+
Err(_) => {
98+
// Fall back to origin if upstream fails
99+
println!("Diff with upstream/master failed, trying origin/master...");
100+
let diff_args_origin = &[
101+
"diff",
102+
"--unified=0",
103+
"origin/master...HEAD",
104+
"--",
105+
file_path,
106+
];
107+
run_git_command(diff_args_origin).await?
108+
}
109+
};
57110

58111
let mut lines = Vec::new();
59112
let line_range_regex = Regex::new(r"@@.*\+(\d+)(?:,(\d+))?.*@@")?;
60-
61113
for line in diff_output {
62114
if line.starts_with("@@") {
63115
if let Some(captures) = line_range_regex.captures(&line) {
64116
let start_line: usize = captures[1]
65117
.parse()
66118
.map_err(|_| MutationError::Git("Invalid line number in diff".to_string()))?;
67-
68119
let num_lines = if let Some(count_match) = captures.get(2) {
69120
count_match
70121
.as_str()
@@ -73,12 +124,10 @@ pub async fn get_lines_touched(file_path: &str) -> Result<Vec<usize>> {
73124
} else {
74125
1
75126
};
76-
77127
lines.extend(start_line..start_line + num_lines);
78128
}
79129
}
80130
}
81-
82131
Ok(lines)
83132
}
84133

0 commit comments

Comments
 (0)