Skip to content

Commit 94d91e7

Browse files
committed
Fixes #3246 preserves links in commit messages
1 parent 9a12a14 commit 94d91e7

File tree

3 files changed

+42
-12
lines changed

3 files changed

+42
-12
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
1717

1818
### Fixed
1919

20-
- Fixes Incorrect PR Link Across Azure DevOps Projects ([#4207](https://github.com/gitkraken/vscode-gitlens/issues/4207))
20+
- Fixes incorrect PR Link Across Azure DevOps Projects ([#4207](https://github.com/gitkraken/vscode-gitlens/issues/4207))
21+
- Fixes detail view incorrectly parses GitHub account in commit message ([#3246](https://github.com/gitkraken/vscode-gitlens/issues/3246))
2122

2223
## [17.0.1] - 2025-04-03
2324

src/git/formatters/commitFormatter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ export class CommitFormatter extends Formatter<GitCommit, CommitFormatOptions> {
734734
message = encodeHtmlWeak(message);
735735
}
736736
if (outputFormat === 'markdown') {
737-
message = escapeMarkdown(message, { quoted: true, inlineBackticks: true });
737+
message = escapeMarkdown(message, { quoted: true, inlineBackticks: true, preserveLinks: true });
738738
}
739739

740740
if (this._options.messageAutolinks) {

src/system/markdown.ts

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
const escapeMarkdownRegex = /[\\*_{}[\]()#+\-.!]/g;
2-
const unescapeMarkdownRegex = /\\([\\`*_{}[\]()#+\-.!])/g;
1+
const escapeMarkdownRegex = /[\\*_{}[\]()#+\-.!<>]/g;
2+
const unescapeMarkdownRegex = /\\([\\`*_{}[\]()#+\-.!<>])/g;
3+
// Regex to find markdown links: [text](url) allowing for escaped brackets/parens within text/url
4+
const markdownLinkRegex = /(\[((?:\\.|[^[\]\\])+)\]\(((?:\\.|[^()\\])+)\))/g;
35

46
const escapeMarkdownHeaderRegex = /^===/gm;
57
const unescapeMarkdownHeaderRegex = /^\u200b===/gm;
@@ -8,19 +10,46 @@ const unescapeMarkdownHeaderRegex = /^\u200b===/gm;
810
const markdownQuotedRegex = /\r?\n/g;
911
const markdownBacktickRegex = /`/g;
1012

11-
export function escapeMarkdown(s: string, options: { quoted?: boolean; inlineBackticks?: boolean } = {}): string {
12-
s = s
13-
// Escape markdown
14-
.replace(escapeMarkdownRegex, '\\$&')
15-
// Escape markdown header (since the above regex won't match it)
16-
.replace(escapeMarkdownHeaderRegex, '\u200b===');
13+
export function escapeMarkdown(
14+
s: string,
15+
options?: { quoted?: boolean; inlineBackticks?: boolean; preserveLinks?: boolean },
16+
): string {
17+
// If preserving links, replace them with placeholders first
18+
if (options?.preserveLinks) {
19+
const links = new Map<string, string>();
20+
let linkIndex = 0;
1721

18-
if (options.inlineBackticks) {
22+
s = s.replace(markdownLinkRegex, match => {
23+
// Create a unique, unlikely-to-occur placeholder
24+
const placeholder = `$$$GLLINK${linkIndex++}GLLINK$$$`;
25+
links.set(placeholder, match);
26+
return placeholder;
27+
});
28+
29+
// Escape markdown characters
30+
s = s.replace(escapeMarkdownRegex, '\\$&');
31+
32+
// Restore the original links if they were preserved
33+
if (options?.preserveLinks && links.size) {
34+
for (const [placeholder, originalLink] of links) {
35+
s = s.replace(placeholder, originalLink);
36+
}
37+
}
38+
} else {
39+
// Escape markdown characters
40+
s = s.replace(escapeMarkdownRegex, '\\$&');
41+
}
42+
43+
// Escape markdown header (since the above regex won't match it)
44+
s = s.replace(escapeMarkdownHeaderRegex, '\u200b===');
45+
46+
if (options?.inlineBackticks) {
1947
s = escapeMarkdownCodeBlocks(s);
2048
} else {
2149
s = s.replace(markdownBacktickRegex, '\\$&');
2250
}
23-
if (!options.quoted) return s;
51+
52+
if (!options?.quoted) return s;
2453

2554
// Keep under the same block-quote but with line breaks
2655
return s.trim().replace(markdownQuotedRegex, '\t\\\n> ');

0 commit comments

Comments
 (0)