* Check if a config line like `[remote "origin"]` matches the given section/subsection. * Section matching is case-insensitive; subsection matching is case-sensitive.
( line: string, sectionLower: string, subsection: string | null, )
| 196 | * Section matching is case-insensitive; subsection matching is case-sensitive. |
| 197 | */ |
| 198 | function matchesSectionHeader( |
| 199 | line: string, |
| 200 | sectionLower: string, |
| 201 | subsection: string | null, |
| 202 | ): boolean { |
| 203 | // line starts with '[' |
| 204 | let i = 1 |
| 205 | |
| 206 | // Read section name |
| 207 | while ( |
| 208 | i < line.length && |
| 209 | line[i] !== ']' && |
| 210 | line[i] !== ' ' && |
| 211 | line[i] !== '\t' && |
| 212 | line[i] !== '"' |
| 213 | ) { |
| 214 | i++ |
| 215 | } |
| 216 | const foundSection = line.slice(1, i).toLowerCase() |
| 217 | |
| 218 | if (foundSection !== sectionLower) { |
| 219 | return false |
| 220 | } |
| 221 | |
| 222 | if (subsection === null) { |
| 223 | // Simple section: must end with ']' |
| 224 | return i < line.length && line[i] === ']' |
| 225 | } |
| 226 | |
| 227 | // Skip whitespace before subsection quote |
| 228 | while (i < line.length && (line[i] === ' ' || line[i] === '\t')) { |
| 229 | i++ |
| 230 | } |
| 231 | |
| 232 | // Must have opening quote |
| 233 | if (i >= line.length || line[i] !== '"') { |
| 234 | return false |
| 235 | } |
| 236 | i++ // skip opening quote |
| 237 | |
| 238 | // Read subsection — case-sensitive, handle \\ and \" escapes |
| 239 | let foundSubsection = '' |
| 240 | while (i < line.length && line[i] !== '"') { |
| 241 | if (line[i] === '\\' && i + 1 < line.length) { |
| 242 | const next = line[i + 1]! |
| 243 | if (next === '\\' || next === '"') { |
| 244 | foundSubsection += next |
| 245 | i += 2 |
| 246 | continue |
| 247 | } |
| 248 | // Git drops the backslash for other escapes in subsections |
| 249 | foundSubsection += next |
| 250 | i += 2 |
| 251 | continue |
| 252 | } |
| 253 | foundSubsection += line[i] |
| 254 | i++ |
| 255 | } |