@@ -15,6 +15,13 @@ def __init__(self, path: str):
1515 self .repo = Repo (path )
1616 assert self .repo
1717 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 } " )
1825
1926 # Use CI environment SHA if available, otherwise fall back to current HEAD commit
2027 github_sha = os .getenv ('GITHUB_SHA' )
@@ -128,12 +135,95 @@ def __init__(self, path: str):
128135 self .commit_sha = self .commit .binsha
129136 self .commit_message = self .commit .message
130137 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 } " )
132222 self .changed_files = []
133223 for item in self .show_files :
134224 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 )
137227
138228 # Determine if this commit is on the default branch
139229 # This considers both GitHub Actions detached HEAD and regular branch situations
0 commit comments