셸 창이 최대화 전용이었다. 끌어 크기 조절(최소 1280x720) · 두 번 누르기 최대화/복원 · 화면 이동이 크기를 지킴 · 크기와 모니터 기억. 최대화는 작업 표시줄까지 덮고(사용자 결정), 크기를 바꿀 때 깜빡이지 않게(검은 칠 99.7% -> 3%). 확인 받고 D:\UbisamPlatform\bin 배포, MergeHub 다시 빌드. MergeHub 네 탭은 최소 크기에서 잘리지 않음. MergeHub 코드 변경 없음. 7차 지시서 E-4 판정 기준을 사용자 결정대로 고침. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
16 KiB
작업 지시 — MergeHub 7차 (병합 화면이 사실대로 말하게 · 병합 말고 다른 충돌 길)
대상: D:\Sorce\MergeTool\MergeHub (플러그인) · D:\Sorce\MergeTool\UbisamPlatform (셸)
전제: 1~6차 지시서는 모두 끝났다(../진행상황.md).
이번 지시서가 나온 곳 — 6차 D-1 에서 시험 저장소를 새로 만들어 MergeHub 만으로 처음부터 병합 커밋까지 다시 했다. 줄끝 · BOM 이 바뀐 파일은 0/33 이었고 5차의 23가지 중 18가지가 사라졌다. 대신 새로 걸린 것이 세 가지였고, 6차에서 일부러 뺀 병합이 아닌 충돌 길(pull · rebase · cherry-pick)이 남아 있다. 근거와 수치는 ../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 규칙).
- 상세는
doc/history/YYYY-MM-DD-7차.md— 원인 · 판단 · 확인한 결과 - ../진행상황.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 에 영향 적기 |
방향
- 먼저 최소 창 크기를 정한다(제안: 1280 × 720, 배율 100% 기준). 그보다 작게는 못 줄인다. 모듈 화면을 좁은 폭용으로 새로 짜지는 않는다 — 최소 크기에서 쓸 수 있으면 된다.
- 셸: 크기 조절 테두리 · 최대화 ↔ 복원(브랜딩 바 두 번 누르기, Win+↑/↓ · 화면 가장자리 끌기 스냅) · 보통 크기에서 끌어 옮기기 · 화면 이동이 크기를 지킴 · 마지막 크기와 상태 기억.
- 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 — 미룬 그대로 둔다.
보고 형식
항목마다 이렇게 적는다.
- 고치기 전에 문제가 다시 나는 것을 어떻게 보였는지 (만든 저장소의 어느 파일로)
- 무엇이 원인이었는지 한두 줄
- 어떤 파일을 어떻게 고쳤는지
- 실제로 실행해 확인한 결과 (바이트 · 줄끝 · 충돌 수처럼 눈이 아닌 값으로)
- 커밋 해시