From 62126e5e0e963755854b8489a51fa5ded5b13938 Mon Sep 17 00:00:00 2001 From: ksj09406 Date: Mon, 28 Sep 2026 13:58:46 +0900 Subject: [PATCH] =?UTF-8?q?=EC=99=BC=EC=AA=BD=20=EC=A4=84=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=EA=B0=80=20=EB=B0=80=EB=A6=AC=EB=8D=98=20=EA=B2=83=20?= =?UTF-8?q?-=20=EC=99=BC=EC=AA=BD=EB=8F=84=20=EB=8B=A4=EC=8B=9C=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=EB=A5=BC=20=EB=A7=A8=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 사용자 보고. 12차 B-1 로 왼쪽에도 반영할 수 있게 되면서 왼쪽 줄이 늘고 주는데, 번호는 정렬기가 처음 준 것 그대로였다. 오른쪽에만 있던 줄을 왼쪽에 넣으면 그 줄은 번호가 비고 뒤 줄은 옛 번호를 달아 01 02 (빈) 03 04 05 (빈) 06 으로 보였다. 왼쪽 파일은 8줄이 됐는데 번호는 6까지라 어느 줄을 고쳤는지 짚을 수 없었다. MergeLine.BaseNumber 의 설명에는 이미 "이제 두 파일 비교에서는 번호도 따라 바뀐다" 고 적혀 있었지만 실제로 다시 매기는 자리가 없었다 - 적어 둔 뜻과 코드가 어긋나 있었다. - RenumberBase 를 RenumberMerged(8차 B-3) 옆에 두고, 그릴 때마다 왼쪽에 있는 줄만 1부터 다시 맨다 - 두 파일 비교(BothWays)에서만. Git 모드 · 네 칸의 BASE 는 지난 커밋 · 공통 조상이라 고칠 수 없고, 그때 번호는 그 파일의 번호이므로 건드리지 않는다 - "머지 반영함" 표시는 BASE 줄 번호를 열쇠로 붙들고 있다(_appliedBaseNumbers) - 번호가 실제로 달라질 때만 그 열쇠도 옛 번호에서 새 번호로 옮겨 담는다. 안 그러면 규칙을 한 번 건드리는 순간 엉뚱한 줄이 반영함으로 칠해진다 화면으로 확인: 연 직후 01..07, 두 줄 넣으면 01..09 로 이어짐, 되돌려도 이어짐, 왼쪽 저장하면 파일 9줄 = 칸의 끝 번호 09, Git 모드 회귀 그대로. 하네스 27벌 1,787건 · 실패 0. 빌드 경고 0 · 오류 0. 아직 확정하지 못한 것: 왼쪽에만 있는 줄을 [<] 로 뺄 때 왼쪽 줄 수가 하나 주는지. 따로 열어 한 번 누르면 잘 빠지는데(3줄 -> 2줄), 다른 반영을 몇 번 한 뒤에는 시험 도구가 읽은 줄 칸이 낡아 옆 줄 단추를 눌러 값이 흔들렸다. 번호 불변식(늘 1부터 이어지고 빠진 번호가 없다)은 어느 경우에도 지켜졌다. Co-Authored-By: Claude Opus 5 --- doc/history/2026-09-23-12차.md | 55 ++++++++++++++++++++++ doc/history/changelog.md | 1 + doc/진행상황.md | 7 +++ src/MergeHub/ViewModels/HomeViewModel.cs | 58 ++++++++++++++++++++++++ 4 files changed, 121 insertions(+) diff --git a/doc/history/2026-09-23-12차.md b/doc/history/2026-09-23-12차.md index 7cda588..8ca3ba4 100644 --- a/doc/history/2026-09-23-12차.md +++ b/doc/history/2026-09-23-12차.md @@ -285,6 +285,61 @@ BASE 칸 자신은 견줄 것이 없어 `4줄 · 기준` 이라고만 적는다. 실제로 켜서 잰 하단 탭 줄이 **111px · 항목 109px**(배율 150% 기준 72.7 DIP)로 "후" 값과 맞았다. 앞서 적었던 "지금 배포 폴더에는 예전 것이 그대로" 는 그 뒤 빌드로 낡은 글이 되어 고쳤다. +## B-1 을 쓰다 나온 것 - 왼쪽 줄 번호가 밀린다 (2026-09-28, 사용자 보고) + +### 먼저 재현 (화면, 값) + +왼쪽 6줄 · 오른쪽 8줄(오른쪽에만 있는 줄 둘)로 열고, 오른쪽에만 있는 줄을 `[<]` 로 왼쪽에 넣었다. + +| | 왼쪽 칸 번호 | +|---|---| +| 연 직후 | `01 02 03 04 05 06` | +| 한 줄 넣은 뒤 | `01 02 · 03 04 05 06` | +| 두 줄 넣은 뒤 | `01 02 · 03 04 05 · 06` | + +`·` 는 번호가 **비어 있는 줄**이다. 왼쪽 파일은 8줄이 됐는데 번호는 6까지만 있고, 새로 들어간 줄에는 +번호가 없다. 저장하면 8줄로 써지므로 "몇 번째 줄을 고쳤나" 를 번호로 짚을 수가 없다. + +### 까닭 + +8차 B-3 에서 만든 `RenumberMerged` 는 **오른쪽(MERGED) 칸만** 다시 번호를 맨다. 그때는 BASE 가 얼어 있었다. +12차 B-1 로 **왼쪽에도 반영**할 수 있게 되면서 왼쪽 줄이 늘고 줄게 됐는데, 왼쪽은 정렬기가 처음 준 번호를 +그대로 달고 있었다. `MergeLine.BaseNumber` 의 설명에는 이미 "이제 두 파일 비교에서는 … 번호도 따라 바뀐다" 고 +적혀 있었지만 실제로 다시 매기는 자리가 없었다 - 적어 둔 뜻과 코드가 어긋나 있었다. + +### 고친 것 + +`RenumberBase` 를 `RenumberMerged` 옆에 두고, 그릴 때마다(`UpdateSummaries`) 왼쪽에 있는 줄만 1부터 다시 맨다. + +- **두 파일 비교에서만**(`BothWays`). Git 모드 · 네 칸의 BASE 는 지난 커밋 · 공통 조상이라 고칠 수 없고, + 그때 번호는 그 파일의 번호이므로 건드리면 안 된다. +- **"머지 반영함" 표시의 열쇠를 함께 옮긴다.** 그 표시는 BASE 줄 번호로 붙들려 있어서(`_appliedBaseNumbers`), + 번호만 바꾸면 규칙을 한 번 건드리는 순간 엉뚱한 줄이 반영함으로 칠해진다. 번호가 실제로 달라질 때만 + 옛 번호 → 새 번호로 옮겨 담는다(안 바뀌면 손대지 않는다 - 연 직후가 그렇다). + +### 화면으로 확인 (값) + +왼쪽 7줄(왼쪽에만 있는 줄 하나) · 오른쪽 8줄로 다시 잡고 봤다. + +| 확인 | 값 | +|---|---| +| 연 직후 | `01 … 07` · 왼쪽 줄 수 = 파일 줄 수 7 | +| 오른쪽 줄 둘을 왼쪽에 넣음 | `01 … 09` 로 이어짐 · 왼쪽 9줄 | +| 왼쪽에만 있는 줄을 반영 | 번호가 이어짐 · 번호 빠진 줄 0 | +| 되돌리기 | 번호가 이어짐 · 번호 빠진 줄 0 | +| 왼쪽 저장 | 저장한 파일 9줄 = 칸의 끝 번호 09 · 넣은 줄이 파일에 있음 | +| Git 모드(회귀) | BASE 번호 그대로 이어짐 | + +하네스 27벌 **1,787건** 통과 · 실패 0, E-2 화면 세 벌도 그대로 통과(빌드 경고 0 · 오류 0). + +### 아직 확인하지 못한 것 + +"왼쪽에만 있는 줄을 `[<]` 로 빼면 왼쪽 줄 수가 하나 준다" 는 것은 **값으로 확정하지 못했다.** +따로 열어 한 번만 누르면 잘 빠지는데(3줄 → 2줄 확인), 다른 반영을 몇 번 한 뒤에 같은 것을 하면 +시험 도구가 읽은 줄 칸이 낡아 옆 줄 단추를 누르는 일이 생겨 값이 흔들렸다. +번호 쪽 불변식(늘 1부터 이어지고 빠진 번호가 없다)은 어느 경우에도 지켜졌다. +**빼는 길 자체가 제대로 도는지는 따로 봐야 한다.** + ## E-2. 여러 짝을 동시에 (문서 탭) (2026-09-28, 완료) ### 먼저 재현 (화면, 값) diff --git a/doc/history/changelog.md b/doc/history/changelog.md index 38987fd..5cf9592 100644 --- a/doc/history/changelog.md +++ b/doc/history/changelog.md @@ -8,6 +8,7 @@ | 날짜 | 항목 | 커밋 | |---|---|---| +| 2026-09-28 | **왼쪽 줄 번호가 밀리던 것**(사용자 보고) — 12차 B-1 로 왼쪽에도 반영할 수 있게 되면서 왼쪽 줄이 늘고 주는데, 번호는 정렬기가 처음 준 것 그대로였다. 오른쪽에만 있던 줄을 왼쪽에 넣으면 그 줄은 번호가 비고 뒤 줄은 옛 번호를 달아 `01 02 · 03 04 05 · 06` 으로 보였다 — 왼쪽 파일은 8줄인데 번호는 6까지라 어느 줄을 고쳤는지 짚을 수 없었다. `RenumberBase` 를 `RenumberMerged`(8차 B-3) 옆에 두고 두 파일 비교에서만 왼쪽 줄을 1부터 다시 맨다. Git 모드 · 네 칸의 BASE 는 고칠 수 없는 쪽이라 건드리지 않는다. "머지 반영함" 표시가 BASE 줄 번호를 열쇠로 붙들고 있어 번호가 실제로 달라질 때만 그 열쇠도 옛 번호 → 새 번호로 옮긴다. 화면으로 넣기 · 빼기 · 되돌리기 · 저장 · Git 회귀 확인, 하네스 27벌 1,787건 · 실패 0. **왼쪽에만 있는 줄을 뺄 때 줄 수가 주는지는 값으로 확정하지 못했다**(시험 도구가 낡은 줄 칸을 집는 한계) | 아래 | | 2026-09-28 | **12차 E-2** — 파일 비교가 짝 여러 개를 동시에 든다(문서 탭). 지금까지는 한 짝만 들어서 짝을 바꾸면 "저장하지 않은 편집이 있습니다" 를 묻고 버리면 고친 글이 사라졌다(재현: 16줄 → 15줄). 이제 떠 있던 탭이 그 글을 맡아 두므로 **묻지 않는다**. 탭마다 `HomeViewModel` 을 따로 만들지 않고(GitWorkspace 의 한 자리짜리 약속 때문) 화면은 하나로 두고 탭이 **파일에 없는 것만** 맡는다 — 고친 글 · 왼쪽 글(B-1) · 되돌리기 이력 · 두 기준점 · 캐럿 · 스크롤 · 저장 형식. 탭 이름은 파일 이름(다르면 `왼 ↔ 오`, 겹치면 위 폴더를 갈릴 때까지 덧붙임), 저장 안 한 탭은 `•`. 탭 줄은 둘 이상일 때만 보인다. `◀ 이전 · 다음 ▶` 은 지금 탭의 짝만 바꾸고(탭이 늘지 않음), 폴더 비교에서 두 번 누르면 새 탭(사용자 결정). Ctrl+Tab · Ctrl+Shift+Tab · Ctrl+W · 가운데 단추 닫기. 탭이 사라져도 고친 글은 **보관함**(짝 50개)에 남아 다시 열면 되살아난다 — E-1 은 이 보관함을 파일로 옮겨 적으면 된다. 원본이 그 사이 바뀌면 되살리고 알린다("연 시점"은 새로 읽은 글로 둔다). 탭 줄은 ItemsControl 이 아니라 ListBox 다(ItemsControl 은 UIA 에 컨트롤로 안 보여 화면 시험이 못 읽는다). 켤 때 저절로 열리는 짝만 탭이 없어 편집이 사라지던 것을 화면에서 찾아 `EnsureTabForCurrentPair` 로 고쳤다. 켜 놓고 눈으로 보다 두 가지를 더 고쳤다(사용자가 고름) — 중괄호 맞춤으로만 바뀐 것에는 점을 붙이지 않고(묻는 자리와 같은 기준), 탭 이름은 양쪽이 같은 부분을 한 번만 적는다(`WeldController_기준.cs ↔ WeldController_내작...` → `WeldController_기준 ↔ 내작업.cs`, 421 → 288px). 뒤쪽은 확장자일 때만 접는다 — 글자 단위로 세면 `a-lef ↔ right.cs` 처럼 낱말 가운데서 잘린다(하네스에서 걸렸다). 하네스 `DocTabTest` 106건, 화면 34건 · 회귀 19건 통과, 전체 27벌 1,787건 · 실패 0. **커밋 안 함**(사용자 지시) | 아래 | | 2026-09-28 | **시험 도구를 런처에 맞춤** — 새 플랫폼은 `UbisamBase.Launcher.exe` 가 셸을 같은 프로세스에 올려 창 주인 프로세스 이름이 바뀌었고, 예전 이름만 찾던 화면 시험 도구가 전부 "창이 안 뜬다" 로 멈춰 있었다. `a2lib.ps1` 에 `Shell-Procs` · `Shell-Proc` · `Stop-App` 을 두고 `Start-App` · `Get-Win` 이 그것을 쓰게 했다(런처가 제목 없는 진행 창을 먼저 띄우는 경우를 대비해 제목 있는 창을 먼저 고름). 스크립트 76개 · 156곳을 함께 고침. 문법 187개 통과, 끄기 → 켜기 → 창 찾기 → 네 탭 → 단추 → 끄기까지 실제로 돌았고 설정 · 창 자리 네 파일 해시 그대로 되돌림. **제품 코드 변경 없음** | 없음 | | 2026-09-28 | **12차 C-2** — 플랫폼 하단 탭 줄을 한 단계 작게(항목 74 → 61 DIP: 여백 13/14→9/10 · 아이콘 22→20 · 아이콘 아래 틈 7→5 · 글자 13.5→12.5). 실측 133 → 109px(−18%)이고 그만큼 콘텐츠가 늘어 파일 비교 코드 칸이 47 → 48줄. 라벨 잘림 · 선택 밑줄 · 탭 접기 띠 · 오른쪽 동작 항목 모두 그대로. 플랫폼 쪽이라 모든 사내 프로그램에 함께 간다. 처음에는 배포본을 백업해 잠깐 바꿔치기해 시험하고 되돌렸으나, 그 뒤 **새 플랫폼을 빌드하면서 함께 배포됐다** — 2026-09-28 배포본 `UbisamBase.Core.dll` 해시 일치 · 화면 실측 111px(항목 109px)로 확인. **커밋 안 함**(사용자 지시) | 없음 | diff --git a/doc/진행상황.md b/doc/진행상황.md index 44193f2..ef1673f 100644 --- a/doc/진행상황.md +++ b/doc/진행상황.md @@ -426,6 +426,13 @@ | **완료** | E-2 여러 짝을 동시에(문서 탭) — 파일 비교 맨 위에 문서 탭 줄(둘 이상일 때만 보임). 탭 이름은 파일 이름 · 다르면 `왼 ↔ 오` · 겹치면 위 폴더를 덧붙임 · 저장 안 한 탭은 `•`. 짝을 바꿀 때 **묻지 않는다**(탭이 편집을 맡는다). 탭이 사라져도 고친 글은 보관함에 남아 다시 열면 되살아남(◀ ▶ 로 훑다 돌아와도). Ctrl+Tab · Ctrl+Shift+Tab · Ctrl+W · 가운데 단추 닫기. 탭마다 되돌리기 · 캐럿 · 스크롤 · 저장 형식. 상한 20(고친 탭은 안 닫음). 탭 이름은 **양쪽이 같은 부분을 한 번만** 적는다(`WeldController_기준 ↔ 내작업.cs` — 421 → 288px). 점은 **사람이 손댄 것만**(스타일 맞춤으로만 바뀐 것은 빼고 센다 — 묻는 자리와 같은 기준). 하네스 `DocTabTest` 106건, 화면 34건 · 회귀 19건 확인 | | 할 일 | E-1 꺼도 남는 편집(notepad++ 식) — E-2 의 보관함을 `{설정 폴더}\Session\` 에 옮겨 적고 켤 때 되살린다 | +### 쓰다 나온 것 + +| 상태 | 항목 | +|---|---| +| **완료** | 왼쪽 줄 번호가 밀린다(사용자 보고) — 12차 B-1 로 왼쪽에도 반영할 수 있게 됐는데 왼쪽 번호를 다시 매기는 자리가 없었다. 줄을 넣으면 그 줄은 번호가 비고 뒤 줄은 옛 번호(`01 02 · 03 04 05 · 06`), 저장하면 8줄인데 번호는 6까지. `RenumberBase` 를 두어 두 파일 비교에서만 왼쪽 줄을 1부터 다시 맨다. "머지 반영함" 표시가 BASE 번호를 열쇠로 쓰므로 그 열쇠도 함께 옮긴다. Git · 네 칸은 손대지 않는다 | +| 볼 것 | 왼쪽에만 있는 줄을 `[<]` 로 뺄 때 줄 수가 실제로 주는지 — 따로 열면 되는데 다른 반영 뒤에는 시험 도구가 낡은 줄 칸을 집어 값이 흔들렸다. 번호 불변식은 지켜짐 | + ### 시험 도구 | 상태 | 항목 | diff --git a/src/MergeHub/ViewModels/HomeViewModel.cs b/src/MergeHub/ViewModels/HomeViewModel.cs index cf9a80e..f019840 100644 --- a/src/MergeHub/ViewModels/HomeViewModel.cs +++ b/src/MergeHub/ViewModels/HomeViewModel.cs @@ -4104,6 +4104,7 @@ namespace MergeHub.ViewModels { // 줄을 고르거나 머지 주석이 끼어들면 결과 줄 수가 바뀐다. 그릴 때마다 번호를 다시 매긴다(8차 B-3). RenumberMerged(Lines); + RenumberBase(Lines); // 왼쪽도 마찬가지다(12차 B-1 로 왼쪽이 바뀔 수 있게 됐다) var total = Lines.Count; var diff = Lines.Count(l => l.IsDifferent); @@ -4628,6 +4629,63 @@ namespace MergeHub.ViewModels for (var i = 0; i < rows.Count; i++) rows[i].LocalNumber = numbers[i]; } + /// + /// 왼쪽(BASE) 칸 번호를 왼쪽 파일 번호로 다시 매긴다(12차 B-1 을 쓰다 나온 것, 2026-09-28). + /// + /// 무엇이 잘못됐었나 - 12차 B-1 로 왼쪽에도 반영할 수 있게 되면서 왼쪽 줄이 늘고 줄게 됐는데, + /// 번호는 정렬기가 처음 준 것 그대로였다. 오른쪽에만 있던 줄을 왼쪽에 넣으면 그 줄은 번호가 비고 + /// 뒤 줄은 옛 번호를 그대로 달고 있어, 왼쪽 파일이 8줄인데 칸에는 01 02 (빈) 03 04 05 (빈) 06 으로 보였다. + /// 저장하면 8줄이 되는데 번호는 6까지만 있으니 어느 줄을 고쳤는지 짚을 수가 없다. + /// + /// + /// Git 모드 · 네 칸(3-Way)의 BASE 는 지난 커밋 · 공통 조상이라 고칠 수 없다 - 그때 번호는 그 파일의 번호이므로 + /// 건드리지 않는다. 두 파일 비교()에서만 다시 맨다. + /// + /// + /// + /// "머지 반영함" 표시는 BASE 줄 번호를 열쇠로 붙들고 있다() - + /// 번호를 바꾸면 그 열쇠도 같은 줄을 가리키도록 함께 옮긴다. 안 그러면 규칙을 한 번 건드리는 순간 + /// 엉뚱한 줄이 "반영함"으로 칠해진다. + /// + /// + private void RenumberBase(IList rows) + { + if (!BothWays || rows is null || rows.Count == 0) return; + + var inLeft = new bool[rows.Count]; + for (var i = 0; i < rows.Count; i++) inLeft[i] = rows[i].HasBase; + + var numbers = MergedNumbering.Assign(inLeft); + + // 바뀐 것이 없으면(연 직후가 그렇다) 표시도 건드리지 않는다. + var changed = false; + for (var i = 0; i < rows.Count; i++) + { + if (rows[i].BaseNumber == numbers[i]) continue; + changed = true; + break; + } + if (!changed) return; + + var moved = _appliedBaseNumbers.Count > 0 ? new HashSet() : null; + + for (var i = 0; i < rows.Count; i++) + { + if (moved is not null && rows[i].BaseNumber is int was && numbers[i] is int now && + _appliedBaseNumbers.Contains(was)) + { + moved.Add(now); + } + + rows[i].BaseNumber = numbers[i]; + } + + if (moved is null) return; + + _appliedBaseNumbers.Clear(); + foreach (var number in moved) _appliedBaseNumbers.Add(number); + } + private string BuildLocalText() => PaneText.Build(Lines, MergeLine.TextPane.Local); } }