Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ad1ae68

Browse files
authoredMar 25, 2021
Merge pull request #78 from dorny/issue-77-tag-as-base-broken
Fix change detection when base is a tag
2 parents ca8fa40 + 5d414b8 commit ad1ae68

File tree

4 files changed

+91
-21
lines changed

4 files changed

+91
-21
lines changed
 

‎CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
## v2.9.3
4+
- [Fix change detection when base is a tag](https://github.com/dorny/paths-filter/pull/78)
5+
36
## v2.9.2
47
- [Fix fetching git history](https://github.com/dorny/paths-filter/pull/75)
58

‎dist/index.js

+40-10
Original file line numberDiff line numberDiff line change
@@ -3866,15 +3866,26 @@ async function getChangesOnHead() {
38663866
}
38673867
exports.getChangesOnHead = getChangesOnHead;
38683868
async function getChangesSinceMergeBase(base, ref, initialFetchDepth) {
3869-
const baseRef = `remotes/origin/${base}`;
3869+
let baseRef;
38703870
async function hasMergeBase() {
3871-
return (await exec_1.default('git', ['merge-base', baseRef, ref], { ignoreReturnCode: true })).code === 0;
3871+
return (baseRef !== undefined && (await exec_1.default('git', ['merge-base', baseRef, ref], { ignoreReturnCode: true })).code === 0);
38723872
}
38733873
let noMergeBase = false;
3874-
core.startGroup(`Searching for merge-base ${baseRef}...${ref}`);
3874+
core.startGroup(`Searching for merge-base ${base}...${ref}`);
38753875
try {
3876+
baseRef = await getFullRef(base);
38763877
if (!(await hasMergeBase())) {
3877-
await exec_1.default('git', ['fetch', `--depth=${initialFetchDepth}`, 'origin', base, ref]);
3878+
await exec_1.default('git', ['fetch', '--no-tags', `--depth=${initialFetchDepth}`, 'origin', base, ref]);
3879+
if (baseRef === undefined) {
3880+
baseRef = await getFullRef(base);
3881+
if (baseRef === undefined) {
3882+
await exec_1.default('git', ['fetch', '--tags', `--depth=1`, 'origin', base, ref]);
3883+
baseRef = await getFullRef(base);
3884+
if (baseRef === undefined) {
3885+
throw new Error(`Could not determine what is ${base} - fetch works but it's not a branch or tag`);
3886+
}
3887+
}
3888+
}
38783889
let depth = initialFetchDepth;
38793890
let lastCommitCount = await getCommitCount();
38803891
while (!(await hasMergeBase())) {
@@ -3897,16 +3908,17 @@ async function getChangesSinceMergeBase(base, ref, initialFetchDepth) {
38973908
finally {
38983909
core.endGroup();
38993910
}
3911+
let diffArg = `${baseRef}...${ref}`;
39003912
if (noMergeBase) {
3901-
core.warning('No merge base found - all files will be listed as added');
3902-
return await listAllFilesAsAdded();
3913+
core.warning('No merge base found - change detection will use direct <commit>..<commit> comparison');
3914+
diffArg = `${baseRef}..${ref}`;
39033915
}
3904-
// Get changes introduced on HEAD compared to ref
3905-
core.startGroup(`Change detection ${baseRef}...${ref}`);
3916+
// Get changes introduced on ref compared to base
3917+
core.startGroup(`Change detection ${diffArg}`);
39063918
let output = '';
39073919
try {
39083920
// Three dots '...' change detection - finds merge-base and compares against it
3909-
output = (await exec_1.default('git', ['diff', '--no-renames', '--name-status', '-z', `${baseRef}...${ref}`])).stdout;
3921+
output = (await exec_1.default('git', ['diff', '--no-renames', '--name-status', '-z', diffArg])).stdout;
39103922
}
39113923
finally {
39123924
fixStdOutNullTermination();
@@ -3994,6 +4006,24 @@ async function getCommitCount() {
39944006
const count = parseInt(output);
39954007
return isNaN(count) ? 0 : count;
39964008
}
4009+
async function getFullRef(shortName) {
4010+
if (isGitSha(shortName)) {
4011+
return shortName;
4012+
}
4013+
const output = (await exec_1.default('git', ['show-ref', shortName], { ignoreReturnCode: true })).stdout;
4014+
const refs = output
4015+
.split(/\r?\n/g)
4016+
.map(l => { var _a, _b; return (_b = (_a = l.match(/refs\/.*$/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : ''; })
4017+
.filter(l => l !== '');
4018+
if (refs.length === 0) {
4019+
return undefined;
4020+
}
4021+
const remoteRef = refs.find(ref => ref.startsWith('refs/remotes/origin/'));
4022+
if (remoteRef) {
4023+
return remoteRef;
4024+
}
4025+
return refs[0];
4026+
}
39974027
function fixStdOutNullTermination() {
39984028
// Previous command uses NULL as delimiters and output is printed to stdout.
39994029
// We have to make sure next thing written to stdout will start on new line.
@@ -4743,7 +4773,7 @@ async function getChangedFilesFromGit(base, initialFetchDepth) {
47434773
return await git.getChanges(baseSha);
47444774
}
47454775
// Changes introduced by current branch against the base branch
4746-
core.info(`Changes will be detected against the branch ${baseRef}`);
4776+
core.info(`Changes will be detected against ${baseRef}`);
47474777
return await git.getChangesSinceMergeBase(baseRef, ref, initialFetchDepth);
47484778
}
47494779
// Uses github REST api to get list of files changed in PR

‎src/git.ts

+47-10
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,30 @@ export async function getChangesOnHead(): Promise<File[]> {
5555
}
5656

5757
export async function getChangesSinceMergeBase(base: string, ref: string, initialFetchDepth: number): Promise<File[]> {
58-
const baseRef = `remotes/origin/${base}`
59-
58+
let baseRef: string | undefined
6059
async function hasMergeBase(): Promise<boolean> {
61-
return (await exec('git', ['merge-base', baseRef, ref], {ignoreReturnCode: true})).code === 0
60+
return (
61+
baseRef !== undefined && (await exec('git', ['merge-base', baseRef, ref], {ignoreReturnCode: true})).code === 0
62+
)
6263
}
6364

6465
let noMergeBase = false
65-
core.startGroup(`Searching for merge-base ${baseRef}...${ref}`)
66+
core.startGroup(`Searching for merge-base ${base}...${ref}`)
6667
try {
68+
baseRef = await getFullRef(base)
6769
if (!(await hasMergeBase())) {
68-
await exec('git', ['fetch', `--depth=${initialFetchDepth}`, 'origin', base, ref])
70+
await exec('git', ['fetch', '--no-tags', `--depth=${initialFetchDepth}`, 'origin', base, ref])
71+
if (baseRef === undefined) {
72+
baseRef = await getFullRef(base)
73+
if (baseRef === undefined) {
74+
await exec('git', ['fetch', '--tags', `--depth=1`, 'origin', base, ref])
75+
baseRef = await getFullRef(base)
76+
if (baseRef === undefined) {
77+
throw new Error(`Could not determine what is ${base} - fetch works but it's not a branch or tag`)
78+
}
79+
}
80+
}
81+
6982
let depth = initialFetchDepth
7083
let lastCommitCount = await getCommitCount()
7184
while (!(await hasMergeBase())) {
@@ -88,17 +101,18 @@ export async function getChangesSinceMergeBase(base: string, ref: string, initia
88101
core.endGroup()
89102
}
90103

104+
let diffArg = `${baseRef}...${ref}`
91105
if (noMergeBase) {
92-
core.warning('No merge base found - all files will be listed as added')
93-
return await listAllFilesAsAdded()
106+
core.warning('No merge base found - change detection will use direct <commit>..<commit> comparison')
107+
diffArg = `${baseRef}..${ref}`
94108
}
95109

96-
// Get changes introduced on HEAD compared to ref
97-
core.startGroup(`Change detection ${baseRef}...${ref}`)
110+
// Get changes introduced on ref compared to base
111+
core.startGroup(`Change detection ${diffArg}`)
98112
let output = ''
99113
try {
100114
// Three dots '...' change detection - finds merge-base and compares against it
101-
output = (await exec('git', ['diff', '--no-renames', '--name-status', '-z', `${baseRef}...${ref}`])).stdout
115+
output = (await exec('git', ['diff', '--no-renames', '--name-status', '-z', diffArg])).stdout
102116
} finally {
103117
fixStdOutNullTermination()
104118
core.endGroup()
@@ -188,6 +202,29 @@ async function getCommitCount(): Promise<number> {
188202
return isNaN(count) ? 0 : count
189203
}
190204

205+
async function getFullRef(shortName: string): Promise<string | undefined> {
206+
if (isGitSha(shortName)) {
207+
return shortName
208+
}
209+
210+
const output = (await exec('git', ['show-ref', shortName], {ignoreReturnCode: true})).stdout
211+
const refs = output
212+
.split(/\r?\n/g)
213+
.map(l => l.match(/refs\/.*$/)?.[0] ?? '')
214+
.filter(l => l !== '')
215+
216+
if (refs.length === 0) {
217+
return undefined
218+
}
219+
220+
const remoteRef = refs.find(ref => ref.startsWith('refs/remotes/origin/'))
221+
if (remoteRef) {
222+
return remoteRef
223+
}
224+
225+
return refs[0]
226+
}
227+
191228
function fixStdOutNullTermination(): void {
192229
// Previous command uses NULL as delimiters and output is printed to stdout.
193230
// We have to make sure next thing written to stdout will start on new line.

‎src/main.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ async function getChangedFilesFromGit(base: string, initialFetchDepth: number):
121121
}
122122

123123
// Changes introduced by current branch against the base branch
124-
core.info(`Changes will be detected against the branch ${baseRef}`)
124+
core.info(`Changes will be detected against ${baseRef}`)
125125
return await git.getChangesSinceMergeBase(baseRef, ref, initialFetchDepth)
126126
}
127127

0 commit comments

Comments
 (0)
Please sign in to comment.