ksj09406 f256f0f038 7차 E-4 기록: 창 크기를 마음대로 조절할 수 있게(플랫폼 셸)
셸 창이 최대화 전용이었다. 끌어 크기 조절(최소 1280x720) · 두 번 누르기 최대화/복원 · 화면 이동이 크기를 지킴 ·
크기와 모니터 기억. 최대화는 작업 표시줄까지 덮고(사용자 결정), 크기를 바꿀 때 깜빡이지 않게(검은 칠 99.7% -> 3%).
확인 받고 D:\UbisamPlatform\bin 배포, MergeHub 다시 빌드. MergeHub 네 탭은 최소 크기에서 잘리지 않음. MergeHub 코드 변경 없음.
7차 지시서 E-4 판정 기준을 사용자 결정대로 고침.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 17:01:54 +09:00

188 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 작업 지시 — MergeHub 7차 (병합 화면이 사실대로 말하게 · 병합 말고 다른 충돌 길)
대상: `D:\Sorce\MergeTool\MergeHub` (플러그인) · `D:\Sorce\MergeTool\UbisamPlatform` (셸)
전제: 1~6차 지시서는 모두 끝났다([../진행상황.md](../진행상황.md)).
**이번 지시서가 나온 곳** — 6차 D-1 에서 시험 저장소를 새로 만들어 MergeHub 만으로 처음부터 병합 커밋까지 다시 했다.
줄끝 · BOM 이 바뀐 파일은 0/33 이었고 5차의 23가지 중 18가지가 사라졌다. 대신 **새로 걸린 것이 세 가지**였고,
6차에서 일부러 뺀 **병합이 아닌 충돌 길**(pull · rebase · cherry-pick)이 남아 있다.
근거와 수치는 [../history/2026-09-14-6차.md](../history/2026-09-14-6차.md) 의 D-1 에 있다.
| 6차 D-1 에서 잰 것 | 값 |
|---|---|
| 충돌 | git 26 · 머지 주석 자동 2 · 파일 단위 Accept 15(1.3초) · 3분할 저장 7 · 지우기/남기기 2 |
| 줄끝 · BOM · 인코딩이 내 쪽과 달라진 파일 | **0 / 33** · 충돌 표식 0줄 |
| 병합 커밋 | 부모 둘 · `Merge branch 'feature/theirs' into feature/mine` |
| 5차 C-1 의 23가지 | 사라짐 18 · 정해서 남음 1(머지 주석) · 이번 흐름에서 안 남 3 · 따로 안 봄 1(#12 줄 번호) |
---
## 공통 규칙
- **A → B → C → D 순서로 진행한다.** A 는 사람이 화면을 보고 잘못 판단하게 만드는 것이라 먼저다.
- **항목 하나를 끝낼 때마다** 빌드하고 실제로 실행해 화면을 확인한 뒤 보고한다.
- **항목 하나가 끝나면 기록을 세 군데에 남기고 로컬 커밋한다**(4차 D-2 규칙).
1. **상세**는 `doc/history/YYYY-MM-DD-7차.md` — 원인 · 판단 · 확인한 결과
2. [../진행상황.md](../진행상황.md) 은 **대기 → 완료로 상태만**
3. [../history/changelog.md](../history/changelog.md) 에 한 줄 — 날짜 · 무엇을 왜 · 커밋
- **푸쉬하지 않는다.**
- **실제 소스를 열지 않는다**(2026-09-11 결정). 시험 재료는 우리가 만들어 쓴다.
- **확인은 `C1Repo` 로 만든 저장소로 한다.** 씨앗이 고정돼 몇 번을 만들어도 같다.
고치기 전에 문제가 **다시 나는 것부터 보이고**, 고친 뒤 안 나는 것을 보인다.
- 기존 검사 하네스 22벌(948건)은 계속 통과해야 한다. 로직을 건드리면 **테스트를 먼저 늘린다.**
- 빌드 경고 0 · 오류 0 을 유지한다. 앱이 실행 중이면 `UbisamBase.Shell` 을 먼저 종료한다.
- 사용자 설정 파일(`D:\UbisamConfig\Settings\MergeHubSettings.json`)은 시험 전에 백업하고, 끝나면 **바이트 그대로** 되돌린다.
- 플랫폼을 고치면 다른 소비 프로그램에 미치는 영향을 함께 적고
`UbisamPlatform/doc/history/changelog.md` 에 남긴다.
---
## A. 병합 화면이 사실과 다르게 말하는 것
### A-1. 마지막 충돌을 저장하면 "남은 차이" 가 뜬다 (D-1 N2)
- 마지막 충돌 파일을 [Save] 하면, **아직 병합 커밋 전인데** 파일 비교 탭이 두 칸(HEAD 내 쪽 ↔ 워킹트리)으로 떨어져
"남은 차이 3줄 · BASE와 다름 3" 을 보인다(`Weld/Unit1.cs`). 방금 고른 줄이 "차이" 로 세어져 **덜 푼 것처럼** 읽힌다.
충돌 탭은 같은 때 "충돌 정리 끝 · 푼 것 26개" 라고 한다. 두 화면이 다른 말을 한다.
- 짚이는 곳: `HomeViewModel.ReloadAfterResolveAsync` 가 남은 충돌이 없으면 `LoadCommitAsync` 로 보통 화면(HEAD 대비)을 연다.
병합 중이라는 사정을 모른다.
- 방향: 병합 중이고 충돌이 0 이면 파일 비교 탭도 "**충돌 정리 끝 · 병합 커밋을 할 수 있습니다**" 를 말한다.
푼 파일을 보여 줄 거라면 무엇과 견준 차이인지(내 쪽 대비 받은 변경) 제목과 요약에 적는다.
- **판정 기준**: D-1 과 같은 순서로 마지막 충돌을 저장했을 때 파일 비교 탭의 요약 · 상태바가 "남은 차이" 가 아니라
병합 커밋을 할 수 있다는 말을 한다. 충돌 탭과 말이 같다. 병합 커밋 뒤에는 지금처럼 보통 화면(B-8)으로 돌아간다.
### A-2. 3분할에서 줄을 골라도 로그는 "3-Way 안 씀" 이라고 한다 (D-1 N1)
- 네 칸에서 Take Theirs 를 누르면 로그가 **"101행 (3-Way 안 씀) 반영"** 이라고 적는다. D-1 로그 11줄이 모두 그랬다.
결과 파일은 맞다 — 글자만 틀렸다.
- 짚이는 곳: `HomeViewModel.cs` 의 `"{line.RemoteNumber}행 {RemoteBranch} 반영"` 이 3-Way 콤보 값을 쓴다.
병합 중 충돌 파일은 콤보를 건드리지 않고 네 칸을 띄우므로(6차 A-3) 콤보는 `(3-Way 안 씀)` 그대로다.
- 머리의 3-Way 콤보도 같은 때 `(3-Way 안 씀)` 을 보이는지 **고치기 전에 화면으로 확인**하고, 그렇다면 같이 고친다.
- **판정 기준**: 병합 중 네 칸에서 줄을 고르면 로그가 상대 쪽 이름(예: `feature/theirs`)이나 "Theirs" 로 적는다.
Take Mine 도 무엇을 골랐는지 적힌다. 네 칸이 떠 있는 동안 화면 어디에도 "3-Way 안 씀" 이 없다.
충돌이 아닌 파일의 2-Way · 브랜치 3-Way 로그는 지금 그대로다.
---
## B. 치우기
### B-1. 병합 커밋 뒤에도 `.git/MERGEHUB_CONFLICTS` 가 남는다 (D-1 N3)
- 병합에서 충돌이 나면 처음 충돌 목록을 `.git/MERGEHUB_CONFLICTS` 에 적는다(6차 C-1, "푼 것 M개 (M/전체)" 용).
**지우는 곳이 없다.** 병합 커밋 · 작업 취소 뒤에도 남는다.
- 첫 줄의 MERGE_HEAD 와 대조하므로 다음 병합에 해는 없다. 그래도 남의 `.git` 에 우리 파일을 흘리지 않는다.
- 짚이는 곳: `GitService.RememberMergeConflicts` 만 있고, 병합 커밋 · `--abort`(작업 취소) 길에 치우는 코드가 없다.
- **판정 기준**: MergeHub 로 병합 커밋을 하거나 작업 취소를 하면 파일이 없다.
MergeHub 밖(터미널)에서 병합을 끝낸 경우에는 다음에 저장소를 열 때 MERGE_HEAD 가 없으면 치운다.
---
## C. 병합 말고 다른 충돌 길 (6차에서 뺀 것)
6차는 "병합만 끝까지 믿을 수 있게" 를 목표로 pull · rebase · cherry-pick 을 뺐다. 같은 네 칸을 쓰지만 끝까지 해 본 적이 없다.
### C-1. pull 이 낸 충돌에는 머지 주석 자동 풀기가 안 걸린다
- `GitService.Pull` 은 안에서 `Merge()` 를 부르므로 처음 충돌 목록은 적힌다.
하지만 **머지 주석만 다른 충돌을 푸는 `ResolveNoteOnlyConflicts` 는 `GitViewModel.MergeAsync` 에서만 부른다.**
pull 로 같은 저장소를 받으면 사람에게 26개를 묻게 된다(6차 B-5 가 약속한 것과 다르다).
- 병합 커밋 메시지 기본값(`Merge branch …`)도 MergeAsync 에만 있다. pull 뒤의 메시지를 확인한다.
- **판정 기준**: 만든 저장소에서 원격을 흉내 낸 bare 저장소를 두고 pull 했을 때 알림 · 로그 · 충돌 수가 [Merge] 와 같다
("충돌 24건 (머지 주석만 다른 2건은 자동으로 풀림)"). 병합 커밋 메시지가 원격 브랜치 이름을 담는다.
### C-2. rebase · cherry-pick 충돌을 네 칸으로 끝까지
- rebase 계속 · cherry-pick 충돌도 파일 비교 탭 네 칸으로 열리는지, **제목(LOCAL · REMOTE 가 무엇인지)** 이 맞는지 본 적이 없다.
rebase 에서는 "내 쪽" 과 "상대 쪽" 이 병합과 **거꾸로**다(upstream 이 ours). 화면이 그 사정을 말해야 한다.
- [Save] 뒤 흐름: 병합은 [병합 커밋] 인데 rebase 는 [계속], cherry-pick 은 커밋이다. 충돌 탭 단추와 안내가 작업에 맞는지 본다.
- 생성기(`C1Repo`)에 rebase · cherry-pick 용 갈래를 더한다(같은 씨앗, 기존 병합 경우는 그대로).
- **판정 기준**: 만든 저장소에서 rebase 와 cherry-pick 을 각각 MergeHub 만으로 끝까지 간다.
네 칸 제목이 실제 쪽을 말한다. 끝난 커밋에 **줄끝 · BOM 이 바뀐 파일 0개**, 충돌 표식 0.
---
## D. 확인
### D-1. 세 길을 처음부터 다시 끝까지
- A~C 를 고친 뒤 저장소를 새로 만들어 **병합 · pull · rebase · cherry-pick** 을 각각 처음부터 끝까지 한다.
- 6차 D-1 에서 **따로 안 본 #12(MERGED 칸 줄 번호)** 를 이번에는 네 칸 화면으로 찍어 확인한다(`Motion/Unit0.cs` · `Weld/Unit1.cs` 끝 줄).
- 6차 D-1 과 **같은 표로** 적는다. 새로 걸린 것은 고치지 말고 적는다 — 그 목록이 8차가 된다.
- **판정 기준**: 네 길 모두 MergeHub 만으로 커밋(또는 rebase 끝)까지 간다. 줄끝 · BOM 이 바뀐 파일 0개.
A-1 · A-2 · B-1 이 다시 나지 않는다.
---
## E. 추가 요청
### E-1. [해결로 저장] 이름을 [Save] 로 (2026-09-14, 사용자)
- 병합 중에 보이는 그 단추는 LOCAL 칸 내용을 저장하는 단추다. 이름을 **Save** 로 바꾼다(단추 옆 Save & Commit 과 짝).
- 하는 일은 그대로다 — 이 파일만 쓰고 스테이징, 커밋은 안 함, Ctrl+S.
- 알림 · 막힘 안내 · 웹 문서의 이름도 같이 바꾼다. 지난 기록(history)은 그때 이름 그대로 둔다.
- **판정 기준**: 병합 중 단추가 "Save" 이고 "해결로 저장" 은 화면 어디에도 없다. 눌렀을 때 충돌이 하나 줄고 커밋은 안 생긴다.
### E-2. 폴더 비교 탭에 폴더를 하나씩 끌어다 놓으면 첫 칸 → 둘째 칸 차례로 (2026-09-14, 사용자 · 완료)
### E-3. 사용자 이름을 저장하기 전에는 화면을 쓸 수 없게 (2026-09-14, 사용자 · 완료, 플랫폼)
### E-4. 창 크기를 마음대로 조절할 수 있게 (2026-09-14, 사용자 · 대기, 플랫폼 + MergeHub)
사용자: "현재는 화면크기 최대화만 지원인데 이거 크기를 마음대로 조절할수있게 할수있겠어? 문제가 많이 발생할 수도 있을거같은데".
**지금 모양** — 셸 창(`UbisamBase.Core/Shell/ShellWindow`)이 `WindowStyle=None` · `WindowState=Maximized` · `ResizeMode=NoResize` 다.
테두리가 없어 가장자리를 잡을 곳이 없고, 브랜딩 바를 끌어 옮기면 손을 뗄 때 **커서 아래 모니터를 다시 꽉 채운다**
(`TitleBar_MouseLeftButtonDown` → `FillMonitorUnderCursor`). 어중간한 크기로 남으면 되돌릴 방법이 없어서 그렇게 만들었다(플랫폼 2026-09-07).
**할 수는 있다. 다만 걸리는 곳이 여럿이라 먼저 적는다.**
| 어디 | 걸리는 것 |
|---|---|
| 셸 · 테두리 | 테두리 없는 창은 가장자리를 끌 수 없다. `WindowChrome`(ResizeBorderThickness · CaptionHeight 0)로 크기 조절 테두리를 따로 둬야 한다. 최대화했을 때 화면 밖으로 몇 px 넘치거나 작업 표시줄을 덮는 WPF 의 알려진 문제가 있다 |
| 셸 · 끌어 옮기기 | 지금은 끌면 늘 다시 최대화한다. 보통 크기일 때는 그 크기 그대로 옮기고, 최대화 상태에서 끌 때만 줄였다가(지금처럼) 놓는 자리에 따라 정해야 한다. 브랜딩 바 두 번 누르기로 최대화 ↔ 복원 |
| 셸 · 화면 이동 · 배율 | "화면 이동" 은 다음 모니터를 꽉 채운다. 보통 크기라면 크기를 지키며 옮겨야 한다. **배율이 다른 모니터(150% ↔ 100%) 사이에서 보통 크기 창은 크기가 틀어지기 쉽다** — 최대화만 두게 된 까닭 중 하나(플랫폼 2026-09-07 "화면 이동" 결함) |
| 셸 · 기억 | 껐다 켜면 마지막 크기 · 위치 · 최대화 여부로. 그 모니터가 없어졌으면(노트북 도킹 해제) 주 모니터 안으로 끌어 들인다 |
| 셸 · 덮는 것 | 잠금 화면 · 스크린 세이버 · 알림 · 이름 창 · 확인 창이 창 크기를 따라 가운데에 오는지. 화면 배율(`ContentScale`) 과 겹칠 때 |
| MergeHub · 파일 비교 | 네 칸이 칸마다 최소 200px(`LocalColumn` · `BaseColumn`), ACTIONS 170~214px, 수정 이력 칸, 줄 번호 여백 66px. 머리의 파일 · 3-Way · 최근 콤보가 260 · 180 · 200px 이라 좁으면 **잘리거나 겹친다** |
| MergeHub · 네 칸 정렬 | 줄 장식 맞춤(`AlignDecorationToEditor`)이 실제 폭 · 위치를 재서 맞춘다. 창 크기가 바뀔 때마다 다시 맞는지 — 6차 B-4 에서 멀리 건너뛰면 네 칸이 밀리던 것과 같은 뿌리가 다시 날 수 있다 |
| MergeHub · 폴더 · Git 탭 | 고정 폭이 폴더 16곳 · Git 15곳. 좁을 때 버튼 줄이 접히는지 잘리는지 |
| 모든 소비 프로그램 | 셸을 고치면 `D:\UbisamPlatform\bin` 을 쓰는 프로그램이 다 같이 바뀐다. **배포는 사용자 확인 뒤**(플랫폼 규칙), 플랫폼 changelog 에 영향 적기 |
**방향**
1. 먼저 **최소 창 크기**를 정한다(제안: 1280 × 720, 배율 100% 기준). 그보다 작게는 못 줄인다. 모듈 화면을 좁은 폭용으로 새로 짜지는 않는다 — 최소 크기에서 쓸 수 있으면 된다.
2. 셸: 크기 조절 테두리 · 최대화 ↔ 복원(브랜딩 바 두 번 누르기, Win+↑/↓ · 화면 가장자리 끌기 스냅) · 보통 크기에서 끌어 옮기기 · 화면 이동이 크기를 지킴 · 마지막 크기와 상태 기억.
3. MergeHub: 최소 크기에서 네 탭을 차례로 열어 잘리는 곳을 고친다(머리 줄 접기 · 최소 폭 조정).
**판정 기준**
- 창 가장자리 · 모서리를 끌어 크기를 바꿀 수 있다. 1280 × 720 보다 작게는 안 줄어든다.
- 브랜딩 바 두 번 누르기 · Win+↑/↓ 로 최대화 ↔ 복원. 최대화했을 때 화면 밖으로 넘치지 않고 **작업 표시줄까지 덮어 화면을 채운다**
(2026-09-15 사용자 결정 "최대화하면 작업표시줄 안보이게 화면을 채워줘" — 처음에는 "덮지 않는다" 였다). 하단 탭 바를 작업 표시줄이 가리지 않는다.
- 크기를 바꾸는 동안 창이 깜빡이지 않는다(2026-09-15 사용자 요청).
- 보통 크기에서 브랜딩 바를 끌면 **크기가 그대로** 옮겨진다. 최대화 상태에서 끌면 지금처럼 줄어들어 따라온다.
- "화면 이동" 을 150% ↔ 100% 모니터 사이로 10번 왕복해도 보통 크기 창의 크기가 모니터 배율대로 맞고(틀어짐 없음), 최대화 창은 그 모니터를 채운다.
- 껐다 켜면 마지막 크기 · 위치 · 최대화 여부로 뜬다. 그 모니터가 없으면 주 모니터 안에 뜬다.
- 1280 × 720 · 1920 × 1080 · 최대화 세 크기에서 MergeHub 네 탭(폴더 비교 · 파일 비교 네 칸 · Git · 설정)의 단추 · 콤보 · 칸 제목이 잘리지 않는다. 네 칸 줄 번호와 장식이 창 크기를 바꾼 뒤에도 맞다(스크린샷으로).
- 잠금 화면 · 알림 · 이름 창 · 확인 창이 보통 크기 창 가운데에 뜬다.
- 기존 동작 회귀 없음: 최대화로 켜서 쓰는 사람에게는 지금과 같다.
---
## 이번 지시서에서 하지 않는 것
- **실제 소스로 병합해 보기** — 실제 소스는 열지 않는다(2026-09-11 결정).
- **머지 주석을 병합에서 끄기** — 6차 B-5 에서 "소스에 넣고 비교 · 병합에서는 무시" 로 정했다. D-1 에서도 그대로 동작했다.
- 빠른 비교(크기 · 수정일)가 내용만 바뀐 파일을 놓치는 것 — 폴더 비교의 알려진 한계로 둔다.
- 같은 줄 접기(4차 B-2) · 외부 편집기(4차 B-4) · 로그인·권한 · Gitea PR — 미룬 그대로 둔다.
---
## 보고 형식
항목마다 이렇게 적는다.
- 고치기 전에 문제가 **다시 나는 것**을 어떻게 보였는지 (만든 저장소의 어느 파일로)
- 무엇이 원인이었는지 한두 줄
- 어떤 파일을 어떻게 고쳤는지
- 실제로 실행해 확인한 결과 (바이트 · 줄끝 · 충돌 수처럼 **눈이 아닌 값**으로)
- 커밋 해시