Skip to content

Commit 8b1f99b

Browse files
Copilotalexr00
andcommitted
Add logic to exclude merge commits from changes since last review
Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
1 parent 29e001d commit 8b1f99b

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

src/github/loggingOctokit.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ export class LoggingOctokit {
150150
}
151151
}
152152

153-
export async function compareCommits(remote: GitHubRemote, octokit: LoggingOctokit, base: GitHubRef, head: GitHubRef, compareWithBaseRef: string, prNumber: number, logId: string): Promise<{ mergeBaseSha: string; files: IRawFileChange[] }> {
154-
Logger.debug(`Comparing commits for ${remote.owner}/${remote.repositoryName} with base ${base.repositoryCloneUrl.owner}:${compareWithBaseRef} and head ${head.repositoryCloneUrl.owner}:${head.sha}`, logId);
153+
export async function compareCommits(remote: GitHubRemote, octokit: LoggingOctokit, base: GitHubRef, head: GitHubRef, compareWithBaseRef: string, prNumber: number, logId: string, excludeMergeCommits: boolean = false): Promise<{ mergeBaseSha: string; files: IRawFileChange[] }> {
154+
Logger.debug(`Comparing commits for ${remote.owner}/${remote.repositoryName} with base ${base.repositoryCloneUrl.owner}:${compareWithBaseRef} and head ${head.repositoryCloneUrl.owner}:${head.sha}${excludeMergeCommits ? ' (excluding merge commits)' : ''}`, logId);
155155
let files: IRawFileChange[] | undefined;
156156
let mergeBaseSha: string | undefined;
157157

@@ -182,6 +182,45 @@ export async function compareCommits(remote: GitHubRemote, octokit: LoggingOctok
182182
files = data.files ? data.files as IRawFileChange[] : [];
183183
}
184184
mergeBaseSha = data.merge_base_commit.sha;
185+
186+
// If we should exclude merge commits, filter out files that were only changed in merge commits
187+
if (excludeMergeCommits && data.commits && data.commits.length > 0) {
188+
const mergeCommits = data.commits.filter((commit: any) => commit.parents && commit.parents.length > 1);
189+
190+
if (mergeCommits.length > 0) {
191+
Logger.appendLine(`Found ${mergeCommits.length} merge commit(s) in range, filtering out their changes`, logId);
192+
193+
// Get the list of non-merge commits
194+
const nonMergeCommits = data.commits.filter((commit: any) => !commit.parents || commit.parents.length <= 1);
195+
196+
// Build a map of files changed by non-merge commits
197+
const fileChangedByNonMerge = new Map<string, IRawFileChange>();
198+
199+
for (const commit of nonMergeCommits) {
200+
try {
201+
// Get the diff for this specific commit
202+
const commitData = await octokit.call(octokit.api.repos.getCommit, {
203+
owner: remote.owner,
204+
repo: remote.repositoryName,
205+
ref: commit.sha,
206+
});
207+
208+
if (commitData.data.files) {
209+
for (const file of commitData.data.files) {
210+
// Store the file change, using the most recent version if multiple commits modified it
211+
fileChangedByNonMerge.set(file.filename, file as IRawFileChange);
212+
}
213+
}
214+
} catch (e) {
215+
Logger.warn(`Failed to get commit ${commit.sha}: ${e}`, logId);
216+
}
217+
}
218+
219+
// Replace files with only those from non-merge commits
220+
files = Array.from(fileChangedByNonMerge.values());
221+
Logger.appendLine(`After filtering merge commits, ${files.length} files remain`, logId);
222+
}
223+
}
185224
} catch (e) {
186225
if (e.message === 'Server Error') {
187226
// Happens when github times out. Let's try to get a few at a time.

src/github/pullRequestModel.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1716,7 +1716,8 @@ export class PullRequestModel extends IssueModel<PullRequest> implements IPullRe
17161716
}
17171717

17181718
Logger.debug(`Comparing commits for ${remote.owner}/${remote.repositoryName} with base ${this.base.repositoryCloneUrl.owner}:${compareWithBaseRef} and head ${this.head!.repositoryCloneUrl.owner}:${this.head!.sha}`, PullRequestModel.ID);
1719-
const { files, mergeBaseSha } = await compareCommits(remote, octokit, this.base, this.head!, compareWithBaseRef, this.number, PullRequestModel.ID);
1719+
const excludeMergeCommits = this._showChangesSinceReview && this.hasChangesSinceLastReview;
1720+
const { files, mergeBaseSha } = await compareCommits(remote, octokit, this.base, this.head!, compareWithBaseRef, this.number, PullRequestModel.ID, excludeMergeCommits);
17201721
this.mergeBase = mergeBaseSha;
17211722

17221723
if (oldHasChangesSinceReview !== undefined && oldHasChangesSinceReview !== this.hasChangesSinceLastReview && this.hasChangesSinceLastReview && this._showChangesSinceReview) {

0 commit comments

Comments
 (0)