@@ -15,6 +15,13 @@ def __init__(self, path: str):
15
15
self .repo = Repo (path )
16
16
assert self .repo
17
17
self .head = self .repo .head
18
+
19
+ # Always fetch all remote refs to ensure branches exist for diffing
20
+ try :
21
+ self .repo .git .fetch ('--all' )
22
+ log .debug ("Fetched all remote refs for diffing." )
23
+ except Exception as fetch_error :
24
+ log .debug (f"Failed to fetch all remote refs: { fetch_error } " )
18
25
19
26
# Use CI environment SHA if available, otherwise fall back to current HEAD commit
20
27
github_sha = os .getenv ('GITHUB_SHA' )
@@ -128,12 +135,95 @@ def __init__(self, path: str):
128
135
self .commit_sha = self .commit .binsha
129
136
self .commit_message = self .commit .message
130
137
self .committer = self .commit .committer
131
- self .show_files = self .repo .git .show (self .commit , name_only = True , format = "%n" ).splitlines ()
138
+ # Detect changed files in PR/MR context for GitHub, GitLab, Bitbucket; fallback to git show
139
+ self .show_files = []
140
+ detected = False
141
+ # GitHub Actions PR context
142
+ github_base_ref = os .getenv ('GITHUB_BASE_REF' )
143
+ github_head_ref = os .getenv ('GITHUB_HEAD_REF' )
144
+ github_event_name = os .getenv ('GITHUB_EVENT_NAME' )
145
+ github_before_sha = os .getenv ('GITHUB_EVENT_BEFORE' ) # previous commit for push
146
+ github_sha = os .getenv ('GITHUB_SHA' ) # current commit
147
+ if github_event_name == 'pull_request' and github_base_ref and github_head_ref :
148
+ try :
149
+ # Fetch both branches individually
150
+ self .repo .git .fetch ('origin' , github_base_ref )
151
+ self .repo .git .fetch ('origin' , github_head_ref )
152
+ # Try remote diff first
153
+ diff_range = f"origin/{ github_base_ref } ...origin/{ github_head_ref } "
154
+ try :
155
+ diff_files = self .repo .git .diff ('--name-only' , diff_range )
156
+ self .show_files = diff_files .splitlines ()
157
+ log .debug (f"Changed files detected via git diff (GitHub PR remote): { self .show_files } " )
158
+ detected = True
159
+ except Exception as remote_error :
160
+ log .debug (f"Remote diff failed: { remote_error } " )
161
+ # Try local branch diff
162
+ local_diff_range = f"{ github_base_ref } ...{ github_head_ref } "
163
+ try :
164
+ diff_files = self .repo .git .diff ('--name-only' , local_diff_range )
165
+ self .show_files = diff_files .splitlines ()
166
+ log .debug (f"Changed files detected via git diff (GitHub PR local): { self .show_files } " )
167
+ detected = True
168
+ except Exception as local_error :
169
+ log .debug (f"Local diff failed: { local_error } " )
170
+ except Exception as error :
171
+ log .debug (f"Failed to fetch branches or diff for GitHub PR: { error } " )
172
+ # Commits to default branch (push events)
173
+ elif github_event_name == 'push' and github_before_sha and github_sha :
174
+ try :
175
+ diff_files = self .repo .git .diff ('--name-only' , f'{ github_before_sha } ..{ github_sha } ' )
176
+ self .show_files = diff_files .splitlines ()
177
+ log .debug (f"Changed files detected via git diff (GitHub push): { self .show_files } " )
178
+ detected = True
179
+ except Exception as error :
180
+ log .debug (f"Failed to get changed files via git diff (GitHub push): { error } " )
181
+ elif github_event_name == 'push' :
182
+ try :
183
+ self .show_files = self .repo .git .show (self .commit , name_only = True , format = "%n" ).splitlines ()
184
+ log .debug (f"Changed files detected via git show (GitHub push fallback): { self .show_files } " )
185
+ detected = True
186
+ except Exception as error :
187
+ log .debug (f"Failed to get changed files via git show (GitHub push fallback): { error } " )
188
+ # GitLab CI Merge Request context
189
+ if not detected :
190
+ gitlab_target = os .getenv ('CI_MERGE_REQUEST_TARGET_BRANCH_NAME' )
191
+ gitlab_source = os .getenv ('CI_MERGE_REQUEST_SOURCE_BRANCH_NAME' )
192
+ if gitlab_target and gitlab_source :
193
+ try :
194
+ self .repo .git .fetch ('origin' , gitlab_target , gitlab_source )
195
+ diff_range = f"origin/{ gitlab_target } ...origin/{ gitlab_source } "
196
+ diff_files = self .repo .git .diff ('--name-only' , diff_range )
197
+ self .show_files = diff_files .splitlines ()
198
+ log .debug (f"Changed files detected via git diff (GitLab): { self .show_files } " )
199
+ detected = True
200
+ except Exception as error :
201
+ log .debug (f"Failed to get changed files via git diff (GitLab): { error } " )
202
+ # Bitbucket Pipelines PR context
203
+ if not detected :
204
+ bitbucket_pr_id = os .getenv ('BITBUCKET_PR_ID' )
205
+ bitbucket_source = os .getenv ('BITBUCKET_BRANCH' )
206
+ bitbucket_dest = os .getenv ('BITBUCKET_PR_DESTINATION_BRANCH' )
207
+ # BITBUCKET_BRANCH is the source branch in PR builds
208
+ if bitbucket_pr_id and bitbucket_source and bitbucket_dest :
209
+ try :
210
+ self .repo .git .fetch ('origin' , bitbucket_dest , bitbucket_source )
211
+ diff_range = f"origin/{ bitbucket_dest } ...origin/{ bitbucket_source } "
212
+ diff_files = self .repo .git .diff ('--name-only' , diff_range )
213
+ self .show_files = diff_files .splitlines ()
214
+ log .debug (f"Changed files detected via git diff (Bitbucket): { self .show_files } " )
215
+ detected = True
216
+ except Exception as error :
217
+ log .debug (f"Failed to get changed files via git diff (Bitbucket): { error } " )
218
+ # Fallback to git show for single commit
219
+ if not detected :
220
+ self .show_files = self .repo .git .show (self .commit , name_only = True , format = "%n" ).splitlines ()
221
+ log .debug (f"Changed files detected via git show: { self .show_files } " )
132
222
self .changed_files = []
133
223
for item in self .show_files :
134
224
if item != "" :
135
- full_path = f" { self . path } / { item } "
136
- self .changed_files .append (full_path )
225
+ # Use relative path for glob matching
226
+ self .changed_files .append (item )
137
227
138
228
# Determine if this commit is on the default branch
139
229
# This considers both GitHub Actions detached HEAD and regular branch situations
0 commit comments