기획안 1차 범위 "커밋 우클릭 -> 이름 변경". 사용자 결정대로 좁은 범위에서만 한다. HEAD 가 아닌 커밋의 메시지를 바꾸면 그 커밋부터 HEAD 까지가 새 해시로 다시 써진다. 고른 커밋의 메시지만 갈고 뒤 커밋은 트리 · 작성자 · 작성 시각 · 부모 관계를 그대로 두어(LibGit2Sharp Refs.RewriteHistory) 해시만 바뀐다. 바꾸기 전 자리는 refs/original/날짜-시각/ 에 남긴다. 막는 자리(메뉴는 켜 두고 눌렀을 때 까닭과 푸는 길을 알림으로): 작업 중 · 커밋 안 한 변경 · 지금 브랜치 조상 아님 · 원격에 올라감 · 다른 로컬 브랜치도 품음 · 구간에 태그 · 사이에 병합 커밋. 파일 비교 탭의 저장 안 한 편집은 우클릭해 줄을 고를 때 기존 창으로 묻는다. - CommitReword (새): 막을 까닭 · 확인 글 · 완료 알림 · 새 메시지 다듬기 - GitService.InspectReword / RewordCommit, RewordInfo - RewordWindow (새): 여러 줄 입력, [바꾸기] 는 기본 단추가 아님 - GitView: MergeHub 첫 우클릭 메뉴, 우클릭한 줄을 먼저 고른다 - 선택이 고친 커밋의 새 해시를 따라간다 - 화면에서 찾아 고침: 새 메시지가 끝 줄바꿈 없이 저장됐다 -> git -m 처럼 다듬는다(뒤 커밋까지 다듬지 않게 새 메시지 하나만) 하네스 MergeSaveTest +40 (272건, 22벌 1,247건) · 빌드 경고 0 · 오류 0. 화면 확인: 되는 자리 1(트리 · 작성자 · 작성 시각 같음, 되돌리기 확인) · 막는 자리 8 모두 막힘. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
29 KiB
11차 진행 기록 (2026-09-18 ~)
지시서: ../작업지시/11차.md
A-1. 변경분 추출을 먼저 뽑아 보고 적는다 (2026-09-18, 완료 · 고치지 않음)
지시서대로 고치지 않고 적기만 했다. 제품 코드는 바꾸지 않았다.
무엇으로 했나
C1Repo로 저장소를 새로 만든 뒤e11-a1-setup.sh로 추출 시험용 커밋을 더 쌓았다(전부 지어낸 파일).
| 커밋 | 무엇 |
|---|---|
4eb9ece base |
내 쪽 작업 (C1Repo 의 feature/mine) |
d3eb15b c1 |
새 파일 Extract/Temp.cs · Io/Unit12.cs 한 줄 더함 |
f884ed1 c2 |
Recipe/Unit11.cs 지움 · Motion/Unit16.cs → Motion/Renamed16.cs(내용 그대로) · 이진 Extract/logo.bin · 한글폴더/깊은/경로/아래/설명.cs |
cbcad8a c3 |
Io/Unit12.cs 를 c1 전으로 되돌림 · Extract/Temp.cs 지움 (범위 안에서 생겼다 사라짐) |
f702996 side · 58d5f7f merge |
base 에서 갈라진 옆가지에 Side/SideOnly.cs, 그것을 --no-ff 로 병합 |
- 화면은 사람 순서로: Git 탭 → 이력에서 줄을 마우스로 고르고 [여기부터] · [해제] · [변경분 추출], 폴더 창에는 경로를 쳐 넣고 Enter.
- 뽑은 폴더는
git diff -M --name-status의 기대 목록과 견주고, 파일마다git hash-object --no-filters로 바이트(blob 해시) 를 대조했다.
아홉 경우의 결과
| # | 경우 | 알림 | 뽑힌 것 | git 과 견주면 |
|---|---|---|---|---|
| 1 | 커밋 하나(시작점 없음, c1) | "2개 파일 추출" | Extract/Temp.cs · Io/Unit12.cs |
같음 · 바이트 같음 |
| 2 | 범위 [여기부터] base → c3 | "3개 파일 추출 (삭제되어 건너뜀 1개)" | Extract/logo.bin · Motion/Renamed16.cs · 한글폴더/…/설명.cs |
같음 — 범위 안에서 생겼다 사라진 Temp.cs, 바뀌었다 되돌아온 Unit12.cs 는 들어가지 않는다(맞다) |
| 3 | 지운 파일이 있는 범위 | 위와 같은 알림 | — | 건너뛴 개수만 알린다. Recipe/Unit11.cs 라는 것은 화면 · 로그 · 폴더 어디에도 없다 |
| 4 | 이름 바뀐 파일 | — | Motion/Renamed16.cs (새 이름) |
새 경로로 바이트 그대로. 옛 경로(Motion/Unit16.cs)를 알 길이 없다 — 장비에 덮어 넣으면 옛 파일이 남는다 |
| 5 | 병합 커밋 하나(merge) | "1개 파일 추출" | Side/SideOnly.cs |
첫 부모(c3)와만 견준다. 둘째 부모(옆가지)와 견주면 4개인데, 지금 무엇과 견주는지는 화면에 없다 |
| 6 | 거꾸로 범위 [여기부터] c3 → base | "2개 파일 추출 (삭제되어 건너뜀 2개)" | Motion/Unit16.cs · Recipe/Unit11.cs |
git 의 diff c3 base 와 같음(되돌리는 방향으로 동작). 경고나 방향 표시는 없다 |
| 7 | 이진 · 한글 · 깊은 경로 | 2 와 같음 | logo.bin 278B · 설명.cs 50B |
바이트 · 경로 그대로 |
| 8 | 이미 파일이 있는 폴더 | "3개 파일 추출 (삭제되어 건너뜀 1개)" | 폴더 안 6개 | 묻지 않고 덮어쓴다. 앞서 뽑아 둔 Extract/Temp.cs · Io/Unit12.cs(c1 것)와 사람이 넣어 둔 사용자메모.txt 가 그대로 남아 섞인다 |
| 9-a | 대상 파일이 읽기 전용 | "변경분 추출 실패: … 액세스가 거부되었습니다" | 2개(logo.bin + 읽기 전용 그대로) | 반쯤 뽑힌 채 멈춘다 — 앞 순서 logo.bin 은 써졌고 뒤 순서 한글…설명.cs 는 빠졌다. 몇 개까지 됐는지는 알림에 없다 |
| 9-b | 대상 파일이 다른 프로그램에 열려 있음 | "… 다른 프로세스에서 사용 중이므로 …" | 2개 | 9-a 와 같은 모양 |
- 알림과 같은 글이 Git 탭 로그에도 남는다 — 성공은
변경분 추출: N개 파일 → 경로 (삭제되어 건너뜀 M개), 실패는[변경분 추출] 실패: …. - 범위 표시는 제대로 바뀐다: 시작점이 없으면
부모 → 고른 커밋, [여기부터] 를 누르면4eb9ece → 고른 커밋. - 폴더 창은 늘 저장소가 있는 폴더에서 열린다.
- 저장소 워킹트리는 아홉 경우 내내 Clean 이었다(추출은 읽기만 한다).
이걸로 확정된 것 (A-2 ~ A-4 로 넘긴다)
| 번호 | 확정된 문제 | 어디로 |
|---|---|---|
| ① | 지운 파일 · 이름 바뀐 옛 경로가 결과에 남지 않는다(경우 3 · 4) | A-2 |
| ② | 무엇과 무엇 사이를 뽑았는지 폴더에 남지 않는다(경우 5 · 6 — 병합 커밋은 첫 부모, 거꾸로 범위도 말없이 됨) | A-2 |
| ③ | 비어 있지 않은 폴더에 묻지 않고 덮어쓰고 옛 파일이 섞인다(경우 8) | A-3 |
| ④ | 쓰다 막히면 반쯤 뽑힌 채 멈추고, 어디까지 됐는지 알 수 없다(경우 9-a · 9-b) | A-3 에 덧 — 먼저 쓸 수 있는지 보고 시작할지, 실패해도 나머지를 계속할지 정한다 |
맞게 도는 것(고칠 것 없음): 파일 고르기(1 · 2 · 5 · 6 모두 git 과 같은 목록) · 바이트 보존(이진 · 한글 · 깊은 경로 포함) · 범위 표시 · 로그.
남긴 것 (시험 도구 쪽, 제품 아님)
화면 자동 조작에서 세 번 막혔다. 모두 스크립트 문제였고 제품과 무관하다.
- 함수 이름
History가 PowerShell 기본 별칭(history=Get-History)과 겹쳐, 내 함수 대신 그것이 불렸다 →GoHistory로 바꿈. - 폴더 창(
#32770)은 데스크톱 바로 아래가 아니라 본 창 아래에 붙는다 → 본 창의 자손에서 찾게 고침. - 폴더 창의 경로 칸(
id 1152)과 [이 폴더 선택](id 1)은 UIA 에서 Pane 으로 보이고, 같은 id 를 가진 다른 칸이 먼저 잡혔다 → id + 클래스(Edit·Button)로 고르고, 경로를 한 글자씩 친 뒤 Enter 로 닫게 함. - 백그라운드로 돌리면 앱 창이 앞으로 나오지 못해 마우스가 다른 창을 누른다 → 앞에서 돌린다.
A-2. 뽑은 폴더 옆에 "무엇을 뽑았는지" 안내를 남긴다 (2026-09-18, 완료)
사용자 결정(2026-09-18): 안내는 뽑은 폴더 밖(옆) 에 두고, 장비에서 지울 파일은 목록으로만 적는다(지우는 배치 파일은 만들지 않는다).
왜
A-1 에서 값으로 확인한 것 — 지운 파일은 "삭제되어 건너뜀 1개" 라고 개수만 알리고 어느 파일인지 아무 데도 없었다. 이름이 바뀐 파일은 새 이름만 뽑혀, 그 폴더를 장비에 덮어 넣으면 옛 파일이 그대로 남는다. 무엇과 무엇 사이를 뽑았는지도 폴더만 보고는 알 수 없었다.
고친 것
| 자리 | 한 일 |
|---|---|
Services/ExportReport.cs (새 파일) |
안내 글을 만든다. 머리글(만든 때 · 만든 사람 · 저장소 · 뽑은 곳 · 범위 두 줄) · 뽑은 파일 목록(추가 · 수정 · 이름 바뀜은 옛 이름을 괄호로) · 장비에서 지워야 할 파일 목록(지워진 파일 · 이름 바뀐 옛 경로). PathFor 가 폴더 옆 이름을 정한다 — …\변경분 → …\변경분_변경분안내.txt, 드라이브 뿌리처럼 옆자리가 없으면 폴더 안에 |
Services/GitService.cs |
ExportChangedFiles 가 (뽑은 수, 건너뛴 수, **무엇을 어떻게 했는지 목록**) 을 돌려준다. git 의 상태 글자(Added · Renamed · Copied …)를 안내 글의 말로 옮기고, 이름이 바뀐 파일은 옛 경로를 함께 들고 온다 |
Services/IGitService.cs |
같은 서명으로 |
ViewModels/GitViewModel.cs |
뽑은 뒤 안내를 폴더 옆에 쓴다(TextFile.Write). 범위 줄은 이력에 있는 커밋이면 제목과 날짜까지, 시작점을 안 잡았으면 "(고른 커밋의 부모)" 를 붙인다. 안내 파일 경로를 로그에 남기고, 알림도 "지워야 할 파일 N개는 안내에" 로 바꿈. 안내를 못 써도 추출 자체는 실패로 만들지 않는다(파일은 이미 다 뽑힌 뒤다) |
하네스 ReportTest |
+14건(31 → 45) — 머리글 · 범위 두 줄 · 요약 수 · 이름 바뀜 표기 · 지울 목록 · 지운 파일이 뽑은 목록에 없음 · 한글 경로 · 빈 목록 · 만든 사람 없음 · 폴더 옆 이름 세 가지 |
확인한 것 — 화면에서 뽑아 git 과 대조
| 경우 | 안내에 적힌 것 | git diff -M --name-status |
|---|---|---|
범위 4eb9ece → cbcad8a |
뽑은 3개(추가 Extract/logo.bin · 이름 바뀜 Motion/Renamed16.cs (옛 이름 Motion/Unit16.cs) · 추가 한글폴더/깊은/경로/아래/설명.cs) · 지울 2개(옛 이름 Motion/Unit16.cs · 지워짐 Recipe/Unit11.cs) |
A logo.bin · R100 Unit16.cs → Renamed16.cs · D Unit11.cs · A 설명.cs — 같음 |
| 병합 커밋(시작점 없음) | 범위 cbcad8a … (고른 커밋의 부모) → 58d5f7f … · 뽑은 1개 Side/SideOnly.cs · 지울 0개 |
같음 |
- 안내 파일은 폴더 옆에 생긴다(
note2b_변경분안내.txt·note5_변경분안내.txt). 폴더 안에는 뽑은 파일만 있다. - 알림: "3개 파일 추출 (지워야 할 파일 1개는 안내에)" · "1개 파일 추출 · 안내 note5_변경분안내.txt". Git 탭 로그에 안내 경로도 남는다.
- 하네스 22벌 1,173건 통과(1,159 → +14) · 빌드 경고 0 · 오류 0.
남긴 것 (시험 도구 쪽)
- 화면 잠금이 걸린 동안에는 마우스가 데스크톱에 닿지 않는다(커서 좌표가 0,0 으로 돌아가고 화면 캡처가 실패한다). 잠긴 줄 모르고 "클릭이 안 먹는다" 로 두 번 헤맸다 — 앞으로는 커서 자리와 맨 앞 창부터 본다.
- 목록에서 스크롤이 필요한 줄은 누를 때마다 자리를 다시 읽어야 한다. 옛 자리로 누르면 조용히 빗나가고, 그 뒤 [여기부터] 가 엉뚱한 커밋(HEAD)으로 잡혀 범위가 거꾸로 됐다.
- PowerShell 변수는 대소문자를 안 가린다 —
$S(경로)와$s(파일 글)가 겹쳐 경로가 깨졌다(9차 A-2 와 같은 종류).
A-3. 이미 파일이 있는 폴더 · 쓰다 막힐 때 (2026-09-18, 완료)
사용자 결정(2026-09-18): 고른 폴더 아래 새 폴더를 만든다 · 쓰다 막히면 먼저 보고 시작한다(하나라도 못 쓰면 아무것도 쓰지 않는다).
고친 것
| 자리 | 한 일 |
|---|---|
Services/ExportPlan.cs (새 파일) |
FolderName — 변경분_4eb9ece..cbcad8a_2026-09-18 처럼 범위와 날짜가 들어간 이름. UniquePath — 같은 이름이 있으면 _2 · _3. Blocked — 쓰기 전에 읽기 전용 · 다른 프로그램이 잡고 있는 파일을 걸러 목록으로. BlockedMessage — 사람에게 보일 글(앞 다섯 개 + "외 N개") |
Services/GitService.cs |
뽑기 전에 ExportPlan.Blocked 로 먼저 본다. 하나라도 막히면 폴더도 만들지 않고 IOException 으로 멈춘다 — 예전에는 앞 순서만 써진 반쯤 뽑힌 폴더가 남았다(A-1 경우 9) |
ViewModels/GitViewModel.cs |
고른 폴더에 바로 쏟지 않고 그 아래 새 폴더를 만들어 거기에 뽑는다. 안내 글은 그 폴더 옆(= 고른 폴더 안)에 붙는다. 알림도 폴더 이름을 앞에 — "변경분_4eb9ece..cbcad8a_2026-09-18 에 3개 (지워야 할 파일 1개는 안내에)" |
하네스 ReportTest |
+12건(45 → 57) — 폴더 이름 · _2 · _3 · 읽기 전용은 막힘 · 아직 없는 파일은 막힘 아님 · 열려 있는 파일은 막힘 · 보일 글의 개수와 줄임 |
확인한 것 — 화면에서
이미 파일이 있는 폴더(사람이 넣어 둔 사용자메모.txt · 옛 폴더 옛자료)를 골라 같은 범위를 두 번 뽑았다.
| 때 | 결과 |
|---|---|
| 첫 번째 | …\a3\변경분_4eb9ece..cbcad8a_2026-09-18 에 3개 · 안내는 그 옆에 |
| 두 번째 | …_2 폴더가 새로 생기고 거기에 3개 · 안내도 …_2_변경분안내.txt |
| 고른 폴더 안 | 새 폴더 둘 · 안내 둘 · 사용자메모.txt 와 옛자료 그대로 — 섞이지 않았다 |
- 먼저 보기(
Blocked)는 하네스 12건으로 확인했다. 화면에서는 재현되지 않는데, 뽑을 때마다 비어 있는 새 폴더를 만들기 때문이다 — A-1 경우 9(반쯤 뽑힌 폴더)가 애초에 생기지 않는다. 남겨 둔 까닭은 폴더가 이미 있는 드문 경우(다른 프로그램이 같은 이름을 방금 만든 경우)와, 나중에 폴더를 다시 쓰게 고칠 때를 위한 것이다. - 하네스 22벌 1,185건 통과(1,173 → +12) · 빌드 경고 0 · 오류 0.
남은 것
- A-4(ZIP)는 아직 정하지 않았다.
- 매뉴얼 · 웹 문서의 변경분 추출 설명(새 폴더 · 안내 파일)은 E-2 에서 함께 고친다.
C-1. 있는 [커밋 수정] 을 다시 내 보고 바로잡음 (2026-09-18, 완료 — 8 만 이번 범위 밖)
고치기 전에 여덟 가지를 화면에서 다시 냈다
시험 저장소: C1Repo 위에 amend 브랜치를 만들고 작성자 박지훈인 커밋을 HEAD 로, 다른 브랜치(feature/revert)에는 더 새 커밋을, 그리고 bare 저장소를 원격으로 걸어 upstream 을 두었다(e11-c1-setup.sh).
| # | 고치기 전에 본 것 |
|---|---|
| 1 | [모든 브랜치] 켠 채 [마지막 메시지] → 칸에 딴 브랜치 최신 작업(HEAD 아님). 그대로 [커밋 수정] 하니 HEAD 제목이 그 메시지로 바뀌었다 |
| 2 | 앱에서 [전체 스테이징] 한 파일이 말없이 커밋에 들어갔다(남은 변경 없음). 알림은 "커밋 수정" 뿐 |
| 3 | 작성자 박지훈 · 작성 2026-09-15 10:00 → 시험 · 2026-09-18 15:48 로 바뀜 |
| 4 | 충돌 24개가 남은 채로도 단추가 켜져 있고, 누르면 [커밋 수정] 실패: cannot create a tree from a not fully merged index |
| 5 | 병합 커밋을 고쳐도 부모 둘 · 본문(충돌 해결 26개 · 29줄) 그대로 |
| 6 | 원격에 이미 올라간 커밋도 막지 않고 고쳐졌고, 그 뒤 [Push] 가 cannot push non-fastforwardable reference 로 거부됨 |
| 7 | 알림 · 로그에 새 해시만(커밋: 61653f5 …). 고치기 전 해시는 어디에도 없음 |
| 8 | 커밋 메시지 칸이 한 줄짜리라 여러 줄 메시지를 아예 칠 수 없다. # 로 시작하는 글자는 그대로 들어간다 |
고친 것 (1 · 3 · 4 · 7)
| 자리 | 한 일 |
|---|---|
Services/CommitSelection.cs |
MessageOfHead — [마지막 메시지] 는 HEAD 커밋의 메시지를 읽는다(목록 순서와 무관). HEAD 가 목록에 없으면 아무것도 주지 않는다. CanAmend — 작업 중이면 끈다. AmendHint — 꺼진 까닭을 단추 설명으로. AmendDone — "커밋 수정 완료 (옛 abc1234 → 새 def5678) · 파일 N개 포함" |
Services/GitService.cs |
고쳐 쓸 때 원래 작성자 · 작성 시각을 그대로 쓴다(git 과 같게). 커밋한 사람 · 시각만 지금 |
Services/GitWorkspace.cs |
HeadFullSha 를 들고 있는다 — 이력 목록의 Sha 와 맞춰 보려면 짧은 해시로는 모자란다 |
ViewModels/GitViewModel.cs |
위 판단을 붙이고, 고치기 전 해시 · 함께 들어간 파일 수를 알림에. 작업이 시작 · 끝날 때 단추 설명도 다시 그린다 |
Views/GitView.xaml |
[커밋 수정] 설명을 상황에 따라 바뀌는 값으로 |
하네스 MergeSaveTest |
+15건(210 → 225) — HEAD 메시지 읽기(맨 위가 딴 브랜치여도 · 대소문자 · HEAD 가 목록에 없음 · 빈 목록) · 켜는 조건 넷 · 꺼진 까닭 · 알림 글 셋 |
고친 뒤 같은 순서로 다시
| # | 결과 |
|---|---|
| 1 | 칸에 남이 만든 커밋(HEAD 것) |
| 3 | 고친 뒤에도 작성자 박지훈 · 작성 2026-09-15 10:00 그대로, 커밋한 사람 · 시각만 지금 |
| 4 | 충돌 24개가 남은 동안 단추 꺼짐 — 누를 수 없고, 누른 뒤 실패 알림도 없다 |
| 7 | 알림 커밋 수정 완료 (옛 bcd2c43 → 새 fd7810c) · 파일 1개 포함 |
- 하네스 22벌 1,200건 통과(1,185 → +15) · 빌드 경고 0 · 오류 0.
이어서 고친 것 (2 · 6) — "먼저 묻기" (2026-09-18 사용자 결정)
두 가지 모두 막지 않고 먼저 묻는다. 막으면 정말로 그러려는 사람(빠뜨린 파일을 같이 넣기 · 아직 남이 안 받은 커밋 고치기)까지 못 하게 되고, 그대로 두면 모르는 새 벌어진다.
| 자리 | 한 일 |
|---|---|
Services/CommitSelection.cs |
AmendWarning(스테이징 수, 이미 올림, 원격 브랜치) — 물을 것이 없으면 null(안 묻는다). 있으면 해당하는 줄만 모아 "… ¶ 계속할까요?" 한 글로 |
ViewModels/GitViewModel.cs |
StagedFileCount(충돌 뺀 스테이징 수) · HeadTrackedBranch · IsHeadAlreadyPushed(추적 브랜치가 있고 앞선 커밋 0개). 물을 것이 있으면 MessageUtil.ShowYesNo 로 먼저 묻고, [아니오] 면 커밋도 메시지 칸도 그대로 두고 아무 일도 하지 않는다 |
하네스 MergeSaveTest |
+7건(225 → 232) — 안 묻는 경우 · 스테이징만 · 올린 것만 · 둘 다 · 브랜치 이름을 모를 때 "원격" · "Push 가 거부됩니다" · 끝이 늘 "계속할까요?" |
앞선 커밋 수는 마지막 fetch 시점 기준이라, fetch 전에 남이 받아 간 것까지는 알 수 없다. 그래서 막지 않고 묻기만 한다(주석에 남김).
고친 뒤 화면에서 (e11-c1g.ps1)
스테이징 1개를 만들어 두고, HEAD 가 origin/amend 와 같은 자리인 채로 냈다 — 두 가지가 겹치는 자리다.
| 무엇 | 결과 |
|---|---|
| [커밋 수정] 누름 | 확인 창 커밋 수정 — "스테이징해 둔 파일 1개도 이 커밋에 들어갑니다. / 이 커밋은 origin/amend 에 이미 올라가 있습니다. 고치면 다음 Push 가 거부됩니다. / 계속할까요?" · 단추 [아니오] [예] (e11-c1g-ask.png) |
| [아니오] | HEAD 62dd57f 그대로 · 스테이징 Recipe/Unit19.cs 그대로 · 메시지 칸 묻는지 확인 그대로 · 창 닫힘 |
| 다시 누르고 [예] | HEAD 62dd57f → 6207b26 · 알림 커밋 수정 완료 (옛 62dd57f → 새 6207b26) · 파일 1개 포함 |
| 스테이징 없음 · 원격보다 앞선 자리에서 다시 | 안 묻고 바로 고침 (ceaab5f, 작성자 박지훈 그대로) (e11-c1g-done.png) |
- 하네스 22벌 1,207건 통과(1,200 → +7) · 빌드 경고 0 · 오류 0 · 설정 파일 해시 같음.
남은 것
- 8. 여러 줄 커밋 메시지 — 칸이 한 줄이라 본문을 칠 수 없다. 이번 범위 밖으로 적어 둔다(병합 커밋 본문은 앱이 저절로 붙인다). C-2 의 [메시지 바꾸기] 창은 여러 줄을 받는다.
- C-2 는 아래(2026-09-22 완료).
C-2. 마지막이 아닌 커밋의 메시지 바꾸기 (2026-09-18 ~ 09-22, 완료 — 좁은 범위)
사용자 결정(2026-09-18): 한다 — 좁은 범위로. 화면은 기획안 문구대로 이력 줄 우클릭 메뉴.
고치기 전
- 이력 줄을 우클릭해도 메뉴가 없고, 이력 탭 단추는 Revert · Cherry-pick · Reset · 여기부터 · 해제 · 변경분 추출뿐이었다(
e11-c2-before.ps1). 고른 커밋의 메시지를 바꿀 길이 없었다. - 메시지는 커밋 해시에 들어가므로, HEAD 가 아닌 커밋을 바꾸면 그 커밋부터 HEAD 까지가 새 해시로 다시 써진다. 아직 안 올린 커밋이면 브랜치가 새 줄기로 옮겨 갈 뿐이지만, 올린 뒤라면 남의 이력과 갈라진다(사용자에게 설명함).
만든 것
| 자리 | 한 일 |
|---|---|
Services/CommitReword.cs (새) |
막을 까닭 — 고른 커밋 없음 · 작업 중 · 커밋 안 한 변경 · 지금 브랜치 조상 아님 · 원격에 올라감 · 다른 로컬 브랜치도 품음 · 구간에 태그 · 사이에 병합 커밋. 먼저 풀어야 할 것부터 말하고 푸는 길까지 적는다. 확인 글 · 완료 알림 · 메뉴 설명. Clean — 새 메시지를 git -m 처럼 다듬는다(아래) |
Services/GitService.cs · IGitService.cs · Models/GitModels.cs |
InspectReword — 저장소에서 사실만 읽는다(다시 쓸 수 · 병합 수 · 올라간 원격 브랜치 · 다른 브랜치 · 태그). RewordCommit — LibGit2Sharp Refs.RewriteHistory 로 고른 커밋의 메시지만 갈고 트리 · 작성자 · 작성 시각 · 부모 관계는 그대로. 바꾸기 전 자리는 refs/original/날짜-시각/ 에 남긴다(같은 자리에 두 번 쓰면 libgit2 가 막아서 시각을 붙임). 고친 커밋의 새 해시도 돌려준다 |
Views/RewordWindow.xaml(.cs) (새 창) |
새 메시지를 받는 창. 고친 커밋 한 줄(해시 · 작성자 · 날짜) · 몇 개가 다시 써지는지를 늘 보이고, 여러 줄을 받는다. 지금 메시지를 미리 넣어 전체를 골라 둔다. [바꾸기] 는 기본 단추가 아니다(Enter 는 줄바꿈) |
Views/GitView.xaml(.cs) |
이력 목록의 우클릭 메뉴 [메시지 바꾸기...] — MergeHub 의 첫 우클릭 메뉴. 목록은 오른쪽 누름으로 선택이 안 바뀌므로 우클릭한 줄을 먼저 고른다(10차 B-1 처럼 저장 안 한 편집이 있으면 먼저 묻고 [취소] 면 메뉴도 안 연다) |
ViewModels/GitViewModel.cs |
막힐 자리면 메뉴를 끄지 않고 눌렀을 때 까닭을 알림으로 — 까닭은 저장소를 읽어 봐야 알고, 꺼 두면 왜 안 되는지 알 길이 없다. 되면 창 → 확인 창 → 실행 → 고른 커밋이 새 해시를 따라간다 |
하네스 MergeSaveTest |
+40건(232 → 272) — 막는 여덟 가지와 보는 순서 · 확인 글 · 완료 알림 · 빈 메시지 · 안 바뀐 메시지 · 다듬기 아홉 |
화면에서 찾아 고친 것 — 끝 줄바꿈
첫 회차에 새 메시지가 줄바꿈 없이 저장됐다(셋 으로 끝남). git 이 만든 커밋은 늘 \n 으로 끝나고, MergeHub 의 [커밋] · [커밋 수정]도 libgit2 가 다듬는다. 칸을 어떻게 고쳤느냐에 따라 끝 줄바꿈이 있다 없다 했다.
libgit2 의 다듬기(PrettifyMessages)를 켜면 손대지 않은 뒤 커밋들 메시지까지 다듬어지므로, 새 메시지 하나만 CommitReword.Clean 으로 다듬는다(줄 끝 공백 · 앞뒤 빈 줄 없앰, 빈 줄 여럿은 하나, 끝은 줄바꿈 하나, # 줄 · 들여쓰기는 둠). 검사 9건을 먼저 넣어 실패를 보고 고쳤다.
같은 회차의 다른 둘은 스크립트 탓으로 가렸다(e11-c2-probe.ps1): 첫 우클릭이 안 먹은 것은 창을 앞으로 부르는 도우미가 다른 프로그램 창을 앞으로 가져와 클릭이 앱에 안 닿은 것, 한글이 한 글자만 들어간 것은 8ms 간격으로 몰아 친 것. 150ms 간격으로 치면 그대로 들어갔다.
고친 뒤 화면에서 (e11-c2-setup.sh · e11-c2a.ps1 · e11-c2b.ps1 · e11-c2c.ps1)
시험 저장소: reword 브랜치에 커밋 넷(작성자 박지훈 · 이수진, 셋째는 일부러 "셋제 커밋" 오타). 막힐 자리로 pushed(bare 원격에 올림) · merged(사이에 병합) · shared + shared-copy · tagged(v9.9).
되는 자리 — "셋제 커밋" 우클릭 → [메시지 바꾸기...]
| 무엇 | 결과 |
|---|---|
| 우클릭 | 그 줄이 먼저 골라지고 메뉴 메시지 바꾸기... |
| 창 | 83ed0b2 · 박지훈 · 2026-09-16 11:00 · "이 커밋과 그 뒤 1개, 모두 2개가 새 해시로 다시 써집니다" · 칸에 셋제 커밋 (e11-c2-window.png) |
| [취소] | HEAD 4c0263e 그대로 |
| "셋째 커밋" 치고 [바꾸기] | 확인 창 "83ed0b2 "셋제 커밋" 의 메시지를 바꿉니다. 이 커밋과 그 뒤 1개, 모두 2개가 새 해시로 다시 써집니다. 내용 · 작성자 · 작성 시각은 그대로입니다. 바꾸기 전 HEAD 4c0263e 는 로그에 남겨…" (e11-c2-confirm.png) |
| [예] | 알림 메시지 바꿈 완료 (옛 HEAD 4c0263e → 새 HEAD 1b11c03) · 커밋 2개 다시 씀 · 로그 … · 되돌릴 자리 refs/original/20260922-102604/ |
| git 대조 | 넷째 · 셋째: 트리 해시 · 작성자 · 작성 시각 같음, 해시만 새것. 제목은 셋째만 바뀜. 둘째 아래는 해시까지 그대로 · 커밋 수 같음 · 워킹트리 깨끗 |
| 메시지 끝 | 셋째 커밋\n — 손 안 댄 넷째(넷째 커밋\n)와 같은 꼴 |
| 고른 커밋 | 새 해시 b2d9880 을 따라감 |
| 되돌리기 | git reset --hard refs/original/20260922-102604/heads/reword → 4c0263e … 셋제 커밋 이 그대로 돌아옴 |
막히는 자리 — 모두 창이 안 뜨고 HEAD 그대로, 알림에 까닭
| 자리 | 알림 |
|---|---|
| 올린 커밋 | "이 커밋은 origin2/pushed 에 이미 올라가 있습니다. 올린 커밋을 다시 쓰면 남의 이력과 갈라져 막습니다." |
| 사이에 병합 | "고른 커밋과 HEAD 사이에 병합 커밋이 1개 있습니다. 병합 이력은 다시 쓰지 않습니다." |
| 다른 브랜치도 품음 | "이 커밋을 다른 브랜치도 품고 있습니다(shared-copy). 그 브랜치까지 다시 써야 해서 막습니다." |
| 구간에 태그 | "다시 쓸 구간에 태그가 있습니다(v9.9). 태그가 가리키는 커밋이 사라져 막습니다." |
| 작업 중(병합 충돌 26개) | "병합 · rebase · cherry-pick · revert 를 끝낸 뒤에 쓸 수 있습니다." |
| 커밋 안 한 변경 | "커밋하지 않은 변경이 있습니다. 먼저 커밋하거나 stash 한 뒤에 바꾸세요." |
| 다른 브랜치에만([모든 브랜치]) | "지금 브랜치에서 닿지 않는 커밋입니다. 그 커밋이 있는 브랜치로 체크아웃한 뒤에 바꾸세요." (e11-c2-other.png) |
| 파일 비교 탭에 저장 안 한 편집 | 우클릭하자 저장하지 않은 편집 창("Common/Util/Unit103.cs 에 저장하지 않은 편집이 있습니다. 다른 커밋을 봅니다.") → [취소] 면 메뉴도 안 열리고 선택 그대로 (e11-c2-unsaved.png) |
- 하네스 22벌 1,247건 통과(1,207 → +40) · 빌드 경고 0 · 오류 0 · 설정 파일 해시 같음.
알아 둘 것
- 판단은 마지막 fetch 시점 기준이다. fetch 전에 남이 올린 것까지는 모른다(C-1 과 같음).
- 되돌릴 자리
refs/original/…은 이력 목록에 안 보인다(목록은 브랜치만 훑음). 지우는 단추는 두지 않았다 — 되돌릴 일이 없으면 그대로 두어도 된다. - HEAD 커밋도 이 메뉴로 바꿀 수 있다. [커밋 수정] 과 달리 스테이징한 파일이 들어가지 않는 메시지만 고치는 길이다.
F-12. C# 코드 스타일 맞춤의 기본값을 AURORA 로 (2026-09-18, 완료)
사용자: "기본값은 원본형태를 따르고 C#인 경우에 AURORA 스타일로 하자" → 물어서 정한 것은 제품 기본값 AURORA · C# 파일만 · 저장 동작은 지금 그대로(켜져 있으면 저장도 그 스타일로 쓴다).
알아본 것
- C/C++ · XAML 은 고칠 것이 없었다. 스타일 맞춤은
CSharpStyle.Applies가 확장자.cs만 보므로(Services/CSharpStyle.cs:60) 설정이 무엇이든 다른 파일은 원본 그대로 견준다. - 그래서 바뀐 것은 설정 기본값 한 줄뿐이다.
고친 것
| 자리 | 고친 것 |
|---|---|
MergeHubSettings.cs:77 |
CSharpBraceStyle 기본값 None → Aurora. 왜 그렇게 정했는지와 "C# 파일에만 걸린다" 를 주석으로 남김 |
| 웹 문서 매뉴얼 | "기본은 끔" → "기본은 AURORA(2026-09-18 결정) · 끄려면 콤보에서 [맞추지 않음]" · "C# 파일에만 걸린다" 한 줄 더함 |
| 웹 문서 설정 표 | 기본값 칸 끔 → AURORA, ".cs 파일에만 걸린다" |
| 웹 문서 시연 대본 | "스타일 맞춤은 끔으로 둔다" → "기본이 AURORA 이므로 시연 전에 [맞추지 않음] 으로 바꿔 둔다" |
하네스 StyleTest |
+12건(78 → 90) — 설정 기본값이 AURORA 인지, .cpp · .h · .hpp · .c · .xaml · .py · .txt · .cs.txt 는 안 걸리는지, .cs · .CS · 한글 경로 .cs 는 걸리는지. 고치기 전에 먼저 넣어 기본값 검사만 실패하는 것을 보고 시작했다 |
확인한 것 — 설정 파일이 없는 첫 실행 (e11-f12.ps1)
설정 파일을 백업해 치우고, 중괄호 자리만 다른 짝 두 벌을 명령줄(--diff)로 열었다.
| 무엇 | 결과 |
|---|---|
C# 짝(left.cs Allman · right.cs AURORA) |
요약 "차이 없음" · 상태바 무시: 머지 주석 · C# AURORA (e11-f12-cs.png) |
C++ 짝(left.cpp · right.cpp, 같은 모양의 중괄호 차이) |
요약 "남은 차이 4줄" — 원본 그대로 (e11-f12-cpp.png) |
| 앱이 새로 만든 설정 파일 | "CSharpBraceStyle": 1 (= Aurora) |
| 설정 파일 되돌림 | 해시 같음 |
- 하네스 22벌 1,159건 통과(1,147 → +12) · 빌드 경고 0 · 오류 0.
- 이미 설정 파일이 있는 PC 는 그 값을 그대로 쓴다. 이번 변경은 설정이 없는 첫 실행에만 닿는다.