Skip to content

Commit 9e027bf

Browse files
committed
Fixes #4069 ensures exact match on found autolinks
1 parent 83ab4ac commit 9e027bf

File tree

4 files changed

+36
-42
lines changed

4 files changed

+36
-42
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
3131
- Fixes _Show \* View_ commands fail intermittently ([#4127](https://github.com/gitkraken/vscode-gitlens/issues/4127))
3232
- Fixes load more not working on incoming changes in Commits/Repositories views ([#4154](https://github.com/gitkraken/vscode-gitlens/issues/4154))
3333
- Fixes incorrect settings.json entry for Google Gemini 2.0 Flash Thinking causes linter warning ([#4168](https://github.com/gitkraken/vscode-gitlens/issues/4168))
34+
- Fixes multiple autolinks in commit message are broken when enriched ([#4069](https://github.com/gitkraken/vscode-gitlens/issues/4069))
3435

3536
## [16.3.3] - 2025-03-13
3637

src/autolinks/autolinksProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ export class AutolinksProvider implements Disposable {
301301
}
302302
}
303303

304-
if (remotes != null && remotes.length !== 0) {
304+
if (remotes?.length) {
305305
remotes = [...remotes].sort((a, b) => {
306306
const aConnected = a.maybeIntegrationConnected;
307307
const bConnected = b.maybeIntegrationConnected;

src/autolinks/models/autolinks.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,10 @@ export interface AutolinkReference {
2323
readonly descriptor?: ResourceDescriptor;
2424
}
2525

26-
export interface Autolink extends AutolinkReference {
26+
export interface Autolink extends Omit<CacheableAutolinkReference, 'id'> {
2727
provider?: ProviderReference;
2828
id: string;
2929
index?: number;
30-
31-
tokenize?:
32-
| ((
33-
text: string,
34-
outputFormat: 'html' | 'markdown' | 'plaintext',
35-
tokenMapping: Map<string, string>,
36-
enrichedAutolinks?: Map<string, MaybeEnrichedAutolink>,
37-
prs?: Set<string>,
38-
footnotes?: Map<number, string>,
39-
) => string)
40-
| null;
4130
}
4231

4332
export type EnrichedAutolink = [
@@ -51,6 +40,8 @@ export type MaybeEnrichedAutolink = readonly [
5140
];
5241

5342
export interface CacheableAutolinkReference extends AutolinkReference {
43+
id?: never;
44+
5445
tokenize?:
5546
| ((
5647
text: string,

src/autolinks/utils/-webview/autolinks.utils.ts

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -61,49 +61,51 @@ function compareAutolinks(a: Autolink, b: Autolink): number {
6161
}
6262

6363
export function ensureCachedRegex(
64-
ref: CacheableAutolinkReference,
64+
ref: Autolink | CacheableAutolinkReference,
6565
outputFormat: 'html',
6666
): asserts ref is RequireSome<CacheableAutolinkReference, 'messageHtmlRegex'>;
6767
export function ensureCachedRegex(
68-
ref: CacheableAutolinkReference,
68+
ref: Autolink | CacheableAutolinkReference,
6969
outputFormat: 'markdown',
7070
): asserts ref is RequireSome<CacheableAutolinkReference, 'messageMarkdownRegex'>;
7171
export function ensureCachedRegex(
72-
ref: CacheableAutolinkReference,
72+
ref: Autolink | CacheableAutolinkReference,
7373
outputFormat: 'plaintext',
74-
): asserts ref is RequireSome<CacheableAutolinkReference, 'messageRegex' | 'branchNameRegex'>;
74+
): asserts ref is RequireSome<CacheableAutolinkReference, 'messageRegex'>;
7575
export function ensureCachedRegex(
76-
ref: CacheableAutolinkReference,
76+
ref: Autolink | CacheableAutolinkReference,
7777
outputFormat: 'html' | 'markdown' | 'plaintext',
78-
): boolean {
78+
): void {
79+
// If the ref is a matched Autolink then only match the exact `id`
80+
const refPattern = ref.id ? ref.id : ref.alphanumeric ? '\\w+' : '\\d+';
81+
const refFlags = !ref.id && ref.ignoreCase ? 'gi' : 'g';
82+
7983
// Regexes matches the ref prefix followed by a token (e.g. #1234)
80-
if (outputFormat === 'markdown' && ref.messageMarkdownRegex == null) {
84+
if (outputFormat === 'markdown') {
8185
// Extra `\\\\` in `\\\\\\[` is because the markdown is escaped
82-
ref.messageMarkdownRegex = new RegExp(
83-
`(^|\\s|\\(|\\[|\\{)(${escapeRegex(encodeHtmlWeak(escapeMarkdown(ref.prefix)))}(${
84-
ref.alphanumeric ? '\\w' : '\\d'
85-
}+))\\b`,
86-
ref.ignoreCase ? 'gi' : 'g',
87-
);
88-
} else if (outputFormat === 'html' && ref.messageHtmlRegex == null) {
89-
ref.messageHtmlRegex = new RegExp(
90-
`(^|\\s|\\(|\\[|\\{)(${escapeRegex(encodeHtmlWeak(ref.prefix))}(${ref.alphanumeric ? '\\w' : '\\d'}+))\\b`,
91-
ref.ignoreCase ? 'gi' : 'g',
86+
ref.messageMarkdownRegex ??= new RegExp(
87+
`(^|\\s|\\(|\\[|\\{)(${escapeRegex(encodeHtmlWeak(escapeMarkdown(ref.prefix)))}(${refPattern}))\\b`,
88+
refFlags,
9289
);
93-
} else if (ref.messageRegex == null) {
94-
ref.messageRegex = new RegExp(
95-
`(^|\\s|\\(|\\[|\\{)(${escapeRegex(ref.prefix)}(${ref.alphanumeric ? '\\w' : '\\d'}+))\\b`,
96-
ref.ignoreCase ? 'gi' : 'g',
97-
);
98-
ref.branchNameRegex = new RegExp(
99-
`(^|\\-|_|\\.|\\/)(?<prefix>${ref.prefix})(?<issueKeyNumber>${
100-
ref.alphanumeric ? '\\w' : '\\d'
101-
}+)(?=$|\\-|_|\\.|\\/)`,
102-
'gi',
90+
} else if (outputFormat === 'html') {
91+
ref.messageHtmlRegex ??= new RegExp(
92+
`(^|\\s|\\(|\\[|\\{)(${escapeRegex(encodeHtmlWeak(ref.prefix))}(${refPattern}))\\b`,
93+
refFlags,
10394
);
95+
} else {
96+
ref.messageRegex ??= new RegExp(`(^|\\s|\\(|\\[|\\{)(${escapeRegex(ref.prefix)}(${refPattern}))\\b`, refFlags);
10497
}
98+
}
10599

106-
return true;
100+
export function ensureCachedBranchNameRegex(
101+
ref: CacheableAutolinkReference,
102+
): asserts ref is RequireSome<CacheableAutolinkReference, 'branchNameRegex'> {
103+
ref.branchNameRegex ??= new RegExp(
104+
`(^|\\-|_|\\.|\\/)(?<prefix>${ref.prefix})(?<issueKeyNumber>${
105+
ref.alphanumeric ? '\\w' : '\\d'
106+
}+)(?=$|\\-|_|\\.|\\/)`,
107+
'gi',
108+
);
107109
}
108110

109111
export const numRegex = /<num>/g;
@@ -165,7 +167,7 @@ export function getBranchAutolinks(branchName: string, refsets: Readonly<RefSet[
165167
continue;
166168
}
167169

168-
ensureCachedRegex(ref, 'plaintext');
170+
ensureCachedBranchNameRegex(ref);
169171
const matches = branchName.matchAll(ref.branchNameRegex);
170172
do {
171173
match = matches.next();

0 commit comments

Comments
 (0)