충돌 탭 파일 단위 Accept 는 소스에 주석이 안 남고, 병합 커밋 본문은 비어 있었고,
Git 탭 로그는 끄면 사라져 누가 어느 파일을 어떻게 풀었는지 남는 곳이 없었다(사용자 요청).
- MergeResolutionLog: 기록 파일(첫 줄 MERGE_HEAD) 읽기 · 쓰기, 본문 만들기, 메시지에 붙이기
- GitService: 병합 중일 때만 .git/MERGEHUB_RESOLUTIONS 에 적고, CommitMerge 가 본문을 붙인다.
병합 커밋 · 작업 취소 · 새로고침 때 쓸모없는 기록을 치운다
- 충돌 탭 Accept Mine/Theirs/Both · [Save] · Save & Commit · 파일 남기기/지우기 · 머지 주석 자동이 적는다
- Git 탭 메시지 칸에 본문을 미리 채우고, 풀 때마다 새로 채운다(사람이 고치면 두고 커밋 때 붙임)
- 하네스 MergeSaveTest 183건(21건 추가), 22벌 1,094건 통과
확인: 병합 "충돌 해결 26개 · 김승준"(줄 단위 7 · Theirs 15 · 남기기 1 · 지우기 1 · 주석 자동 2),
pull 26개, Accept Mine 기록 뒤 [작업 취소] 로 기록 파일 없음. 줄끝 · BOM 0/33, 회귀 없음.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
네 칸 MERGED 칸 번호가 정렬할 때 정해진 채 굳어 있었다. 고른 줄 · 머지 주석으로 결과가 늘어도
다시 매기지 않아 끝 번호가 3363 인데 상태바는 총 3369줄이었다.
- 사용자 결정(2026-09-16): 결과 파일 번호로 맞춘다 - 상태바 · [이동] 칸 · 코드 검사와 같은 기준
- MergedNumbering.Assign - 결과에 들어가는 줄만 1부터 센다
- 줄을 만들 때와 요약을 그릴 때마다 다시 매긴다(고르기 · 편집 · 되돌리기 · 주석 끼우기 뒤)
- LOCAL (Mine) 칸은 내 파일 번호 그대로
- 하네스 MergeSaveTest 162건(번호 7건), 18벌 928건 통과
확인: MERGED 끝 번호 3363 → 3369, 상태바 총 3369줄 · [이동] 3369 · 저장된 파일 3369줄과 같다.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
이미 들어 있는 커밋을 cherry-pick 하면 [커밋] 이 켜졌고, 누르면 로그에
"[cherry-pick 커밋] 실패: No changes; nothing to commit." 만 남았다. 진행 줄도 그대로였다.
- GitService.HasStagedChanges() 를 두고 적용 로그 · 커밋 앞 막음에 쓴다
- GitWorkspace.PendingHasChanges 를 상태로 들고, 진행 줄이 그 값을 본다
- CanFinishOperation 은 cherry-pick · revert 에서 커밋할 것이 있어야 켜진다
- 병합 커밋은 트리가 같아도 정상이라 걸지 않는다
- 하네스 MergeSaveTest 155건(진행 줄 7건), 18벌 921건 통과
확인: HEAD 커밋을 다시 cherry-pick → [커밋] 꺼짐 · "가져올 변경이 없습니다 - [작업 취소] 로 끝냅니다" ·
[작업 취소] 로 빠져나옴. 충돌 24건짜리 보통 cherry-pick 은 그대로 커밋까지(원래 메시지).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rebase · cherry-pick 에서 마지막 충돌을 [Save] 하면 파일 비교 탭이 "남은 차이 6줄" 로 떨어져
충돌 탭("충돌 정리 끝 - [계속] 으로 rebase 를 이어 갑니다")과 다른 말을 했다.
- OperationLabels.ResolvedSummary / BaseHeader 로 옮기고 작업별 글을 붙였다
- MergeSavePlan 의 병합 전용 함수 둘을 걷어냈다
- 화면은 IsMergeInProgress 대신 IsOperationInProgress · OperationState.Kind 를 본다
- 하네스 MergeSaveTest 148건(작업별 16건), 18벌 914건 통과
확인: rebase "충돌 정리 끝 · [계속] 으로 rebase 를 이어 갑니다 · 올릴 자리 대비 올린 변경 6줄" · 제목 "올릴 자리",
cherry-pick "… [커밋] 으로 cherry-pick 을 끝냅니다", 병합은 예전 글 그대로.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
파일 비교 탭을 처음 여는 것이 [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>
화면이 모든 충돌을 "병합" 으로 불렀다 - 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>
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>
병합 중 충돌이 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>
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>
훑기 - 가리기 - 세기로 나눴다. 훑으면서 그 자리에서 파일을 열어
견주던 것을, 트리를 먼저 세우고 가리는 일만 여러 갈래로 돌린다.
결과 차례는 트리가 정하므로 몇 갈래로 돌리든 같은 순서로 나온다.
세는 일만은 한 갈래로 한다. 파일이 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개 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 로 같은 것을 다르게 부르던 것도 맞췄다.
경로 칸(TextBox)이 Drop 을 먼저 먹어 놓아도 아무 일이 없었다 - Preview 로 옮겼다.
파일 비교의 경로 글자는 Background 가 없어 놓을 자리 자체가 없었다.
칸에 놓아도 다시 견주지 않던 것을 DropFile / DropFolder 로 고쳤다.
파일을 하나씩 놓아 짝을 만들 수 있게 했다.
검색 결과 칸에 머리글을 넣고 줄 간격을 목록과 맞췄다.
결과를 남에게 보내거나 결재에 붙일 때 화면을 캡처하는 것 말고는 방법이 없었다.
캡처는 검색도 안 되고 줄 번호를 짚어 말하기도 어렵다.
Services/CompareReport.cs 신설. 파일 비교와 폴더 비교 양쪽에서 쓴다. 글을
만드는 일만 여기서 하고, 어디에 저장할지 묻는 것은 화면 쪽 일이다. 그래야
화면 없이 검사한다.
파일 쪽은 요약과 다른 줄 목록을 적는다. 줄 번호는 양쪽을 다 적는다. 한쪽에만
있는 줄이 있어 번호가 어긋나므로 하나만 적으면 파일에서 그 줄을 찾을 수 없다.
폴더 쪽은 상태와 상대 경로를 줄마다 적는다. 폴더 자체는 적지 않는다. 그 안의
파일이 이미 다 적혀 있다.
곁들여 요약에 주석만 다른 수를 덧붙였다. "다름 3(주석만 1)". D-1 로 새로 생긴
갈래가 요약에는 안 보였다.
확인: 두 화면에서 각각 뽑아 메모장으로 열었다. ReportTest 23건 신설.
전체 451건 통과.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>