@@ -24,47 +24,98 @@ pub async fn run_git_command(args: &[&str]) -> Result<Vec<String>> {
2424}
2525
2626pub 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
4885pub 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