Skip to content

Commit 624f4ac

Browse files
authored
Git - Tweak git config parser (microsoft#166022)
Tweak git config parser
1 parent ddb50a0 commit 624f4ac

File tree

1 file changed

+24
-32
lines changed

1 file changed

+24
-32
lines changed

extensions/git/src/git.ts

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -695,45 +695,39 @@ interface GitConfigSection {
695695
}
696696

697697
class GitConfigParser {
698-
private static readonly _lineSeparator = /\r?\n/;
698+
private static readonly _lineSeparator = /\r?\n/g;
699699

700-
private static readonly _commentRegex = /^\s*[#;].*/;
701-
private static readonly _emptyLineRegex = /^\s*$/;
702700
private static readonly _propertyRegex = /^\s*(\w+)\s*=\s*(.*)$/;
703701
private static readonly _sectionRegex = /^\s*\[\s*([^\]]+?)\s*(\"[^"]+\")*\]\s*$/;
704702

705-
static parse(raw: string, sectionName: string): GitConfigSection[] {
706-
let section: GitConfigSection | undefined;
703+
static parse(raw: string): GitConfigSection[] {
707704
const config: { sections: GitConfigSection[] } = { sections: [] };
705+
let section: GitConfigSection = { name: 'DEFAULT', properties: {} };
708706

709707
const addSection = (section?: GitConfigSection) => {
710708
if (!section) { return; }
711709
config.sections.push(section);
712710
};
713711

714-
for (const configFileLine of raw.split(GitConfigParser._lineSeparator)) {
715-
// Ignore empty lines and comments
716-
if (GitConfigParser._emptyLineRegex.test(configFileLine) ||
717-
GitConfigParser._commentRegex.test(configFileLine)) {
718-
continue;
719-
}
712+
let position = 0;
713+
let match: RegExpExecArray | null = null;
720714

721-
// Section
722-
const sectionMatch = configFileLine.match(GitConfigParser._sectionRegex);
715+
while (match = GitConfigParser._lineSeparator.exec(raw)) {
716+
const line = raw.substring(position, match.index);
717+
position = match.index + match[0].length;
718+
719+
const sectionMatch = line.match(GitConfigParser._sectionRegex);
723720
if (sectionMatch?.length === 3) {
724721
addSection(section);
725-
section = sectionMatch[1] === sectionName ?
726-
{ name: sectionMatch[1], subSectionName: sectionMatch[2]?.replaceAll('"', ''), properties: {} } : undefined;
722+
section = { name: sectionMatch[1], subSectionName: sectionMatch[2]?.replaceAll('"', ''), properties: {} };
727723

728724
continue;
729725
}
730726

731727
// Properties
732-
if (section) {
733-
const propertyMatch = configFileLine.match(GitConfigParser._propertyRegex);
734-
if (propertyMatch?.length === 3 && !Object.keys(section.properties).includes(propertyMatch[1])) {
735-
section.properties[propertyMatch[1]] = propertyMatch[2];
736-
}
728+
const propertyMatch = line.match(GitConfigParser._propertyRegex);
729+
if (propertyMatch?.length === 3 && !Object.keys(section.properties).includes(propertyMatch[1])) {
730+
section.properties[propertyMatch[1]] = propertyMatch[2];
737731
}
738732
}
739733

@@ -818,7 +812,7 @@ export interface Submodule {
818812
export function parseGitmodules(raw: string): Submodule[] {
819813
const result: Submodule[] = [];
820814

821-
for (const submoduleSection of GitConfigParser.parse(raw, 'submodule')) {
815+
for (const submoduleSection of GitConfigParser.parse(raw).filter(s => s.name === 'submodule')) {
822816
if (submoduleSection.subSectionName && submoduleSection.properties['path'] && submoduleSection.properties['url']) {
823817
result.push({
824818
name: submoduleSection.subSectionName,
@@ -834,18 +828,16 @@ export function parseGitmodules(raw: string): Submodule[] {
834828
export function parseGitRemotes(raw: string): Remote[] {
835829
const remotes: Remote[] = [];
836830

837-
for (const remoteSection of GitConfigParser.parse(raw, 'remote')) {
838-
if (!remoteSection.subSectionName) {
839-
continue;
831+
for (const remoteSection of GitConfigParser.parse(raw).filter(s => s.name === 'remote')) {
832+
if (remoteSection.subSectionName) {
833+
remotes.push({
834+
name: remoteSection.subSectionName,
835+
fetchUrl: remoteSection.properties['url'],
836+
pushUrl: remoteSection.properties['pushurl'] ?? remoteSection.properties['url'],
837+
// https://github.com/microsoft/vscode/issues/45271
838+
isReadOnly: remoteSection.properties['pushurl'] === 'no_push'
839+
});
840840
}
841-
842-
remotes.push({
843-
name: remoteSection.subSectionName,
844-
fetchUrl: remoteSection.properties['url'],
845-
pushUrl: remoteSection.properties['pushurl'] ?? remoteSection.properties['url'],
846-
// https://github.com/microsoft/vscode/issues/45271
847-
isReadOnly: remoteSection.properties['pushurl'] === 'no_push'
848-
});
849841
}
850842

851843
return remotes;

0 commit comments

Comments
 (0)