(pages)
| 459 | |
| 460 | |
| 461 | def find_conflicts(pages): |
| 462 | out = [] |
| 463 | for p in pages: |
| 464 | # 跳过反引号 / 围栏代码——周报、运维文档讨论冲突格式不应触发。 |
| 465 | # mask_code_spans 保留行结构(仅把代码字符替换为空格),故掩码后的行与 |
| 466 | # 原文行一一对应:用掩码行判定 / 起始匹配,用原文行还原 block 文本。 |
| 467 | scan_lines = mask_code_spans(p.raw_content).split("\n") |
| 468 | raw_lines = p.raw_content.split("\n") |
| 469 | i = 0 |
| 470 | n = len(scan_lines) |
| 471 | while i < n: |
| 472 | if not CONFLICT_START_RE.match(scan_lines[i]): |
| 473 | i += 1 |
| 474 | continue |
| 475 | # 命中起始行:逐行收集"以 > 开头 或 空行"的连续行,直到真内容行 |
| 476 | start = i |
| 477 | j = i + 1 |
| 478 | while j < n: |
| 479 | s = scan_lines[j] |
| 480 | if s.startswith(">") or s.strip() == "": |
| 481 | j += 1 |
| 482 | continue |
| 483 | break |
| 484 | # 还原 block:从原文取 [start, j) 行,去掉尾部空行 |
| 485 | block_lines = raw_lines[start:j] |
| 486 | while block_lines and block_lines[-1].strip() == "": |
| 487 | block_lines.pop() |
| 488 | out.append({ |
| 489 | "path": p.path, |
| 490 | "title": p.title, |
| 491 | "block": "\n".join(block_lines).strip(), |
| 492 | "line": start + 1, |
| 493 | }) |
| 494 | # 从块结束处继续(避免把同一块重复匹配) |
| 495 | i = max(j, start + 1) |
| 496 | return out |
| 497 | |
| 498 | |
| 499 | def find_to_update(pages): |
no test coverage detected