파일 비교 탭을 처음 여는 것이 [3분할로 열기] 면 고른 파일 대신 첫 충돌 파일이 보였고,
그 화면을 [Save] 하면 고른 파일에 그 내용이 써졌다(Unit47 이 Unit15 내용으로 스테이징).
- 읽기: 읽는 사이 파일 · 커밋이 바뀌면 버리고, 화면이 지금 고른 파일과 다르면 한 번 더 읽는다
- 쓰기: 저장 · Save & Commit · 파일 지우기/남기기가 화면에 실린 파일과 다르면 아무것도 쓰지 않는다
- 하네스 MergeSaveTest 15건 추가(140건), 18벌 906건 통과
확인: 병합 · pull · rebase · cherry-pick 네 길 모두 고른 파일이 열리고 저장이 그 파일에만 감.
병합은 파일 비교 탭을 미리 열지 않고 끝까지 - 커밋 3ba6314, 줄끝 · BOM 0/33, class 이름 검사 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
7차 전부 끝. D-1 에서 새로 걸린 넷과 7차에서 남긴 것을 8차로 넘긴다(코드 변경 없음).
- A-1 고른 충돌 파일 대신 다른 파일이 보이고 저장하면 고른 파일에 써짐 (가장 먼저)
- B-1 rebase · cherry-pick 마지막 저장 뒤 "남은 차이" · B-2 빈 cherry-pick [커밋] · B-3 MERGED 번호(먼저 정함)
- C-1 revert 끝까지 · C-2 원래 작성자 · C-3 창 크기 조절에서 안 본 것
- D-1 웹 문서 갱신 · E-1 다섯 길을 파일 비교 탭을 미리 열지 않고 다시
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
코드 변경 없음. 새 시험 저장소에서 MergeHub 만으로 네 길 모두 커밋(rebase 끝)까지 갔다.
줄끝 · BOM 바뀐 파일 0, A-2 · B-1 다시 안 남, MERGED 줄 번호 안 잘림.
새로 걸린 것(고치지 않음 → 8차):
- N1 파일 비교 탭을 처음 여는 것이 [3분할로 열기] 면 첫 충돌 파일이 보이고,
그 화면을 [Save] 하면 고른 파일에 그 내용이 써진다(Unit47 ← Unit15)
- N2 rebase · cherry-pick 마지막 저장 뒤 "남은 차이"(A-1 은 병합만)
- N3 MERGED 칸 번호가 결과 파일 번호가 아님
- N4 바뀌는 것 없는 cherry-pick 에서 [커밋] 이 켜져 실패
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
셸 창이 최대화 전용이었다. 끌어 크기 조절(최소 1280x720) · 두 번 누르기 최대화/복원 · 화면 이동이 크기를 지킴 ·
크기와 모니터 기억. 최대화는 작업 표시줄까지 덮고(사용자 결정), 크기를 바꿀 때 깜빡이지 않게(검은 칠 99.7% -> 3%).
확인 받고 D:\UbisamPlatform\bin 배포, MergeHub 다시 빌드. MergeHub 네 탭은 최소 크기에서 잘리지 않음. MergeHub 코드 변경 없음.
7차 지시서 E-4 판정 기준을 사용자 결정대로 고침.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
화면이 모든 충돌을 "병합" 으로 불렀다 - rebase REMOTE 가 "THEIRS", cherry-pick 에 "병합 진행 중",
다 풀면 cherry-pick 을 끝낼 단추가 없고, 로그에 RebaseContinue() · Commit(), 다른 브랜치 커밋은 고를 수 없었다.
GitOperationState 로 칸 제목(올릴 자리 · 다시 올리는 내 커밋 · 가져오는 커밋) · 머리 글 · 진행 표시 ·
끝내기 단추(병합 커밋 · 계속 · 커밋)를 정한다. cherry-pick · revert 는 원래 메시지 · 작성자로 커밋.
머지 주석 자동 풀기 · 알림도 같은 뒷일. 이력 탭 [모든 브랜치].
rebase · cherry-pick 모두 줄끝 바뀐 파일 0, MergeSaveTest 125건 통과.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
사용자 요청. 지금 셸은 최대화 전용(WindowStyle=None · ResizeMode=NoResize · 끌면 다시 최대화).
걸리는 곳(크기 조절 테두리 · 배율 다른 모니터 · 크기 기억 · MergeHub 고정 폭과 네 칸 정렬 · 모든 소비 프로그램)과
판정 기준(최소 1280x720 · 최대화 복원 · 화면 이동 10번 왕복 · 세 크기에서 잘림 없음)을 적었다. 코드 변경 없음.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
pull 은 Git.Pull 만 불러 머지 주석만 다른 충돌까지 사람에게 물었고(26 · 0/26), 알림도 커밋 메시지도 없었다.
MergeAsync 의 뒷일을 AfterMerge 로 빼 pull 도 부른다(24 · 2/26 · 같은 알림).
pull 병합 커밋 메시지는 git 과 같은 "Merge remote-tracking branch 'origin/feature/mine' into feature/mine".
bare 원격으로 화면 확인, [Merge] 회귀 없음. MergeSaveTest 93건 통과.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
병합 때 적는 처음 충돌 목록이 병합 커밋 · 작업 취소 · 터미널에서 끝낸 병합 뒤에도 남았다.
MERGE_HEAD 가 없거나 다른 병합의 것이면 병합 커밋 · 작업 취소 직후와 상태를 다시 읽을 때마다 지운다.
병합 중에는 그대로라 "푼 것 M개 (M/전체)" 는 이어진다. 세 경우 화면에서 확인, MergeSaveTest 88건 통과.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Take Theirs 로그가 3-Way 콤보 값을 써서 "10행 (3-Way 안 씀) 반영" 이었고, Take Mine 은 로그가 없었다.
이제 "10행 Theirs(feature/theirs) 반영" · "10행 Mine(feature/mine) 으로 정함".
충돌 네 칸이면 3-Way 콤보 대신 "병합 충돌 · REMOTE = 상대". 브랜치 3-Way 문구는 그대로.
MergeSaveTest 82건 통과.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
화면 아무 데나 폴더 하나를 놓으면 늘 첫 칸에 들어가 두 번째 폴더가 첫 폴더를 덮어썼다.
DropSlotOrder 로 놓는 차례를 두고, 양쪽이 차면 바로 비교한다. 경로 칸 위에 놓은 것도 차례에 친다.
탐색기에서 끌어다 놓아 다섯 경우 확인. PathTest 62건 통과.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
켤 때 이름 창을 Alt+F4 로 닫으면 이름 없이 본 창을 쓸 수 있었고, 창도 끌려 움직였다.
플랫폼 UserNameDialog 에서 저장 전 닫기를 막고 끌기를 뺐다. 확인 받고 D:\UbisamPlatform\bin 배포.
MergeHub 코드 변경 없음(다시 빌드해 새 Core 를 받음).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
병합 중 충돌이 0 이면 두 칸 요약을 "충돌 정리 끝 · 병합 커밋을 할 수 있습니다 · 내 쪽 대비 받은 변경 N줄" 로,
BASE 제목에 "병합 전 내 쪽". 예전에는 "남은 차이 6줄" 이라 덜 푼 것처럼 보였다.
E-1 기록의 하네스 문장을 바로잡음(MergeSaveTest 기대값은 [Save] 로 고침).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
LOCAL 칸을 이 파일에만 쓰고 스테이징하는 단추라 Save & Commit 과 짝이 되게 이름만 바꿈.
알림 · 막힘 안내 · 웹 문서도 Save. 하는 일은 그대로(충돌 24 → 23, 커밋 없음 확인).
7차 지시서: 6차 D-1 에서 걸린 세 가지(마지막 저장 뒤 남은 차이 · 로그 3-Way 안 씀 · 기록 파일 남음)와
pull · rebase · cherry-pick 충돌.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
충돌 26(머지 주석 자동 2) · 파일 단위 Accept 15 · 3분할 해결로 저장 7 · 지우기/남기기 2.
5차 C-1 의 23가지 중 사라짐 18, 머지 주석은 B-5 대로 남음.
새로 걸린 3가지(로그 "3-Way 안 씀" · 마지막 저장 뒤 두 칸 · 기록 파일 남음)는 7차로. 코드 변경 없음.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Io/Unit12.cs 를 고치고 콤보에서 Io/Unit20.cs 를 고르면 확인 창이
"Unit20.cs 에 저장하지 않은 편집" 이라고 했다. [취소] 뒤에는 콤보가
Io/Unit20.cs 를, 화면은 Io/Unit12.cs 를 보여 서로 달랐다.
확인하다 더 큰 것을 찾았다. [저장하고 계속] 이 새로 고른 파일에 썼다.
Io/Unit20.cs 를 고치고 Io/Unit12.cs 로 옮기며 누르자 Io/Unit12.cs 안에
class Unit20 이 들어가고 해결된 것으로 스테이징됐다. 병합 결과가
망가지는 버그다.
원인은 하나다. 콤보에서 고르면 SelectedFile 이 먼저 새 파일로 바뀐
뒤에 변경 처리가 불리는데, 확인 창의 이름과 저장할 곳을 둘 다
SelectedFile 에서 가져왔다.
- ConfirmDiscard: 이름을 화면에 실린 파일(_lastLoadedFile)에서.
Git 모드는 저장소 안 경로로
- SaveWorkingCopy: 쓸 곳도 실린 파일로. 충돌이면 그 파일의 충돌을 푼다
- 취소 뒤 되돌리기를 콤보의 선택 처리가 끝난 다음 차례에
- 저장소가 이미 열려 있으면 생성자에서 목록을 세운다(B-1 빈틈 -
저장소를 먼저 열고 파일 비교 탭을 나중에 열면 목록이 0개였다)
화면 확인 18건 통과(목록 23개, 이름, 취소, 저장하지 않고 계속,
저장하고 계속 뒤 Unit20 은 풀리고 Unit12 는 그대로). 경고 0, 오류 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
병합하고 파일 비교 탭으로 오면 목록이 병합 전 커밋 파일(304개) 그대로
였고, [새로고침] 을 한 번 더 눌러야 충돌 23개가 나왔다. 충돌 탭 목록을
두 번 눌러도 아무 일이 없었고, 안내 글은 없는 "홈 탭" 을 가리켰다.
원인: 새로고침은 게이트를 쥔 채 화면 목록을 갈아 끼우고, 끝나자마자
Git 탭이 게이트를 다시 잡는다. 파일 비교 화면이 그 틈에 목록을 세우려다
"다른 작업 진행 중" 으로 건너뛰었다.
- OnWorkspaceRefreshed: 게이트가 풀릴 때까지 기다렸다 목록을 세운다
- GitWorkspace.RequestOpenConflict: 충돌 파일을 파일 비교 탭에서 열어
달라는 요청을 남겨 두고 탭을 옮긴다(폴더 비교의 넘겨주기와 같은 방식)
- OpenConflictAsync: 목록에 설 때까지 기다렸다 고른다. 이 요청 때문에
화면이 새로 만들어졌으면 기본 저장소를 새로 열지 않는다
- 충돌 목록: 두 번 누르기(MouseDoubleClick), Enter, [3분할로 열기]
- 안내 글과 병합 알림의 "홈 탭" 을 실제 탭 이름으로
화면 확인 17건 통과(병합 뒤 목록 23개, 두 번 누르기와 단추와 Enter 로
네 칸, 파일 비교 탭을 안 연 새 앱에서도 열림, 병합 취소 뒤 Git 탭
새로고침만으로 목록 304개). 경고 0, 오류 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
양쪽이 같은 이름으로 새로 만든 파일에 Accept Both 를 누르면 묻지 않고
두 blob 을 바이트째 이어 붙였다. 결과 파일 한가운데에 BOM 이 하나 더
들어갔고 같은 class 가 두 번 나와 빌드가 안 됐다.
- BothJoin: 두 벌을 각자 제 인코딩으로 글로 풀어 이어 붙인 뒤 내 쪽
형식(인코딩, BOM, 줄끝)으로 다시 쓴다. 규칙은 A-1 의 TextFile.Encode
- ResolveConflict(Both): 바이트 이어 붙이기 대신 BothJoin
- Git 탭 Accept Both: 먼저 묻는다(무엇이 일어나는지, 줄 단위로 둘 다
넣으려면 3분할에서). 단추 도움말
Both 는 없애지 않았다. 이어 붙이는 게 맞는 파일도 있다.
화면 확인 14건 통과(묻기, 아니오면 그대로, 예면 BOM 1개와 CRLF 한
가지, 보통 충돌도 같음). EncTest 10건 추가. 21벌 785건 통과
(새로 빌드한 실행 파일). 경고 0, 오류 0. A 묶음 끝.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
상대가 지운 파일(UD)이나 내가 지운 파일(DU)을 열면 줄 단위 3분할로
끌고 가서 지운 쪽 칸이 통째로 비었다. 범례는 내 쪽에만 있는 줄 89개를
"Theirs only 89" 라고 거꾸로 말했고, 정할 것인 "남길까 지울까" 는
화면 어디에도 없었다. 파일 단위 해결은 이미 바르게 동작했다.
- DeletionConflict: 어느 쪽이 지웠는지, 남기기와 지우기가 각각 어느
쪽을 고르는 것인지(UD 는 남기기=내 것, DU 는 남기기=상대 것)
- LoadFileAsync: 지운 충돌이면 남은 파일을 BASE 와 두 칸으로 보인다.
칸 제목이 누가 지웠는지 말하고, BASE 제목은 (merge base)
- 범례 위 띠: 누가 지웠고 누가 고쳤는지, [파일 남기기] [파일 지우기]
- 남기기는 고친 것이 있으면 고친 대로 남기고, 지우기는 고친 것이
있으면 한 번 묻는다. 푼 뒤 남은 충돌 첫 파일로 간다
- 해결로 저장과 같은 뒷정리를 ReloadAfterResolveAsync 로 모았다
시험 저장소 생성기에 DU 경우를 넣었다(충돌 23개). 뿌리 폴더를 잡고
있는 셸 때문에 다시 만들기가 멈춰서 안만 비우게 고쳤다.
화면 확인 23건 + BASE 제목 고친 뒤 5건 통과. MergeSaveTest 16건 추가.
21벌 775건 통과(새로 빌드한 실행 파일). 경고 0, 오류 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
병합 중에 충돌 파일을 고르면 BASE 와 내 것 두 칸뿐이었다. 읽기는
충돌 갈래(세 벌)로 했지만 켠 것은 지역 변수 threeWay 뿐이고, 화면
틀을 정하는 IsThreeWay 는 콤보에서 브랜치를 골랐을 때만 참이었다.
상대가 무엇을 바꿨는지 안 보인 채 풀게 됐다.
- IsThreeWay: 콤보로 고른 3-Way 이거나 충돌 파일이라 켠 3분할이면 참.
충돌 쪽은 따로 둔 깃발이라 콤보 값은 건드리지 않는다
- LoadFileAsync: 행을 싣기 전에 틀부터 바꾸고, 읽기 갈래는 콤보로
고른 3-Way 만 본다(앞 파일의 3분할이 다음 파일로 새지 않게)
- GetMergeTheirsName: MERGE_HEAD 를 가리키는 브랜치 이름, 없으면
병합 메시지의 이름, 그것도 없으면 짧은 해시
- MergeNames: 병합 메시지에서 이름 꺼내기(저장소 없이 검사)
- REMOTE 제목에 상대 브랜치 이름
화면 확인 18건 통과(충돌 파일 네 칸, 제목 REMOTE · feature/theirs,
콤보 없이 해결로 저장, 병합이 끝나면 두 칸, 콤보 3-Way 는 예전과 같음).
MergeSaveTest 14건 추가. 21벌 759건 통과(새로 빌드한 실행 파일).
경고 0, 오류 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
3분할로 푼 파일을 저장하면 줄끝이 전부 LF 가 됐다. 3,363줄 CRLF
파일에서 충돌 6개를 풀었는데 git 에는 파일 전체가 바뀐 것으로 나왔다.
원인은 둘이었다.
- ResolveConflictWithContent 가 인코딩만 맞추고 줄끝을 안 봤다.
편집기 글은 줄마다 \n 이라 늘 LF 로 써졌다.
- 원본으로 워킹트리 파일을 읽었다. 충돌 중에는 git 이 LF 로 충돌
표시를 넣어 두어 원본이 아니다.
- TextFile.Encode: 저장 바이트 규칙을 한 곳으로. "원본 유지" 는
넘겨받은 원본 바이트를 따르고, 줄끝은 가장 많은 것, BOM 은 한 번
- TextFile.Write: 디스크 파일을 원본으로 Encode 를 쓴다
- ResolveConflictWithContent: 원본을 ours blob 으로(없으면 theirs,
base). 고른 저장 형식을 받는다
- HomeViewModel 세 자리가 저장 형식을 넘긴다
Io/Unit12.cs +399 줄 -> +2 -1, CRLF 유지
Motion/Unit0.cs +3367 -3363 -> +8 -4
한글설명.cs CP949 와 CRLF 유지
LineEnding.cs 상대가 LF 로 바꿔도 내 쪽 CRLF
줄바꿈 LF 를 고르면 LF
검사 모음이 빌드 실패를 삼키고 옛 실행 파일을 돌리던 것을 찾았다.
LangTest(5차 B-1 의 CarryOver 변경), ReportTest(파일 누락),
TokenTest(Program.cs 없음, 새로 씀)를 고쳤다. 이제 모두 다시 빌드한
새 실행 파일만 센다. 21벌 745건 통과. 경고 0, 오류 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Save & Commit 이 쓰기, 스테이징, 커밋을 한 덩어리로 돌려서 남은
충돌은 마지막 커밋 단계에서야 막혔다. 화면은 실패라는데 파일은
이미 써지고 스테이징됐고(충돌 22 -> 21), 편집 상태도 안 치워서
다른 파일을 고를 때마다 확인 창이 다시 떴다.
- MergeSavePlan: 지금 커밋해도 되는지 판단만 따로 뺐다
- Save & Commit: 병합 중 다른 충돌이 남으면 아무것도 쓰기 전에 멈춘다
- [해결로 저장]: 병합 중에만 보인다. 이 파일만 쓰고 스테이징한다
- Ctrl+S: 병합 중이면 해결로 저장
- 확인 창의 "저장하고 계속": 병합 중 충돌 파일이면 충돌까지 푼다
화면에서 해 보다 둘이 더 나왔다.
- 게이트에 막혀 건너뛴 목록 불러오기가 빈 결과로 목록을 비웠다.
건너뛰면 그대로 두고, 해결로 저장 뒤에는 게이트가 풀릴 때까지
기다렸다 다시 세운다(WhenIdleAsync). 남은 충돌 첫 파일이 열린다.
- 충돌을 전부 Take Mine 으로 정하면 글이 안 바뀌어 저장할 수 없었다.
3분할에서 충돌을 다 정했으면 고친 글이 없어도 저장할 수 있다.
화면 확인 25건 통과. MergeSaveTest 18건 추가, 21벌 716건 통과.
경고 0, 오류 0. 줄끝(A-1)은 아직 그대로다.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
사용자가 정했다. 누가 언제 반영했는지는 소스에 남아야 하므로 머지
주석은 지금처럼 넣는다. 대신 비교하고 병합할 때는 그 줄을 무시한다.
git 은 이 규칙을 모른다. 병합은 주석 줄도 글자로 보고 충돌을 낸다.
그래서 무시는 MergeHub 가 한다.
- 2-Way, 3-Way, 폴더 비교에서 머지 주석을 차이로 세지 않는다
- 줄 끝에 붙은 주석은 조각만 떼고 견준다
- git 이 낸 충돌이 주석 차이뿐이면 묻지 않고 풀고, 두 주석을 다 남긴다
- 무시는 보는 방식일 뿐 파일에서 지우지 않는다. 설정에서 끌 수 있다
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
5차 C-1 에서 만든 저장소로 병합을 커밋까지 해 보고 걸린 23가지를
지시서로 묶었다.
A 파일이나 이력을 망가뜨리는 것 (C-1 에서 심각으로 적은 다섯)
A-1 3분할 저장이 CRLF 를 LF 로 바꾼다
A-2 Save & Commit 이 실패라는데 이미 써지고 스테이징됐다
A-3 충돌 파일에 상대 칸이 안 나온다
A-4 상대가 지운 파일을 3분할이 다룰 줄 모른다
A-5 양쪽 새 파일에 Accept Both 가 빌드를 깬다
B 헷갈리거나 막히는 것 8 · C 사소한 것 1
D 고친 뒤 같은 저장소로 병합을 처음부터 다시 해 본다
확인은 C-1 과 같은 생성기로 한다. 고치기 전에 문제가 다시 나는
것부터 보인다. B-5(병합에 머지 주석을 넣을지)는 사용자가 정한다.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
만든 저장소(파일 303개, 충돌 22개)로 MergeHub 만으로 병합해서
커밋까지 갔다. 지시서대로 고치지 않고 적기만 했다. 제품 코드는
바꾸지 않았다.
맞게 된 것: 병합 결과가 git 과 똑같다(UU 20 AA 1 UD 1 M 7).
3분할에서 충돌 6개를 6 -> 0 으로 줄였고, 파일 단위 Accept 는 고른
쪽과 바이트까지 같다. 부모 둘인 병합 커밋이 생겼다.
걸린 것 23가지. 심각한 다섯:
- 3분할로 푼 파일을 저장하면 CRLF 가 LF 로 바뀐다(커밋에 CR 0개)
- Save & Commit 이 실패라는데 파일은 이미 써지고 스테이징됐다
- 충돌 파일을 고르면 상대(Theirs) 칸이 안 나온다
- 상대가 지운 파일을 3분할이 다룰 줄 모른다
- 양쪽 새 파일에 Accept Both 를 누르면 BOM 이 가운데 하나 더 들어간다
기대값은 사본에서 git 으로 먼저 받아 대조했다. 실제 소스는
열지 않았다.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
훑기 - 가리기 - 세기로 나눴다. 훑으면서 그 자리에서 파일을 열어
견주던 것을, 트리를 먼저 세우고 가리는 일만 여러 갈래로 돌린다.
결과 차례는 트리가 정하므로 몇 갈래로 돌리든 같은 순서로 나온다.
세는 일만은 한 갈래로 한다. 파일이 64개 아래면 나누지 않는다 -
그 아래는 갈래를 세우는 값이 더 든다.
폴더를 훑는 방식도 바꿨다. Directory.GetFiles 는 이름만 주므로
파일마다 File.Exists 와 FileInfo 를 양쪽에 다시 물었다. 4,500개면
만 팔천 번이다. DirectoryInfo.GetFiles 는 크기와 수정 시각이
딸려 오므로 한 번으로 끝난다. 974ms 가 89ms 가 됐다.
재는 데 쓴 묶음은 우리가 만들었다(실제 소스를 열지 않는다).
2026-09-10 에 재 둔 모양을 흉내 냈고 씨앗을 고정해서 몇 번을
돌려도 똑같다.
전체 비교 3,077ms -> 901ms (3.4배)
빠른 비교 1,832ms -> 392ms (4.7배)
앱에서 기다리는 시간 2,078ms -> 1,086ms (1.9배)
결과는 글자 하나까지 같다. 앱 쪽이 덜 줄어든 것은 비교가 끝난 뒤
화면 트리를 세우는 데 따로 드는 시간 때문이고, 거기는 손대지 않았다.
빠른 비교를 기본으로 켜지도 않았다 - 틀릴 수 있는 방법이다.
FolderTest 41 -> 51 (갈래 나누는 길, 열 번 돌려 같은 결과, 취소).
전체 698건 통과(하네스 20벌). 경고 0 · 오류 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
여기는 머지툴을 만드는 자리다. 남의 저장소를 읽을 까닭이 더 남아
있지 않고, 읽는 동안 사고가 날 여지만 있다. 이미 받아 둔 숫자
(XAML 400개, CP949 67개, 4,503개에 12.2초)는 그대로 쓴다.
B-2 와 C-1 을 그에 맞게 다시 썼다. 둘 다 큰 재료가 필요한데,
이제 우리가 만들어 쓴다. 만든 묶음은 몇 번을 돌려도 같은 값이
나와서 재기에는 오히려 낫다. C-1 에는 그 한계도 같이 적었다 -
만든 소스에는 진짜 코드의 지저분함이 없다.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
실제 소스에 XAML 이 400개 42,477줄인데 여태 주석과 따옴표만 알아봐서
사실상 평문이었다. 마크업 전용 토크나이저를 따로 뒀다.
기존 토크나이저에 못 얹은 까닭은 규칙이 다르기 때문이다. 그쪽은 낱말을
읽어 예약어 표와 맞춰 보는데, 마크업은 같은 Content 가 꺾쇠 안에서는
속성 이름이고 밖에서는 그냥 글자다. 낱말이 무엇이냐가 아니라 어디에
있느냐로 갈린다.
줄 넘김 상태를 bool 하나에서 깃발 묶음(CarryOver)으로 넓혔다. XAML 은
여는 태그가 여러 줄에 걸치는 것이 보통이라 - 시험에 쓴 실제 파일은 첫
태그 하나가 14줄이다 - "지금 꺾쇠 안이다"를 안 넘기면 이어지는 줄의
속성이 그냥 글자로 보인다. 부르는 자리 다섯을 모두 바꿨다.
색은 새로 만들지 않고 이미 있는 갈래에 얹었다. 태그는 예약어 색,
속성 이름은 메서드 색, 값은 문자열 색, 앞가지는 타입 색이다. 태그
밖의 본문은 일부러 안 칠한다.
붙이는 중에 파일 비교 화면이 통째로 비어서 뜨는 일이 있었다. 의존
속성 타입을 bool 에서 CarryOver 로 바꾸면서 기본값 false 를 같이 안
고쳤다. 빌드도 통과하고 로그에도 안 남는다. 같은 주의를 코드 옆에
적어 뒀다.
실제 저장소 XAML 사본(638줄)으로 화면 확인. C# 색칠은 그대로.
MarkupTest 65건. 전체 688건 통과(하네스 20벌). 경고 0 · 오류 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
커밋·체크아웃 뒤에 저장 안 한 편집이 말없이 사라지던 것을 막았다.
막는 자리를 옮겼다. 목록을 다시 세우는 자리(RefreshCommits →
LoadCommitAsync)가 아니라 Git 작업이 시작되는 문(GitWorkspace.
RunAndRefreshAsync)에서 묻는다. 그 순간에는 아직 아무것도 바뀌지
않았으므로 취소가 뜻을 가진다.
작업을 가려서 묻는 쪽은 접었다. fetch·태그·스테이징처럼 파일을 안
건드리는 열두 가지는 안 물으려 했는데, 해 보니 그런 작업 뒤에도
편집이 사라졌다. 파일이 그대로여도 저장소를 다시 읽으면서 본문을
새로 그리기 때문이다. 다시 그리지 않게 막는 쪽도 해 봤지만 고른
파일까지 바뀌는 경우가 있어 조건을 세울 수 없었다. 잃지 않는 쪽으로
갔다 - 확인 창은 고치던 것이 있을 때만 뜨고, 틀려도 한 번 더 묻는
것으로 끝난다. 알아낸 열두 이름은 KnownSafeCandidates 에 남겼다.
덤으로 4차 A-1 이 새던 자리 셋을 막았다. 목록을 다시 세우면 화면이
값을 되밀어 넣는데, 그것을 사람이 고른 것으로 보고 확인 창을 띄우고
있었다. OnSelectedNodeChanged(null·같은 커밋), OnRemoteBranchChanged
(_syncingBranches), Files.Clear()(_suspendGuard 안으로).
화면 시험 10건 통과(데모 저장소). GitOpTest 36건. 전체 623건 통과
(하네스 19벌). 빌드 경고 0 · 오류 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
실제 저장소 2091개를 MergeHub 로 읽어 봤다. CP949 67개 포함해 깨짐 0, 저장 왕복 어긋남 0.
판별 코드가 TextFile 과 GitService 두 군데에 복사돼 있던 것을 한 곳으로 모았다.
상태바가 KS_C_5601-1987, 목록이 CP949 로 같은 것을 다르게 부르던 것도 맞췄다.