88 lines
4.0 KiB
Python
88 lines
4.0 KiB
Python
import subprocess, sys, re, os
|
|
|
|
sys.stdout.reconfigure(encoding='utf-8')
|
|
|
|
res = subprocess.run(['git', '-c', 'core.quotepath=false', 'diff', '-U5', '0054b5ac..3cd61cad'], capture_output=True, text=True, encoding='utf-8')
|
|
diff_text = res.stdout
|
|
|
|
file_diffs = diff_text.split('diff --git ')
|
|
print(f"Total files modified in 3cd61cad: {len(file_diffs)-1}")
|
|
|
|
possible_duplicates_found = []
|
|
|
|
for fd in file_diffs[1:]:
|
|
lines = fd.split('\n')
|
|
header = lines[0]
|
|
filename = header.split(' ')[0][2:]
|
|
if "2026년_건설공사_표준품셈.md" in filename:
|
|
continue # Check split files only
|
|
|
|
# Read full content of current file
|
|
with open(filename, 'r', encoding='utf-8') as f:
|
|
file_lines = f.readlines()
|
|
|
|
raw_hunks = re.split(r'\n@@\s+[^@]+\s+@@\n', fd)[1:]
|
|
|
|
for h_idx, h in enumerate(raw_hunks):
|
|
h_lines = h.split('\n')
|
|
# Get added lines (starting with +)
|
|
added_lines = [l[1:].strip() for l in h_lines if l.startswith('+') and l[1:].strip().startswith('|') and not all(re.match(r'^:?-+:?$', c) for c in [x.strip() for x in l[1:].strip().split('|')[1:-1]] if c)]
|
|
# Get deleted lines (starting with -)
|
|
del_lines = [l[1:].strip() for l in h_lines if l.startswith('-') and l[1:].strip().startswith('|')]
|
|
|
|
if not added_lines:
|
|
continue
|
|
|
|
# Find where added_lines appear in file_lines
|
|
first_added = added_lines[0]
|
|
match_idx = -1
|
|
for idx, fl in enumerate(file_lines):
|
|
if fl.strip() == first_added:
|
|
match_idx = idx
|
|
break
|
|
|
|
if match_idx == -1:
|
|
continue
|
|
|
|
# Check 40 lines above and 40 lines below match_idx
|
|
# for duplicate table data
|
|
added_content_words = set(w for l in added_lines for w in re.findall(r'[가-힣A-Za-z0-9]+', l) if len(w) > 1 and w not in ["인부", "보통인부", "특별인부"])
|
|
added_nums = set(n for l in added_lines for n in re.findall(r'\b\d+(?:\.\d+)?\b', l))
|
|
|
|
# Check above lines (match_idx - 40 to match_idx - 1)
|
|
above_start = max(0, match_idx - 50)
|
|
above_lines = [file_lines[i].strip() for i in range(above_start, match_idx) if file_lines[i].strip().startswith('|')]
|
|
|
|
# Check below lines (match_idx + len(added_lines) to match_idx + len(added_lines) + 50)
|
|
below_start = match_idx + len(added_lines)
|
|
below_end = min(len(file_lines), below_start + 50)
|
|
below_lines = [file_lines[i].strip() for i in range(below_start, below_end) if file_lines[i].strip().startswith('|')]
|
|
|
|
# Check if above or below contains significant overlap with added_lines
|
|
for region_name, r_lines in [('above', above_lines), ('below', below_lines)]:
|
|
overlap_rows = 0
|
|
for rl in r_lines:
|
|
rl_words = set(w for w in re.findall(r'[가-힣A-Za-z0-9]+', rl) if len(w) > 1 and w not in ["인부", "보통인부", "특별인부"])
|
|
rl_nums = set(re.findall(r'\b\d+(?:\.\d+)?\b', rl))
|
|
common_w = added_content_words.intersection(rl_words)
|
|
common_n = added_nums.intersection(rl_nums)
|
|
if len(common_w) >= 2 and len(common_n) >= 1:
|
|
overlap_rows += 1
|
|
|
|
if overlap_rows >= 3:
|
|
possible_duplicates_found.append({
|
|
'file': os.path.basename(filename),
|
|
'hunk': h_idx,
|
|
'line': match_idx + 1,
|
|
'region': region_name,
|
|
'overlap_rows': overlap_rows,
|
|
'added_sample': added_lines[0],
|
|
'region_sample': r_lines[0] if r_lines else ''
|
|
})
|
|
|
|
print(f"\nPossible duplicated / overlapping fixes: {len(possible_duplicates_found)}")
|
|
for p in possible_duplicates_found:
|
|
print(f"[{p['file']}:L{p['line']}] Hunk {p['hunk']} overlaps with {p['region']} ({p['overlap_rows']} rows)")
|
|
print(f" Added: {p['added_sample']}")
|
|
print(f" {p['region']}: {p['region_sample']}")
|