11차 C-1(마무리): [커밋 수정] 은 위험한 자리에서 먼저 묻는다
스테이징해 둔 파일이 있으면 그 파일도 이 커밋에 들어간다는 것을, 이미 원격에 올라간 커밋이면 고치는 순간 다음 Push 가 거부된다는 것을 누르기 전에 알린다. 둘 다 걸리면 한 창에 두 줄로 묻고, [아니오] 면 커밋도 메시지 칸도 그대로 둔다. 막지 않고 묻기만 하는 까닭 - 앞선 커밋 수는 마지막 fetch 시점 기준이라 남이 이미 받아 갔는지는 확실히 알 수 없고, 빠뜨린 파일을 같이 넣으려고 일부러 그러는 사람도 있다. - CommitSelection.AmendWarning: 물을 것이 없으면 null(안 묻는다) - GitViewModel: 스테이징 수 · 추적 브랜치 · 앞선 커밋 0개인지로 판단 - 하네스 MergeSaveTest +7 (232건, 22벌 1,207건) · 빌드 경고 0 · 오류 0 - 화면 확인(e11-c1g.ps1): 두 줄 다 물음 -> [아니오] 뒤 HEAD · 스테이징 · 메시지 칸 그대로 -> [예] 뒤 "옛 62dd57f -> 새 6207b26 · 파일 1개 포함", 물을 것이 없는 자리에서는 안 묻고 바로 고침 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
aa3f179390
commit
8f9ac13872
@ -127,7 +127,7 @@ A-1 에서 값으로 확인한 것 — 지운 파일은 "삭제되어 건너뜀
|
||||
- A-4(ZIP)는 아직 정하지 않았다.
|
||||
- 매뉴얼 · 웹 문서의 변경분 추출 설명(새 폴더 · 안내 파일)은 E-2 에서 함께 고친다.
|
||||
|
||||
## C-1. 있는 [커밋 수정] 을 다시 내 보고 바로잡음 (2026-09-18, 일부 완료 — 2 · 6 은 결정 대기)
|
||||
## C-1. 있는 [커밋 수정] 을 다시 내 보고 바로잡음 (2026-09-18, 완료 — 8 만 이번 범위 밖)
|
||||
|
||||
### 고치기 전에 여덟 가지를 화면에서 다시 냈다
|
||||
|
||||
@ -166,10 +166,33 @@ A-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 · 설정 파일 해시 같음.
|
||||
|
||||
### 남은 것
|
||||
|
||||
- **2. 스테이징한 파일이 함께 들어가는 것** — 지금은 들어가되 알림에 "파일 N개 포함" 으로 드러내기만 한다. 묻기 / 메시지만 고치기(git `--only`) / 지금대로 중 정해야 한다.
|
||||
- **6. 이미 올린 커밋** — 지금도 막지 않는다(그 뒤 Push 가 거부된다). 묻기 / 막기 / 매뉴얼에만 중 정해야 한다.
|
||||
- **8. 여러 줄 커밋 메시지** — 칸이 한 줄이라 본문을 칠 수 없다. 이번 범위 밖으로 적어 둔다(병합 커밋 본문은 앱이 저절로 붙인다).
|
||||
- C-2(마지막이 아닌 커밋의 메시지 수정)는 C-1 을 쓰면서 더 필요한지 보고 정한다.
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
| 날짜 | 항목 | 커밋 |
|
||||
|---|---|---|
|
||||
| 2026-09-18 | **11차 C-1 (마무리)** — [커밋 수정] 을 누르기 전에 **먼저 묻는다**(사용자 결정): 스테이징해 둔 파일이 있으면 "파일 N개도 이 커밋에 들어갑니다", 이미 올린 커밋이면 "origin/… 에 이미 올라가 있습니다 · 고치면 다음 Push 가 거부됩니다". 둘 다면 두 줄을 한 창에. [아니오] 면 커밋도 메시지 칸도 그대로 둔다. 막지 않는 까닭은 앞선 커밋 수가 마지막 fetch 시점 기준이라 확실치 않아서다. 하네스 MergeSaveTest +7(232건) | 아래 |
|
||||
| 2026-09-18 | **11차 C-1 (일부)** — [커밋 수정]의 여덟 가지를 화면에서 재현한 뒤 넷을 고침: [마지막 메시지]가 이력 맨 위(딴 브랜치일 수 있음) 대신 **HEAD 커밋** 메시지를 읽고, 고쳐 써도 **원래 작성자 · 작성 시각을 지키며**(git 과 같게), 병합 · rebase · cherry-pick · revert **진행 중에는 단추를 끄고**(예전엔 눌러서 실패), 알림에 **"옛 해시 → 새 해시 · 파일 N개 포함"**. 하네스 MergeSaveTest +15(225건). 스테이징 파일 처리(2)와 이미 올린 커밋(6)은 사용자 결정 대기 | 아래 |
|
||||
| 2026-09-18 | **11차 F-1 에 덧 (추가 요청)** — 지시서의 F-1(칸 이름 · 어느 파일인지)에 "머지 주석에도 어디서 가져왔는지(REMOTE/BASE · 브랜치/해시)를 남기고, 그에 맞춰 무시 조건도 고친다" 를 적음. 고칠 곳(`MergeNote.NoteBody` · `LooksLikeNote` · `TailStart` · `CompareRules` · `FolderComparer` · `NoteConflict` · `NoteRows`)과 옛 주석도 그대로 무시되어야 한다는 기준까지. 코드 변경 없음 | 아래 |
|
||||
| 2026-09-18 | **11차 A-3** — 변경분을 고른 폴더에 바로 쏟지 않고 **그 아래 새 폴더**(`변경분_범위_날짜`, 같은 이름이면 `_2`)를 만들어 뽑는다(사용자 결정). 예전에는 묻지 않고 덮어써 지난번에 뽑은 것과 사람이 넣어 둔 파일이 섞였다. 또 뽑기 전에 읽기 전용 · 열려 있는 파일을 **먼저 보고** 하나라도 막히면 아무것도 쓰지 않는다 — 반쯤 뽑힌 폴더가 남지 않는다. 하네스 ReportTest +12(57건) | 아래 |
|
||||
|
||||
@ -350,7 +350,7 @@
|
||||
|
||||
| 상태 | 항목 |
|
||||
|---|---|
|
||||
| **일부** | C-1 있는 [커밋 수정] 바로잡기 — 여덟 가지를 화면에서 재현한 뒤 **1 · 3 · 4 · 7 고침**([마지막 메시지]가 HEAD 것 · 작성자와 작성 시각 보존 · 작업 중 단추 끔 · 알림에 "옛 → 새 해시 · 파일 N개 포함"). 하네스 MergeSaveTest +15(225건). **남은 결정**: 2(스테이징 파일 함께 들어감 — 묻기/메시지만/지금대로) · 6(이미 올린 커밋 — 묻기/막기/매뉴얼). 옛 항목: — [마지막 메시지] 가 목록 맨 위(다른 브랜치일 수 있음) · 스테이징 파일이 말없이 들어감 · 원래 작성자 · 시각이 바뀜 · 작업 중에도 켜짐 · 병합 커밋 · 올린 커밋 · 옛 해시 · `#` 줄 |
|
||||
| **완료** | C-1 있는 [커밋 수정] 바로잡기 — 여덟 가지를 화면에서 재현한 뒤 **1 · 3 · 4 · 7 고침**([마지막 메시지]가 HEAD 것 · 작성자와 작성 시각 보존 · 작업 중 단추 끔 · 알림에 "옛 → 새 해시 · 파일 N개 포함"), 이어서 **2 · 6 은 "먼저 묻기"**(사용자 결정) — 스테이징해 둔 파일이 있거나 이미 올린 커밋이면 확인 창을 띄우고 [아니오] 면 아무것도 안 바뀐다. 하네스 MergeSaveTest +22(232건). 8(여러 줄 메시지 못 침)만 범위 밖. 옛 항목: — [마지막 메시지] 가 목록 맨 위(다른 브랜치일 수 있음) · 스테이징 파일이 말없이 들어감 · 원래 작성자 · 시각이 바뀜 · 작업 중에도 켜짐 · 병합 커밋 · 올린 커밋 · 옛 해시 · `#` 줄 |
|
||||
| 대기 | C-2 마지막 커밋이 아닌 커밋의 메시지 수정 (기획안 "커밋 우클릭 → 이름 변경") — 할지 먼저 정함 |
|
||||
|
||||
### D. 시험 도구 정리
|
||||
|
||||
@ -89,6 +89,34 @@ namespace MergeHub.Services
|
||||
public static bool CanAmend(bool repositoryOpen, bool hasMessage, bool operationInProgress) =>
|
||||
repositoryOpen && hasMessage && !operationInProgress;
|
||||
|
||||
/// <summary>
|
||||
/// [커밋 수정] 을 누르기 전에 물어야 할 것(11차 C-1, 2026-09-18 사용자 결정: <b>먼저 묻기</b>).
|
||||
/// 물을 것이 없으면 null - 그때는 묻지 않고 바로 고친다.
|
||||
///
|
||||
/// 두 가지다. ① 스테이징해 둔 파일이 있으면 <b>그 파일도 이 커밋에 들어간다</b> - 메시지만 고치는 줄 알고
|
||||
/// 누르면 남의 눈에는 커밋 내용이 달라져 있다(값으로 확인). ② 이 커밋이 이미 원격에 올라가 있으면
|
||||
/// 고치는 순간 남의 이력과 갈라져 다음 Push 가 거부된다(`cannot push non-fastforwardable reference`).
|
||||
/// </summary>
|
||||
public static string? AmendWarning(int stagedCount, bool alreadyPushed, string? remoteBranch)
|
||||
{
|
||||
var lines = new List<string>();
|
||||
|
||||
if (stagedCount > 0)
|
||||
lines.Add($"스테이징해 둔 파일 {stagedCount}개도 이 커밋에 들어갑니다.");
|
||||
|
||||
if (alreadyPushed)
|
||||
{
|
||||
var where = string.IsNullOrWhiteSpace(remoteBranch) ? "원격" : remoteBranch!;
|
||||
lines.Add($"이 커밋은 {where} 에 이미 올라가 있습니다. 고치면 다음 Push 가 거부됩니다.");
|
||||
}
|
||||
|
||||
if (lines.Count == 0) return null;
|
||||
|
||||
lines.Add(string.Empty);
|
||||
lines.Add("계속할까요?");
|
||||
return string.Join("\n", lines);
|
||||
}
|
||||
|
||||
/// <summary>작업 중이라 [커밋 수정] 이 꺼졌을 때 단추 설명에 쓸 말.</summary>
|
||||
public static string AmendHint(bool operationInProgress) =>
|
||||
operationInProgress
|
||||
|
||||
@ -660,6 +660,25 @@ namespace MergeHub.ViewModels
|
||||
/// <summary>단추 설명. 작업 중이면 왜 꺼졌는지 말한다.</summary>
|
||||
public string AmendHint => CommitSelection.AmendHint(AmendBlockedByOperation);
|
||||
|
||||
/// <summary>스테이징해 둔 파일 수 - 고치면 이 파일들도 함께 들어간다(충돌 중인 것은 빼고 센다).</summary>
|
||||
private int StagedFileCount => _workspace.StatusFiles.Count(f => f.IsStaged && !f.IsConflicted);
|
||||
|
||||
/// <summary>지금 브랜치가 따라가는 원격 브랜치 이름(없으면 null).</summary>
|
||||
private string? HeadTrackedBranch => _workspace.Branches.FirstOrDefault(b => b.IsCurrentHead)?.TrackedBranch;
|
||||
|
||||
/// <summary>
|
||||
/// HEAD 가 <b>이미 원격에 올라가 있는가</b> - 추적 브랜치가 있고 앞선 커밋이 0개면 올라간 것으로 본다.
|
||||
/// 이 수치는 마지막 fetch 시점 기준이라, fetch 전에 남이 올린 것까지는 알 수 없다(그래서 막지 않고 묻기만 한다).
|
||||
/// </summary>
|
||||
private bool IsHeadAlreadyPushed
|
||||
{
|
||||
get
|
||||
{
|
||||
var head = _workspace.Branches.FirstOrDefault(b => b.IsCurrentHead);
|
||||
return head?.TrackedBranch is not null && (head.AheadBy ?? 0) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 마지막 커밋을 고쳐 쓴다(`git commit --amend`).
|
||||
///
|
||||
@ -667,12 +686,18 @@ namespace MergeHub.ViewModels
|
||||
/// 이미 올린 커밋을 고치면 남의 이력과 갈라지므로, <b>푸시 전에만</b> 쓰는 것이 원칙이다.
|
||||
///
|
||||
/// 고치기 전 해시를 알림에 남긴다(11차 C-1) - 예전에는 새 해시만 알려 되돌릴 실마리가 없었다.
|
||||
/// 스테이징해 둔 파일이 있거나 이미 올린 커밋이면 <b>먼저 묻는다</b>(11차 C-1, 2026-09-18 사용자 결정).
|
||||
/// </summary>
|
||||
[RelayCommand(CanExecute = nameof(CanAmend))]
|
||||
private Task AmendAsync()
|
||||
{
|
||||
var oldSha = _workspace.HeadFullSha;
|
||||
|
||||
// 누르기 전에 물을 것. [취소] 하면 커밋도 메시지 칸도 그대로 둔다.
|
||||
var warning = CommitSelection.AmendWarning(StagedFileCount, IsHeadAlreadyPushed, HeadTrackedBranch);
|
||||
if (warning is not null && !MessageUtil.ShowYesNo("커밋 수정", warning))
|
||||
return Task.CompletedTask;
|
||||
|
||||
return _workspace.RunAndRefreshAsync("커밋 수정", () =>
|
||||
{
|
||||
var staged = _workspace.Git.GetStatus().StagedCount;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user