전체 반영 · 자동 병합의 주석을 구간마다 한 줄로 (사용자 요청 · 결정)
[전체 반영] 은 줄마다 Apply 를 따로 불러 바뀐 줄마다 머지 주석이 붙고 Undo 도 줄마다 한 걸음이었다. [구간 반영] 처럼 구간마다 주석 한 줄로 바꾼다. - 두 파일 비교 [전체 반영]: 반영할 수 있는 줄이 이어진 구간(BlockAround 와 같은 기준)을 먼저 나눠 구간마다 ApplyGroup. 지우는 반영은 "삭제 N줄". 모든 구간을 한 묶음 번호로 넘겨 Undo 한 번에 전체가 돌아간다. ApplyGroup 에 group · finish 를 더함. - 3-Way [전체 반영] 은 끈다(사용자 결정) - 차이 나는 모든 줄을 공통 조상(BASE)으로 바꾸던 동작이라 병합에서 쓸 데가 없고 양쪽 작업을 지운다. 꺼져도 툴팁으로 까닭. - 3-Way [자동 병합] 도 저쪽만 고친 줄 구간마다 주석 한 줄 · Undo 한 번. 사이에 낀 충돌 · 내가 고친 줄은 구간을 끊고 그대로 둔다. 시험: 빌드 경고 0 · 오류 0. 화면 g22-accept-all(새) 주석 7 -> 3 · 삭제 2줄 · BASE 와 같음 · Undo 한 번, g23-three-way(새, --merge) 전체 반영 꺼짐 · 주석 5 -> 2 · 내 줄 · 충돌 줄 그대로 · Undo 한 번. 실패 0. 기존 회귀는 사용자 지시로 돌리지 않았다. Agent: main (claude-opus-5-5) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
04b76df807
commit
b717f4ed06
@ -2,6 +2,21 @@
|
|||||||
|
|
||||||
지시서: [../작업지시/12차.md](../작업지시/12차.md)
|
지시서: [../작업지시/12차.md](../작업지시/12차.md)
|
||||||
|
|
||||||
|
## 전체 반영 · 자동 병합의 주석이 너무 많다 (2026-10-01, 사용자 요청 · 결정 · 완료)
|
||||||
|
|
||||||
|
[전체 반영] 은 반영할 줄마다 `Apply` 를 따로 불러 **바뀐 줄마다 머지 주석 한 줄**, 되돌리기도 줄마다 한 걸음이었다.
|
||||||
|
[구간 반영] 은 이어진 차이 구간을 `ApplyGroup` 으로 묶어 구간마다 주석 한 줄(`N~M행 구간 … 반영 (k줄)`)만 남긴다.
|
||||||
|
|
||||||
|
- **두 파일 비교 [전체 반영]** → 반영할 수 있는 줄이 이어진 구간(구간 반영의 `BlockAround` 와 같은 기준)을 먼저 다 나눈 뒤
|
||||||
|
구간마다 `ApplyGroup` — 주석은 구간마다 한 줄, 지우는 반영이 섞이면 `삭제 N줄`. 모든 구간을 한 묶음 번호로 넘겨 **Undo 한 번에 전체가** 돌아간다.
|
||||||
|
`ApplyGroup` 에 `group` · `finish` 를 더했다(여러 구간을 이을 때 화면 맞추기는 끝에 한 번). 끝나면 `N구간 M줄 반영` 알림.
|
||||||
|
- **3-Way [전체 반영] 은 끈다**(사용자 결정). 3-Way 에서 이 단추는 차이 나는 모든 줄을 **공통 조상(BASE)** 으로 바꿨다 — 나와 저쪽 변경을 함께 지우는 일이라 병합에서 쓸 데가 없고,
|
||||||
|
"저쪽 전부" 로 바꾸면 충돌 줄까지 말없이 덮는다. 꺼져 있어도 툴팁(`ShowOnDisabled`)으로 까닭을 보인다.
|
||||||
|
- **3-Way [자동 병합]** 도 같은 방식(사용자 결정) — 저쪽만 고친 줄이 이어진 구간마다 주석 한 줄, Undo 한 번. 사이에 낀 충돌 · 내가 고친 줄은 구간을 끊고 그대로 둔다.
|
||||||
|
|
||||||
|
시험(사용자 지시로 이것만): `g22-accept-all`(새 — 고친 3줄 · 오른쪽에만 2줄 · 오른쪽에서 빠진 2줄): 주석 **3줄**(예전 방식 7) · `삭제 2줄` 1 ·
|
||||||
|
주석을 빼면 BASE 와 같음 · Undo 한 번에 처음으로. `g23-three-way`(새, `--merge` 로 네 파일 — 저쪽만 3줄 · 2줄 구간, 나만 1줄, 충돌 1줄):
|
||||||
|
[전체 반영] 꺼짐 · [자동 병합] 뒤 주석 **2줄**(예전 방식 5) · 저쪽 5줄 들어옴 · 내 줄 · 충돌 줄 그대로 · Undo 한 번에 처음으로. 실패 0. 기존 회귀는 돌리지 않았다.
|
||||||
## 스크롤을 내리면 프로그램이 뻗는다 (2026-10-01, 사용자 보고 · 완료)
|
## 스크롤을 내리면 프로그램이 뻗는다 (2026-10-01, 사용자 보고 · 완료)
|
||||||
|
|
||||||
어제 커밋(`f105bab` 칸 어긋남 고침) 뒤부터 생겼다. Windows 이벤트에 `UbisamBase.Launcher.exe` **응답 없음(AppHang)** 두 번(13:44 · 13:45) — 죽은 것이 아니라
|
어제 커밋(`f105bab` 칸 어긋남 고침) 뒤부터 생겼다. Windows 이벤트에 `UbisamBase.Launcher.exe` **응답 없음(AppHang)** 두 번(13:44 · 13:45) — 죽은 것이 아니라
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
| 날짜 | 항목 | 커밋 |
|
| 날짜 | 항목 | 커밋 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
|
| 2026-10-01 | **전체 반영 · 자동 병합의 주석을 구간마다 한 줄로(사용자 요청 · 결정)** — 줄마다 머지 주석이 붙던 것. ① 두 파일 비교 [전체 반영]: 반영할 수 있는 줄이 이어진 구간마다 [구간 반영] 과 같게(`ApplyGroup`), 지우는 반영은 `삭제 N줄`, 모든 구간을 한 묶음으로 Undo 한 번 ② 3-Way [전체 반영] 끔 — 차이 나는 모든 줄을 공통 조상으로 바꾸던 동작(꺼져도 툴팁으로 까닭) ③ 3-Way [자동 병합]: 저쪽만 고친 줄 구간마다 주석 한 줄 · Undo 한 번(충돌 · 내 줄은 구간을 끊고 그대로). 화면 `g22-accept-all` 주석 7 → 3, `g23-three-way`(`--merge`) 5 → 2, 실패 0. 기존 회귀는 돌리지 않음. 빌드 경고 0 · 오류 0 | 아래 |
|
||||||
| 2026-10-01 | **스크롤을 내리면 프로그램이 뻗던 것(사용자 보고)** — 어제 칸 맞추기(`f105bab`) 뒤 응답 없음. ① 사람이 BASE 를 굴려도 LOCAL 기준으로 되돌려 초당 32번 밀고 당김 → 손이 닿은 칸(휠 · 누름 · 키)을 기준으로, LOCAL 쪽일 때만 BASE 를 맞춤 ② 따라 굴러가는 도중에 재서 보정값이 휠 한 칸씩 6,619px 까지 쌓임 → 메아리 막기 중이면 큰 맞추기는 앱이 한가할 때 한 번, 못 굴리면 실제로 움직인 만큼만 ③ 칸 목록(그 칸에 있는 줄만)의 항목 번호를 정렬 행 번호로 써 엉뚱한 줄끼리 견줌 → 줄 객체로 오감 ④ 빠르게 굴리면 사람의 스크롤이 메아리로 버려져 따라가는 칸이 멈춤 → 멈춘 뒤 한 번 따라잡기, BASE 를 굴릴 때 보정값을 보이는 줄에서 다시 잼. 화면 `g20-scroll-end` · `g21-blocks-fast`(새) 응답 · 따라옴, `g7` 실패 0, `g17` 통과. 사용자 파일로는 확인 안 함 · 기존 회귀는 돌리지 않음. 빌드 경고 0 · 오류 0 | 아래 |
|
| 2026-10-01 | **스크롤을 내리면 프로그램이 뻗던 것(사용자 보고)** — 어제 칸 맞추기(`f105bab`) 뒤 응답 없음. ① 사람이 BASE 를 굴려도 LOCAL 기준으로 되돌려 초당 32번 밀고 당김 → 손이 닿은 칸(휠 · 누름 · 키)을 기준으로, LOCAL 쪽일 때만 BASE 를 맞춤 ② 따라 굴러가는 도중에 재서 보정값이 휠 한 칸씩 6,619px 까지 쌓임 → 메아리 막기 중이면 큰 맞추기는 앱이 한가할 때 한 번, 못 굴리면 실제로 움직인 만큼만 ③ 칸 목록(그 칸에 있는 줄만)의 항목 번호를 정렬 행 번호로 써 엉뚱한 줄끼리 견줌 → 줄 객체로 오감 ④ 빠르게 굴리면 사람의 스크롤이 메아리로 버려져 따라가는 칸이 멈춤 → 멈춘 뒤 한 번 따라잡기, BASE 를 굴릴 때 보정값을 보이는 줄에서 다시 잼. 화면 `g20-scroll-end` · `g21-blocks-fast`(새) 응답 · 따라옴, `g7` 실패 0, `g17` 통과. 사용자 파일로는 확인 안 함 · 기존 회귀는 돌리지 않음. 빌드 경고 0 · 오류 0 | 아래 |
|
||||||
| 2026-09-30 | **끌 때 저장하지 않은 편집을 묻는다(사용자 요청 · 결정)** — 파일 비교의 모든 탭(지금 화면 · Git 모드 · 뒤 탭 · 닫은 탭, 메모 제외)에 편집이 있으면 [저장하고 종료] · [저장하지 않고 종료] · [취소]. 저장은 기존 길(`SaveWorkingCopy` · `WritePlainFile`), 하나라도 실패하면 끄지 않음. 버리면 걸려 있던 보관 쓰기를 기다린 뒤 보관본을 비워 다음에 안 살아남. 플랫폼 `ICloseGuard` 사용(수정 없음) — 곧바로 답하면 셸의 `Close()` 가 Closing 안에서 불려 창이 안 꺼져 `await Task.Yield()` 로 비켜섬. 화면 `g19-exit-confirm` 다섯 경우 실패 0(Git 모드는 화면 시험 안 함). **기존 회귀는 사용자 지시로 돌리지 않음.** 빌드 경고 0 · 오류 0 | 아래 |
|
| 2026-09-30 | **끌 때 저장하지 않은 편집을 묻는다(사용자 요청 · 결정)** — 파일 비교의 모든 탭(지금 화면 · Git 모드 · 뒤 탭 · 닫은 탭, 메모 제외)에 편집이 있으면 [저장하고 종료] · [저장하지 않고 종료] · [취소]. 저장은 기존 길(`SaveWorkingCopy` · `WritePlainFile`), 하나라도 실패하면 끄지 않음. 버리면 걸려 있던 보관 쓰기를 기다린 뒤 보관본을 비워 다음에 안 살아남. 플랫폼 `ICloseGuard` 사용(수정 없음) — 곧바로 답하면 셸의 `Close()` 가 Closing 안에서 불려 창이 안 꺼져 `await Task.Yield()` 로 비켜섬. 화면 `g19-exit-confirm` 다섯 경우 실패 0(Git 모드는 화면 시험 안 함). **기존 회귀는 사용자 지시로 돌리지 않음.** 빌드 경고 0 · 오류 0 | 아래 |
|
||||||
| 2026-09-30 | **엔터 꾹 · 확대 · 쭉 내리기에서 칸 어긋남(사용자 보고)** — ① 엔터를 꾹 누르면 캐럿 줄과 LOCAL 칸 줄이 벌어졌다 → 캐럿은 글에서 센 줄 자리로, 메아리 막기 중에도 LOCAL 칸은 편집기를 따라감. ② Ctrl+휠 확대 뒤 칸 위가 비고 내리면 BASE 가 다른 줄: 가상화 목록 높이 어림 차이(편집기 28,896 · 목록 27,940)를 네 칸 공통 이동값으로 메우다 467px 까지 커졌다 → 두 줄 넘으면 칸을 실제로 굴리고 칸별 보정으로 기억, BASE · REMOTE 는 같은 줄끼리 맞춤(한쪽에만 있는 묶음 안은 제외 — 짝을 억지로 불러 초당 600번 되풀이하던 것을 기록으로 잡음). ③ 편집기 `GetFirstVisibleLineIndex`(886 → 1033) · 확대 직후 `GetRectFromCharacterIndex`(1,892px 틀림)가 틀려 → 줄 높이 고정이면 계산. 화면 `g17-hold-enter` 통과(남은 ✗ 는 대본 한계 · 꾹 누름 흉내에서 Windows 가 반복 키를 합치는 것 — 고치기 전과 같음). **기존 회귀는 사용자 지시로 돌리지 않음.** 빌드 경고 0 · 오류 0 | 아래 |
|
| 2026-09-30 | **엔터 꾹 · 확대 · 쭉 내리기에서 칸 어긋남(사용자 보고)** — ① 엔터를 꾹 누르면 캐럿 줄과 LOCAL 칸 줄이 벌어졌다 → 캐럿은 글에서 센 줄 자리로, 메아리 막기 중에도 LOCAL 칸은 편집기를 따라감. ② Ctrl+휠 확대 뒤 칸 위가 비고 내리면 BASE 가 다른 줄: 가상화 목록 높이 어림 차이(편집기 28,896 · 목록 27,940)를 네 칸 공통 이동값으로 메우다 467px 까지 커졌다 → 두 줄 넘으면 칸을 실제로 굴리고 칸별 보정으로 기억, BASE · REMOTE 는 같은 줄끼리 맞춤(한쪽에만 있는 묶음 안은 제외 — 짝을 억지로 불러 초당 600번 되풀이하던 것을 기록으로 잡음). ③ 편집기 `GetFirstVisibleLineIndex`(886 → 1033) · 확대 직후 `GetRectFromCharacterIndex`(1,892px 틀림)가 틀려 → 줄 높이 고정이면 계산. 화면 `g17-hold-enter` 통과(남은 ✗ 는 대본 한계 · 꾹 누름 흉내에서 Windows 가 반복 키를 합치는 것 — 고치기 전과 같음). **기존 회귀는 사용자 지시로 돌리지 않음.** 빌드 경고 0 · 오류 0 | 아래 |
|
||||||
|
|||||||
@ -446,6 +446,7 @@
|
|||||||
|
|
||||||
| 상태 | 항목 |
|
| 상태 | 항목 |
|
||||||
|---|---|
|
|---|---|
|
||||||
|
| **완료** | **전체 반영 · 자동 병합의 주석이 너무 많다**(사용자 요청 · 결정) — 두 파일 비교 [전체 반영] 을 구간 반영처럼(구간마다 주석 한 줄 · Undo 한 번), 3-Way [전체 반영] 은 끔(공통 조상으로 되돌리는 동작이었다), 3-Way [자동 병합] 도 구간마다 주석 한 줄 · Undo 한 번. 화면 `g22` 주석 7 → 3, `g23` 5 → 2, 실패 0 |
|
||||||
| **완료** | **스크롤을 내리면 프로그램이 뻗는다**(사용자 보고, 어제 `f105bab` 뒤) — 응답 없음(AppHang). 원인 넷: BASE 를 굴려도 LOCAL 쪽으로 되돌려 밀고 당김 · 따라 굴러가는 도중에 재서 보정값이 6,619px 까지 쌓임 · 칸 목록 항목 번호를 정렬 행 번호로 씀(한쪽에만 있는 줄만큼 엉뚱한 줄끼리 견줌) · 빠르게 굴리면 사람의 스크롤이 버려짐. 손이 닿은 칸을 기준으로, 큰 맞추기는 한가할 때 한 번, 줄 객체로 오가기, 버려지면 멈춘 뒤 따라잡기. 화면 `g20` · `g21`(새) 응답, `g7` 실패 0, `g17` 통과 |
|
| **완료** | **스크롤을 내리면 프로그램이 뻗는다**(사용자 보고, 어제 `f105bab` 뒤) — 응답 없음(AppHang). 원인 넷: BASE 를 굴려도 LOCAL 쪽으로 되돌려 밀고 당김 · 따라 굴러가는 도중에 재서 보정값이 6,619px 까지 쌓임 · 칸 목록 항목 번호를 정렬 행 번호로 씀(한쪽에만 있는 줄만큼 엉뚱한 줄끼리 견줌) · 빠르게 굴리면 사람의 스크롤이 버려짐. 손이 닿은 칸을 기준으로, 큰 맞추기는 한가할 때 한 번, 줄 객체로 오가기, 버려지면 멈춘 뒤 따라잡기. 화면 `g20` · `g21`(새) 응답, `g7` 실패 0, `g17` 통과 |
|
||||||
| **완료** | **끌 때 저장하지 않은 편집을 묻는다**(사용자 요청 · 결정) — 파일 비교의 모든 탭(Git 모드 · 뒤 탭 · 닫은 탭 포함, 메모 제외)에 편집이 있으면 [저장하고 종료] · [저장하지 않고 종료] · [취소]. 버리면 보관본도 비워 다음에 안 살아남. 플랫폼 `ICloseGuard` 를 그대로 씀(플랫폼 수정 없음). 화면 `g19-exit-confirm` 실패 0. Git 모드는 화면 시험 안 함 · 기존 회귀는 사용자 지시로 안 돌림 |
|
| **완료** | **끌 때 저장하지 않은 편집을 묻는다**(사용자 요청 · 결정) — 파일 비교의 모든 탭(Git 모드 · 뒤 탭 · 닫은 탭 포함, 메모 제외)에 편집이 있으면 [저장하고 종료] · [저장하지 않고 종료] · [취소]. 버리면 보관본도 비워 다음에 안 살아남. 플랫폼 `ICloseGuard` 를 그대로 씀(플랫폼 수정 없음). 화면 `g19-exit-confirm` 실패 0. Git 모드는 화면 시험 안 함 · 기존 회귀는 사용자 지시로 안 돌림 |
|
||||||
| **완료** | **엔터 꾹 · Ctrl+휠 확대 · 쭉 내리기에서 칸이 어긋난다**(사용자 보고) — 캐럿 줄 ≠ LOCAL 칸 줄, 확대하면 칸 위가 비고, 내리면 BASE 가 다른 줄을 봤다. 가상화 목록의 높이 어림 차이를 이동값으로 메우지 않고 칸을 실제로 굴려 칸별로 기억, BASE 는 같은 줄끼리 맞춤, 편집기 보이는 줄은 줄 높이로 계산(편집기의 `GetFirstVisibleLineIndex` · 확대 직후 `GetRectFromCharacterIndex` 가 틀렸다). 화면 `g17-hold-enter` — 엔터 뒤 936=936, 확대 · 30칸 내린 뒤 LOCAL = BASE. 기존 회귀는 사용자 지시로 안 돌림 |
|
| **완료** | **엔터 꾹 · Ctrl+휠 확대 · 쭉 내리기에서 칸이 어긋난다**(사용자 보고) — 캐럿 줄 ≠ LOCAL 칸 줄, 확대하면 칸 위가 비고, 내리면 BASE 가 다른 줄을 봤다. 가상화 목록의 높이 어림 차이를 이동값으로 메우지 않고 칸을 실제로 굴려 칸별로 기억, BASE 는 같은 줄끼리 맞춤, 편집기 보이는 줄은 줄 높이로 계산(편집기의 `GetFirstVisibleLineIndex` · 확대 직후 `GetRectFromCharacterIndex` 가 틀렸다). 화면 `g17-hold-enter` — 엔터 뒤 936=936, 확대 · 30칸 내린 뒤 LOCAL = BASE. 기존 회귀는 사용자 지시로 안 돌림 |
|
||||||
|
|||||||
@ -1023,16 +1023,49 @@ namespace MergeHub.ViewModels
|
|||||||
AfterEdit();
|
AfterEdit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CanAcceptAll() => Lines.Any(l => l.CanTakeBase);
|
/// <summary>
|
||||||
|
/// 두 파일 비교에서만 켠다(2026-10-01 사용자 결정). 3-Way 에서 이 단추는 차이 나는 모든 줄을 <b>공통 조상(BASE)</b> 으로
|
||||||
|
/// 바꿨다 - 나와 저쪽의 변경을 함께 지우는 일이라 병합에서 쓸 데가 없고, 잘못 누르면 양쪽 작업이 다 사라진다.
|
||||||
|
/// "저쪽 전부" 로 바꾸면 충돌 줄까지 말없이 덮는다. 3-Way 는 [자동 병합](저쪽만 고친 줄)과 충돌별 반영을 쓴다.
|
||||||
|
/// </summary>
|
||||||
|
private bool CanAcceptAll() => !IsThreeWay && Lines.Any(l => l.CanTakeBase);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 반영할 수 있는 줄을 모두 반영한다.
|
||||||
|
///
|
||||||
|
/// 두 파일 비교에서는 <b>구간마다 [구간 반영] 과 똑같이</b> 한다(2026-10-01 사용자 요청 "주석이 너무 많이 남는다").
|
||||||
|
/// 예전에는 줄마다 반영해 바뀐 줄마다 머지 주석이 한 줄씩 붙었다. 이제 이어진 차이 구간마다 주석 한 줄
|
||||||
|
/// (N~M행 구간 … 반영 (k줄))만 남는다. 한 번 누른 것이라 되돌리기도 전체가 한 번에 돌아간다.
|
||||||
|
/// 3-Way 에서는 끈다(<see cref="CanAcceptAll"/>).
|
||||||
|
/// </summary>
|
||||||
[RelayCommand(CanExecute = nameof(CanAcceptAll))]
|
[RelayCommand(CanExecute = nameof(CanAcceptAll))]
|
||||||
private void AcceptAll()
|
private void AcceptAll()
|
||||||
{
|
{
|
||||||
if (!AuthorReady()) return;
|
if (IsThreeWay || !AuthorReady()) return;
|
||||||
foreach (var line in Lines.Where(l => l.CanTakeBase).ToList())
|
|
||||||
Apply(line, requery: false);
|
// 구간을 먼저 다 나눠 둔다 - 반영하며 주석 줄이 끼면 행 번호가 밀리므로 줄 객체로 들고 간다.
|
||||||
|
var blocks = new List<List<MergeLine>>();
|
||||||
|
List<MergeLine>? current = null;
|
||||||
|
foreach (var line in Lines)
|
||||||
|
{
|
||||||
|
if (!line.CanTakeBase) { current = null; continue; }
|
||||||
|
if (current is null) blocks.Add(current = new List<MergeLine>());
|
||||||
|
current.Add(line);
|
||||||
|
}
|
||||||
|
if (blocks.Count == 0) return;
|
||||||
|
|
||||||
|
var group = ++_lastGroup;
|
||||||
|
var changed = 0;
|
||||||
|
var applied = 0;
|
||||||
|
foreach (var block in blocks)
|
||||||
|
{
|
||||||
|
var count = ApplyGroup(block, anchor: null, what: "구간", group: group, finish: false);
|
||||||
|
changed += count;
|
||||||
|
if (count > 0) applied++;
|
||||||
|
}
|
||||||
|
|
||||||
AfterEdit();
|
AfterEdit();
|
||||||
|
if (changed > 0) MessageUtil.ShowSuccessToast($"{applied}구간 {changed}줄 반영");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>저장할 것이 있거나, 저장은 했지만 연 시점과 달라졌다(11차 F-8 - 저장해도 연 시점으로 돌아갈 수 있다).</summary>
|
/// <summary>저장할 것이 있거나, 저장은 했지만 연 시점과 달라졌다(11차 F-8 - 저장해도 연 시점으로 돌아갈 수 있다).</summary>
|
||||||
@ -4349,9 +4382,11 @@ namespace MergeHub.ViewModels
|
|||||||
/// 되돌리기는 묶음째. 머지 주석 줄은 건드리지 않는다 - 이력이다.
|
/// 되돌리기는 묶음째. 머지 주석 줄은 건드리지 않는다 - 이력이다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>글이 바뀐 줄 수.</returns>
|
/// <returns>글이 바뀐 줄 수.</returns>
|
||||||
private int ApplyGroup(IReadOnlyList<MergeLine> rows, MergeLine? anchor, string what)
|
/// <param name="group">함께 되돌릴 묶음 번호. 0 이면 새로 하나 뗀다 - [전체 반영] 은 여러 구간을 한 묶음으로 넘긴다.</param>
|
||||||
|
/// <param name="finish">끝에 화면을 다시 맞출지. 여러 구간을 이어서 반영할 때는 부르는 쪽이 마지막에 한 번 한다.</param>
|
||||||
|
private int ApplyGroup(IReadOnlyList<MergeLine> rows, MergeLine? anchor, string what, int group = 0, bool finish = true)
|
||||||
{
|
{
|
||||||
var group = ++_lastGroup;
|
if (group == 0) group = ++_lastGroup;
|
||||||
var changed = 0;
|
var changed = 0;
|
||||||
var deleted = 0; // 주석에 "삭제 N줄" 로 한 번만 적는다(사용자 2026-09-30)
|
var deleted = 0; // 주석에 "삭제 N줄" 로 한 번만 적는다(사용자 2026-09-30)
|
||||||
int? first = null, last = null;
|
int? first = null, last = null;
|
||||||
@ -4373,7 +4408,7 @@ namespace MergeHub.ViewModels
|
|||||||
|
|
||||||
if (changed == 0)
|
if (changed == 0)
|
||||||
{
|
{
|
||||||
AfterEdit();
|
if (finish) AfterEdit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4401,7 +4436,7 @@ namespace MergeHub.ViewModels
|
|||||||
|
|
||||||
ClearRedo();
|
ClearRedo();
|
||||||
_workspace.AppendLog(description);
|
_workspace.AppendLog(description);
|
||||||
AfterEdit();
|
if (finish) AfterEdit();
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4570,15 +4605,28 @@ namespace MergeHub.ViewModels
|
|||||||
private void AutoMerge()
|
private void AutoMerge()
|
||||||
{
|
{
|
||||||
// 반영하면서 주석 줄이 끼어들어 Lines 가 바뀐다. 먼저 목록을 떠 놓고 돈다.
|
// 반영하면서 주석 줄이 끼어들어 Lines 가 바뀐다. 먼저 목록을 떠 놓고 돈다.
|
||||||
var targets = Lines.Where(l => l.ThreeWay == ThreeWayState.RemoteChanged && l.CanTakeRemote).ToList();
|
// 이어진 줄끼리 묶어 <b>구간마다 주석 한 줄</b>만 남긴다(2026-10-01 사용자 결정 - 예전에는 줄마다 붙어 주석이 너무 많았다).
|
||||||
if (targets.Count == 0) return;
|
// 묶음에는 저쪽만 고친 줄만 넣는다 - 사이에 낀 충돌 · 내가 고친 줄은 구간을 끊고 그대로 둔다.
|
||||||
|
var blocks = new List<List<MergeLine>>();
|
||||||
|
List<MergeLine>? current = null;
|
||||||
|
foreach (var line in Lines)
|
||||||
|
{
|
||||||
|
if (line.ThreeWay != ThreeWayState.RemoteChanged || !line.CanTakeRemote) { current = null; continue; }
|
||||||
|
if (current is null) blocks.Add(current = new List<MergeLine>());
|
||||||
|
current.Add(line);
|
||||||
|
}
|
||||||
|
if (blocks.Count == 0) return;
|
||||||
|
|
||||||
foreach (var line in targets) ApplyRemote(line, requery: false);
|
// 한 번 누른 것이라 되돌리기도 한 번에 - 모든 구간을 한 묶음 번호로.
|
||||||
|
var group = ++_lastGroup;
|
||||||
|
var changed = 0;
|
||||||
|
foreach (var block in blocks)
|
||||||
|
changed += ApplyGroup(block, anchor: null, what: "자동 병합", group: group, finish: false);
|
||||||
|
|
||||||
AfterEdit();
|
AfterEdit();
|
||||||
MessageUtil.ShowSuccessToast(UnresolvedConflictCount == 0
|
MessageUtil.ShowSuccessToast(UnresolvedConflictCount == 0
|
||||||
? $"{targets.Count}줄 자동 병합 · 남은 충돌 없음"
|
? $"{changed}줄 자동 병합 · 남은 충돌 없음"
|
||||||
: $"{targets.Count}줄 자동 병합 · 남은 충돌 {UnresolvedConflictCount}개");
|
: $"{changed}줄 자동 병합 · 남은 충돌 {UnresolvedConflictCount}개");
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CanGoConflict() => IsThreeWay && Lines.Any(l => l.NeedsDecision);
|
private bool CanGoConflict() => IsThreeWay && Lines.Any(l => l.NeedsDecision);
|
||||||
|
|||||||
@ -1756,7 +1756,8 @@
|
|||||||
<TextBlock Text="파일 전체" Style="{StaticResource Muted}" FontSize="11" Margin="0,12,0,4"/>
|
<TextBlock Text="파일 전체" Style="{StaticResource Muted}" FontSize="11" Margin="0,12,0,4"/>
|
||||||
<!-- 두 칸으로 나누면 "전체 되돌리기" 글자가 잘린다. 한 줄에 하나씩 둔다. -->
|
<!-- 두 칸으로 나누면 "전체 되돌리기" 글자가 잘린다. 한 줄에 하나씩 둔다. -->
|
||||||
<Button Content="전체 반영" Command="{Binding AcceptAllCommand}" MinHeight="28"
|
<Button Content="전체 반영" Command="{Binding AcceptAllCommand}" MinHeight="28"
|
||||||
FontSize="11" ToolTip="차이나는 모든 줄을 BASE 내용으로"/>
|
FontSize="11" ToolTipService.ShowOnDisabled="True"
|
||||||
|
ToolTip="차이나는 모든 줄을 BASE 내용으로 - 구간마다 주석 한 줄, Undo 한 번에 전체가 되돌아갑니다. 3-Way 에서는 쓰지 않습니다(저쪽만 고친 줄은 [자동 병합], 충돌은 한 줄씩)"/>
|
||||||
<Button Content="전체 되돌리기" Command="{Binding RevertAllCommand}" MinHeight="28"
|
<Button Content="전체 되돌리기" Command="{Binding RevertAllCommand}" MinHeight="28"
|
||||||
FontSize="11" Margin="0,4,0,0" ToolTip="파일을 연 시점으로 되돌립니다"/>
|
FontSize="11" Margin="0,4,0,0" ToolTip="파일을 연 시점으로 되돌립니다"/>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user