Ubisam-MergeTool/doc/history/2026-09-18-11차.md
ksj09406 588f3d75e9 11차 C-2: 이력 줄 우클릭으로 마지막이 아닌 커밋의 메시지를 바꾼다
기획안 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>
2026-09-22 10:34:58 +09:00

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 는 그 값을 그대로 쓴다. 이번 변경은 설정이 없는 첫 실행에만 닿는다.