@@ -23,6 +23,7 @@ type GitService interface {
23
23
CreateAndCheckoutBranch (repoPath , branchName string ) error
24
24
CheckoutBranch (repoPath , branchName string ) error
25
25
CreateTrackingBranch (repoPath , branchName string ) error
26
+ FetchAndCheckoutPR (repoPath string , prNumber int ) error
26
27
}
27
28
28
29
type gitService struct {}
@@ -46,18 +47,25 @@ func (g *gitService) CloneRepository(repoURL, clonePath, branch string, createNe
46
47
if createNewBranch {
47
48
// Clone the default branch first, then create new branch
48
49
cmd = exec .Command ("git" , "clone" , "--depth" , "50" , repoURL , clonePath )
50
+ log .Infof ("Executing Git command: %s" , cmd .String ())
49
51
} else {
50
52
// Try to clone specific branch directly
51
53
cmd = exec .Command ("git" , "clone" , "--depth" , "50" , "--branch" , branch , repoURL , clonePath )
54
+ log .Infof ("Executing Git command: %s" , cmd .String ())
52
55
}
53
56
54
57
output , err := cmd .CombinedOutput ()
55
58
if err != nil {
59
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , cmd .String (), string (output ), err )
56
60
if ! createNewBranch {
57
61
// If direct branch clone failed, try cloning default branch first
58
62
log .Warnf ("Failed to clone specific branch %s directly, cloning default branch: %v" , branch , err )
59
63
cmd = exec .Command ("git" , "clone" , "--depth" , "50" , repoURL , clonePath )
64
+ log .Infof ("Executing fallback Git command: %s" , cmd .String ())
60
65
output , err = cmd .CombinedOutput ()
66
+ if err != nil {
67
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , cmd .String (), string (output ), err )
68
+ }
61
69
}
62
70
if err != nil {
63
71
return GitError ("clone" , clonePath , fmt .Errorf ("%s: %w" , string (output ), err ))
@@ -103,8 +111,10 @@ func (g *gitService) CloneRepository(repoURL, clonePath, branch string, createNe
103
111
func (g * gitService ) GetRemoteURL (repoPath string ) (string , error ) {
104
112
cmd := exec .Command ("git" , "remote" , "get-url" , "origin" )
105
113
cmd .Dir = repoPath
114
+ log .Infof ("Executing Git command: %s" , cmd .String ())
106
115
output , err := cmd .Output ()
107
116
if err != nil {
117
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , cmd .String (), string (output ), err )
108
118
return "" , GitError ("get_remote_url" , repoPath , err )
109
119
}
110
120
return strings .TrimSpace (string (output )), nil
@@ -114,8 +124,10 @@ func (g *gitService) GetRemoteURL(repoPath string) (string, error) {
114
124
func (g * gitService ) GetCurrentBranch (repoPath string ) (string , error ) {
115
125
cmd := exec .Command ("git" , "rev-parse" , "--abbrev-ref" , "HEAD" )
116
126
cmd .Dir = repoPath
127
+ log .Infof ("Executing Git command: %s" , cmd .String ())
117
128
output , err := cmd .Output ()
118
129
if err != nil {
130
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , cmd .String (), string (output ), err )
119
131
return "" , GitError ("get_current_branch" , repoPath , err )
120
132
}
121
133
return strings .TrimSpace (string (output )), nil
@@ -125,8 +137,10 @@ func (g *gitService) GetCurrentBranch(repoPath string) (string, error) {
125
137
func (g * gitService ) GetCurrentCommit (repoPath string ) (string , error ) {
126
138
cmd := exec .Command ("git" , "rev-parse" , "HEAD" )
127
139
cmd .Dir = repoPath
140
+ log .Infof ("Executing Git command: %s" , cmd .String ())
128
141
output , err := cmd .Output ()
129
142
if err != nil {
143
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , cmd .String (), string (output ), err )
130
144
return "" , fmt .Errorf ("failed to get current commit: %w" , err )
131
145
}
132
146
return strings .TrimSpace (string (output )), nil
@@ -136,8 +150,10 @@ func (g *gitService) GetCurrentCommit(repoPath string) (string, error) {
136
150
func (g * gitService ) GetBranchCommit (repoPath , branch string ) (string , error ) {
137
151
cmd := exec .Command ("git" , "rev-parse" , fmt .Sprintf ("origin/%s" , branch ))
138
152
cmd .Dir = repoPath
153
+ log .Infof ("Executing Git command: %s" , cmd .String ())
139
154
output , err := cmd .Output ()
140
155
if err != nil {
156
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , cmd .String (), string (output ), err )
141
157
return "" , fmt .Errorf ("failed to get branch commit for %s: %w" , branch , err )
142
158
}
143
159
return strings .TrimSpace (string (output )), nil
@@ -183,7 +199,9 @@ func (g *gitService) ValidateBranch(repoPath, expectedBranch string) bool {
183
199
func (g * gitService ) ConfigureSafeDirectory (repoPath string ) error {
184
200
cmd := exec .Command ("git" , "config" , "--local" , "--add" , "safe.directory" , repoPath )
185
201
cmd .Dir = repoPath
202
+ log .Infof ("Executing Git command: %s" , cmd .String ())
186
203
if output , err := cmd .CombinedOutput (); err != nil {
204
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , cmd .String (), string (output ), err )
187
205
return GitError ("config_safe_directory" , repoPath , fmt .Errorf ("%s: %w" , string (output ), err ))
188
206
}
189
207
return nil
@@ -193,7 +211,9 @@ func (g *gitService) ConfigureSafeDirectory(repoPath string) error {
193
211
func (g * gitService ) ConfigurePullStrategy (repoPath string ) error {
194
212
cmd := exec .Command ("git" , "config" , "--local" , "pull.rebase" , "true" )
195
213
cmd .Dir = repoPath
214
+ log .Infof ("Executing Git command: %s" , cmd .String ())
196
215
if output , err := cmd .CombinedOutput (); err != nil {
216
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , cmd .String (), string (output ), err )
197
217
return fmt .Errorf ("failed to configure pull strategy: %w, output: %s" , err , string (output ))
198
218
}
199
219
return nil
@@ -203,7 +223,9 @@ func (g *gitService) ConfigurePullStrategy(repoPath string) error {
203
223
func (g * gitService ) CreateAndCheckoutBranch (repoPath , branchName string ) error {
204
224
cmd := exec .Command ("git" , "checkout" , "-b" , branchName )
205
225
cmd .Dir = repoPath
226
+ log .Infof ("Executing Git command: %s" , cmd .String ())
206
227
if output , err := cmd .CombinedOutput (); err != nil {
228
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , cmd .String (), string (output ), err )
207
229
return fmt .Errorf ("failed to create new branch %s: %w, output: %s" , branchName , err , string (output ))
208
230
}
209
231
return nil
@@ -213,7 +235,9 @@ func (g *gitService) CreateAndCheckoutBranch(repoPath, branchName string) error
213
235
func (g * gitService ) CheckoutBranch (repoPath , branchName string ) error {
214
236
cmd := exec .Command ("git" , "checkout" , branchName )
215
237
cmd .Dir = repoPath
238
+ log .Infof ("Executing Git command: %s" , cmd .String ())
216
239
if output , err := cmd .CombinedOutput (); err != nil {
240
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , cmd .String (), string (output ), err )
217
241
return fmt .Errorf ("failed to checkout branch %s: %w, output: %s" , branchName , err , string (output ))
218
242
}
219
243
return nil
@@ -223,8 +247,64 @@ func (g *gitService) CheckoutBranch(repoPath, branchName string) error {
223
247
func (g * gitService ) CreateTrackingBranch (repoPath , branchName string ) error {
224
248
cmd := exec .Command ("git" , "checkout" , "-b" , branchName , fmt .Sprintf ("origin/%s" , branchName ))
225
249
cmd .Dir = repoPath
250
+ log .Infof ("Executing Git command: %s" , cmd .String ())
226
251
if output , err := cmd .CombinedOutput (); err != nil {
252
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , cmd .String (), string (output ), err )
227
253
return fmt .Errorf ("failed to create tracking branch %s: %w, output: %s" , branchName , err , string (output ))
228
254
}
229
255
return nil
230
256
}
257
+
258
+ // FetchAndCheckoutPR fetches and checks out PR content using GitHub's PR refs
259
+ // Always uses force mode to handle updates, force pushes, and ensure latest content
260
+ func (g * gitService ) FetchAndCheckoutPR (repoPath string , prNumber int ) error {
261
+ log .Infof ("Fetching PR #%d content using GitHub PR refs (force mode)" , prNumber )
262
+
263
+ prBranchName := fmt .Sprintf ("pr-%d" , prNumber )
264
+ currentBranch , err := g .GetCurrentBranch (repoPath )
265
+
266
+ // If we're already on the PR branch, use a lightweight in-place update
267
+ if err == nil && currentBranch == prBranchName {
268
+ log .Infof ("Already on PR branch %s, performing in-place sync" , prBranchName )
269
+
270
+ // Step 1: First fetch the PR content to FETCH_HEAD without creating/updating local branch
271
+ fetchCmd := exec .Command ("git" , "fetch" , "origin" , fmt .Sprintf ("pull/%d/head" , prNumber ))
272
+ fetchCmd .Dir = repoPath
273
+ log .Infof ("Executing Git command: %s" , fetchCmd .String ())
274
+ if output , err := fetchCmd .CombinedOutput (); err != nil {
275
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , fetchCmd .String (), string (output ), err )
276
+ return fmt .Errorf ("failed to fetch PR #%d content: %w, output: %s" , prNumber , err , string (output ))
277
+ }
278
+
279
+ // Step 2: Reset current branch to the fetched content
280
+ resetCmd := exec .Command ("git" , "reset" , "--hard" , "FETCH_HEAD" )
281
+ resetCmd .Dir = repoPath
282
+ log .Infof ("Executing Git command: %s" , resetCmd .String ())
283
+ if output , err := resetCmd .CombinedOutput (); err != nil {
284
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , resetCmd .String (), string (output ), err )
285
+ return fmt .Errorf ("failed to reset PR branch to latest content: %w, output: %s" , err , string (output ))
286
+ }
287
+
288
+ log .Infof ("Successfully updated PR #%d branch in-place" , prNumber )
289
+ return nil
290
+ }
291
+
292
+ fetchCmd := exec .Command ("git" , "fetch" , "origin" , fmt .Sprintf ("pull/%d/head:%s" , prNumber , prBranchName ), "--force" )
293
+ fetchCmd .Dir = repoPath
294
+ log .Infof ("Executing Git command: %s" , fetchCmd .String ())
295
+ if output , err := fetchCmd .CombinedOutput (); err != nil {
296
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , fetchCmd .String (), string (output ), err )
297
+ return fmt .Errorf ("failed to fetch PR #%d: %w, output: %s" , prNumber , err , string (output ))
298
+ }
299
+
300
+ checkoutCmd := exec .Command ("git" , "checkout" , prBranchName )
301
+ checkoutCmd .Dir = repoPath
302
+ log .Infof ("Executing Git command: %s" , checkoutCmd .String ())
303
+ if output , err := checkoutCmd .CombinedOutput (); err != nil {
304
+ log .Errorf ("Git command failed: %s, output: %s, error: %v" , checkoutCmd .String (), string (output ), err )
305
+ return fmt .Errorf ("failed to checkout PR branch %s: %w, output: %s" , prBranchName , err , string (output ))
306
+ }
307
+
308
+ log .Infof ("Successfully fetched and checked out PR #%d content to branch: %s" , prNumber , prBranchName )
309
+ return nil
310
+ }
0 commit comments