11차 C-1(일부): [커밋 수정] 을 다시 내 보고 넷을 바로잡음
화면에서 여덟 가지를 먼저 재현하고, 방향이 정해진 1 · 3 · 4 · 7 만 고쳤다. - [마지막 메시지] 는 이력 맨 위가 아니라 HEAD 커밋 메시지를 읽는다 (CommitSelection.MessageOfHead) - 고쳐 써도 원래 작성자 · 작성 시각을 지킨다 (git 과 같게, 커밋한 사람만 지금) - 병합 · rebase · cherry-pick · revert 중에는 단추를 끈다 (CanAmend) · 꺼진 까닭을 단추 설명으로 - 알림에 '커밋 수정 완료 (옛 bcd2c43 → 새 fd7810c) · 파일 1개 포함' - GitWorkspace 가 HeadFullSha 를 들고 있는다 - 하네스 MergeSaveTest +15 (210 → 225), 22벌 1,200건 통과, 빌드 경고 0 오류 0 남은 결정: 2(스테이징 파일이 함께 들어가는 것) · 6(이미 올린 커밋). 8(여러 줄 메시지)은 범위 밖으로 적어 둠. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
bd270f4628
commit
aa3f179390
@ -127,6 +127,52 @@ A-1 에서 값으로 확인한 것 — 지운 파일은 "삭제되어 건너뜀
|
|||||||
- A-4(ZIP)는 아직 정하지 않았다.
|
- A-4(ZIP)는 아직 정하지 않았다.
|
||||||
- 매뉴얼 · 웹 문서의 변경분 추출 설명(새 폴더 · 안내 파일)은 E-2 에서 함께 고친다.
|
- 매뉴얼 · 웹 문서의 변경분 추출 설명(새 폴더 · 안내 파일)은 E-2 에서 함께 고친다.
|
||||||
|
|
||||||
|
## C-1. 있는 [커밋 수정] 을 다시 내 보고 바로잡음 (2026-09-18, 일부 완료 — 2 · 6 은 결정 대기)
|
||||||
|
|
||||||
|
### 고치기 전에 여덟 가지를 화면에서 다시 냈다
|
||||||
|
|
||||||
|
시험 저장소: `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. 스테이징한 파일이 함께 들어가는 것** — 지금은 들어가되 알림에 "파일 N개 포함" 으로 드러내기만 한다. 묻기 / 메시지만 고치기(git `--only`) / 지금대로 중 정해야 한다.
|
||||||
|
- **6. 이미 올린 커밋** — 지금도 막지 않는다(그 뒤 Push 가 거부된다). 묻기 / 막기 / 매뉴얼에만 중 정해야 한다.
|
||||||
|
- **8. 여러 줄 커밋 메시지** — 칸이 한 줄이라 본문을 칠 수 없다. 이번 범위 밖으로 적어 둔다(병합 커밋 본문은 앱이 저절로 붙인다).
|
||||||
|
- C-2(마지막이 아닌 커밋의 메시지 수정)는 C-1 을 쓰면서 더 필요한지 보고 정한다.
|
||||||
|
|
||||||
## F-12. C# 코드 스타일 맞춤의 기본값을 AURORA 로 (2026-09-18, 완료)
|
## F-12. C# 코드 스타일 맞춤의 기본값을 AURORA 로 (2026-09-18, 완료)
|
||||||
|
|
||||||
사용자: "기본값은 원본형태를 따르고 C#인 경우에 AURORA 스타일로 하자" → 물어서 정한 것은 **제품 기본값 AURORA · C# 파일만 · 저장 동작은 지금 그대로**(켜져 있으면 저장도 그 스타일로 쓴다).
|
사용자: "기본값은 원본형태를 따르고 C#인 경우에 AURORA 스타일로 하자" → 물어서 정한 것은 **제품 기본값 AURORA · C# 파일만 · 저장 동작은 지금 그대로**(켜져 있으면 저장도 그 스타일로 쓴다).
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
| 날짜 | 항목 | 커밋 |
|
| 날짜 | 항목 | 커밋 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
|
| 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차 F-1 에 덧 (추가 요청)** — 지시서의 F-1(칸 이름 · 어느 파일인지)에 "머지 주석에도 어디서 가져왔는지(REMOTE/BASE · 브랜치/해시)를 남기고, 그에 맞춰 무시 조건도 고친다" 를 적음. 고칠 곳(`MergeNote.NoteBody` · `LooksLikeNote` · `TailStart` · `CompareRules` · `FolderComparer` · `NoteConflict` · `NoteRows`)과 옛 주석도 그대로 무시되어야 한다는 기준까지. 코드 변경 없음 | 아래 |
|
||||||
| 2026-09-18 | **11차 A-3** — 변경분을 고른 폴더에 바로 쏟지 않고 **그 아래 새 폴더**(`변경분_범위_날짜`, 같은 이름이면 `_2`)를 만들어 뽑는다(사용자 결정). 예전에는 묻지 않고 덮어써 지난번에 뽑은 것과 사람이 넣어 둔 파일이 섞였다. 또 뽑기 전에 읽기 전용 · 열려 있는 파일을 **먼저 보고** 하나라도 막히면 아무것도 쓰지 않는다 — 반쯤 뽑힌 폴더가 남지 않는다. 하네스 ReportTest +12(57건) | 아래 |
|
| 2026-09-18 | **11차 A-3** — 변경분을 고른 폴더에 바로 쏟지 않고 **그 아래 새 폴더**(`변경분_범위_날짜`, 같은 이름이면 `_2`)를 만들어 뽑는다(사용자 결정). 예전에는 묻지 않고 덮어써 지난번에 뽑은 것과 사람이 넣어 둔 파일이 섞였다. 또 뽑기 전에 읽기 전용 · 열려 있는 파일을 **먼저 보고** 하나라도 막히면 아무것도 쓰지 않는다 — 반쯤 뽑힌 폴더가 남지 않는다. 하네스 ReportTest +12(57건) | 아래 |
|
||||||
| 2026-09-18 | **11차 A-2** — 변경분을 뽑으면 **폴더 옆에 안내 파일**(`…_변경분안내.txt`)을 함께 만든다(사용자 결정: 폴더 밖 · 지울 파일은 목록으로만). A-1 에서 지운 파일 · 이름 바뀐 옛 경로 · 뽑은 범위가 결과에 안 남는 것을 확인했기 때문. 안내에 범위(커밋 제목 · 날짜) · 뽑은 파일(추가 · 수정 · 이름 바뀜은 옛 이름 병기) · **장비에서 지워야 할 파일**을 적는다. 추출이 무엇을 했는지 목록으로 돌려주도록 `ExportChangedFiles` 를 고치고, 안내를 못 써도 추출은 성공으로 둔다. 하네스 ReportTest +14(45건) | 아래 |
|
| 2026-09-18 | **11차 A-2** — 변경분을 뽑으면 **폴더 옆에 안내 파일**(`…_변경분안내.txt`)을 함께 만든다(사용자 결정: 폴더 밖 · 지울 파일은 목록으로만). A-1 에서 지운 파일 · 이름 바뀐 옛 경로 · 뽑은 범위가 결과에 안 남는 것을 확인했기 때문. 안내에 범위(커밋 제목 · 날짜) · 뽑은 파일(추가 · 수정 · 이름 바뀜은 옛 이름 병기) · **장비에서 지워야 할 파일**을 적는다. 추출이 무엇을 했는지 목록으로 돌려주도록 `ExportChangedFiles` 를 고치고, 안내를 못 써도 추출은 성공으로 둔다. 하네스 ReportTest +14(45건) | 아래 |
|
||||||
|
|||||||
@ -350,7 +350,7 @@
|
|||||||
|
|
||||||
| 상태 | 항목 |
|
| 상태 | 항목 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| 대기 | C-1 있는 [커밋 수정] 을 다시 내 보고 바로잡기 — [마지막 메시지] 가 목록 맨 위(다른 브랜치일 수 있음) · 스테이징 파일이 말없이 들어감 · 원래 작성자 · 시각이 바뀜 · 작업 중에도 켜짐 · 병합 커밋 · 올린 커밋 · 옛 해시 · `#` 줄 |
|
| **일부** | C-1 있는 [커밋 수정] 바로잡기 — 여덟 가지를 화면에서 재현한 뒤 **1 · 3 · 4 · 7 고침**([마지막 메시지]가 HEAD 것 · 작성자와 작성 시각 보존 · 작업 중 단추 끔 · 알림에 "옛 → 새 해시 · 파일 N개 포함"). 하네스 MergeSaveTest +15(225건). **남은 결정**: 2(스테이징 파일 함께 들어감 — 묻기/메시지만/지금대로) · 6(이미 올린 커밋 — 묻기/막기/매뉴얼). 옛 항목: — [마지막 메시지] 가 목록 맨 위(다른 브랜치일 수 있음) · 스테이징 파일이 말없이 들어감 · 원래 작성자 · 시각이 바뀜 · 작업 중에도 켜짐 · 병합 커밋 · 올린 커밋 · 옛 해시 · `#` 줄 |
|
||||||
| 대기 | C-2 마지막 커밋이 아닌 커밋의 메시지 수정 (기획안 "커밋 우클릭 → 이름 변경") — 할지 먼저 정함 |
|
| 대기 | C-2 마지막 커밋이 아닌 커밋의 메시지 수정 (기획안 "커밋 우클릭 → 이름 변경") — 할지 먼저 정함 |
|
||||||
|
|
||||||
### D. 시험 도구 정리
|
### D. 시험 도구 정리
|
||||||
|
|||||||
@ -61,6 +61,57 @@ namespace MergeHub.Services
|
|||||||
/// <summary>작업이 진행 중이고 남은 충돌이 없는가.</summary>
|
/// <summary>작업이 진행 중이고 남은 충돌이 없는가.</summary>
|
||||||
public static bool IsResolvedOperation(bool inProgress, int conflictCount) => inProgress && conflictCount == 0;
|
public static bool IsResolvedOperation(bool inProgress, int conflictCount) => inProgress && conflictCount == 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// [마지막 메시지] 가 가져올 메시지(11차 C-1).
|
||||||
|
///
|
||||||
|
/// 예전에는 <b>이력 목록의 맨 위</b>(<c>Commits[0]</c>)를 가져왔다. [모든 브랜치] 를 켜면 맨 위가
|
||||||
|
/// 다른 브랜치의 더 새 커밋이라, 그 메시지를 가져와 그대로 [커밋 수정] 하면
|
||||||
|
/// <b>HEAD 제목이 남의 커밋 메시지로 바뀌었다</b>(값으로 확인). 고치는 대상은 늘 HEAD 이므로 HEAD 것을 읽는다.
|
||||||
|
/// HEAD 가 목록에 없으면(조회 개수 밖으로 밀렸을 때) 아무것도 주지 않는다 - 엉뚱한 것을 주느니 빈 칸이 낫다.
|
||||||
|
/// </summary>
|
||||||
|
public static string? MessageOfHead(IReadOnlyList<(string Sha, string Message)> commits, string? headSha)
|
||||||
|
{
|
||||||
|
if (commits is null || commits.Count == 0 || string.IsNullOrEmpty(headSha)) return null;
|
||||||
|
|
||||||
|
foreach (var commit in commits)
|
||||||
|
if (SameSha(commit.Sha, headSha)) return commit.Message;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// [커밋 수정] 을 켤 수 있는가(11차 C-1).
|
||||||
|
///
|
||||||
|
/// 예전에는 저장소가 열려 있고 메시지 칸이 비어 있지 않기만 하면 켜졌다. 병합 · rebase · cherry-pick ·
|
||||||
|
/// revert 가 도는 중에도 켜져 있어서 누르면 <c>cannot create a tree from a not fully merged index</c> 로
|
||||||
|
/// 실패했다(값으로 확인). git 도 병합 중 <c>--amend</c> 를 막는다. 작업 중에는 아예 끈다.
|
||||||
|
/// </summary>
|
||||||
|
public static bool CanAmend(bool repositoryOpen, bool hasMessage, bool operationInProgress) =>
|
||||||
|
repositoryOpen && hasMessage && !operationInProgress;
|
||||||
|
|
||||||
|
/// <summary>작업 중이라 [커밋 수정] 이 꺼졌을 때 단추 설명에 쓸 말.</summary>
|
||||||
|
public static string AmendHint(bool operationInProgress) =>
|
||||||
|
operationInProgress
|
||||||
|
? "병합 · rebase · cherry-pick · revert 를 끝낸 뒤에 쓸 수 있습니다"
|
||||||
|
: "마지막 커밋을 고쳐 씁니다 (git commit --amend). 푸시하기 전에만 쓰세요";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 커밋을 고친 뒤 알릴 글(11차 C-1).
|
||||||
|
///
|
||||||
|
/// 예전에는 "커밋 수정 완료 (새해시)" 라 <b>고치기 전 해시가 어디에도 남지 않았다.</b> 되돌리려면
|
||||||
|
/// reflog 를 뒤져야 했다. 함께 들어간 파일 수도 적는다 - 스테이징해 둔 것이 조용히 들어가는 것을 보이게.
|
||||||
|
/// </summary>
|
||||||
|
public static string AmendDone(string? oldSha, string? newSha, int fileCount)
|
||||||
|
{
|
||||||
|
var from = Short(oldSha);
|
||||||
|
var to = Short(newSha);
|
||||||
|
var files = fileCount > 0 ? $" · 파일 {fileCount}개 포함" : string.Empty;
|
||||||
|
return $"커밋 수정 완료 (옛 {from} → 새 {to}){files}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string Short(string? sha) =>
|
||||||
|
string.IsNullOrEmpty(sha) ? "-" : (sha!.Length > 7 ? sha.Substring(0, 7) : sha);
|
||||||
|
|
||||||
private static bool SameSha(string? a, string? b) =>
|
private static bool SameSha(string? a, string? b) =>
|
||||||
!string.IsNullOrEmpty(a) && string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
|
!string.IsNullOrEmpty(a) && string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
|||||||
@ -483,8 +483,14 @@ namespace MergeHub.Services
|
|||||||
if (string.IsNullOrWhiteSpace(message))
|
if (string.IsNullOrWhiteSpace(message))
|
||||||
throw new ArgumentException("커밋 메시지가 비어 있습니다.", nameof(message));
|
throw new ArgumentException("커밋 메시지가 비어 있습니다.", nameof(message));
|
||||||
|
|
||||||
var signature = BuildSignature();
|
var now = BuildSignature();
|
||||||
var commit = Repo.Commit(message, signature, signature, new CommitOptions { AmendPreviousCommit = amend });
|
|
||||||
|
// 고쳐 쓸 때는 <b>원래 작성자와 작성 시각을 그대로 둔다</b>(11차 C-1). git 도 그렇게 한다
|
||||||
|
// (`--reset-author` 를 줄 때만 바뀐다). 예전에는 남이 만든 커밋(cherry-pick 으로 가져온 것)의
|
||||||
|
// 메시지만 고쳐도 작성자가 지금 사람으로 바뀌어, 누가 쓴 코드인지가 사라졌다.
|
||||||
|
var author = amend && Repo.Head.Tip is { } tip ? tip.Author : now;
|
||||||
|
|
||||||
|
var commit = Repo.Commit(message, author, now, new CommitOptions { AmendPreviousCommit = amend });
|
||||||
Report($"커밋: {commit.Sha[..7]} {commit.MessageShort}");
|
Report($"커밋: {commit.Sha[..7]} {commit.MessageShort}");
|
||||||
return commit.Sha;
|
return commit.Sha;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -155,6 +155,9 @@ namespace MergeHub.Services
|
|||||||
[ObservableProperty] private string _repositoryName = "-";
|
[ObservableProperty] private string _repositoryName = "-";
|
||||||
[ObservableProperty] private string _currentBranch = "-";
|
[ObservableProperty] private string _currentBranch = "-";
|
||||||
[ObservableProperty] private string _headSha = "-";
|
[ObservableProperty] private string _headSha = "-";
|
||||||
|
|
||||||
|
/// <summary>HEAD 의 전체 해시. 이력 목록(<see cref="Commits"/>)의 Sha 와 맞춰 볼 때 쓴다(11차 C-1).</summary>
|
||||||
|
public string? HeadFullSha { get; private set; }
|
||||||
[ObservableProperty] private string _workingTreeSummary = "저장소 없음";
|
[ObservableProperty] private string _workingTreeSummary = "저장소 없음";
|
||||||
[ObservableProperty] private bool _isWorkingTreeClean = true;
|
[ObservableProperty] private bool _isWorkingTreeClean = true;
|
||||||
[ObservableProperty] private bool _isRepositoryOpen;
|
[ObservableProperty] private bool _isRepositoryOpen;
|
||||||
@ -410,6 +413,7 @@ namespace MergeHub.Services
|
|||||||
RepositoryName = GetRepositoryName(info.WorkingDirectory);
|
RepositoryName = GetRepositoryName(info.WorkingDirectory);
|
||||||
CurrentBranch = info.CurrentBranchName ?? "(detached)";
|
CurrentBranch = info.CurrentBranchName ?? "(detached)";
|
||||||
HeadSha = string.IsNullOrEmpty(info.HeadSha) ? "-" : info.HeadSha!.Substring(0, 7);
|
HeadSha = string.IsNullOrEmpty(info.HeadSha) ? "-" : info.HeadSha!.Substring(0, 7);
|
||||||
|
HeadFullSha = info.HeadSha;
|
||||||
IsRepositoryOpen = true;
|
IsRepositoryOpen = true;
|
||||||
|
|
||||||
IsRemoteConnected = remotes.Count > 0;
|
IsRemoteConnected = remotes.Count > 0;
|
||||||
|
|||||||
@ -646,30 +646,67 @@ namespace MergeHub.ViewModels
|
|||||||
|
|
||||||
// ================= 커밋 수정 (amend) =================
|
// ================= 커밋 수정 (amend) =================
|
||||||
|
|
||||||
private bool CanAmend() => IsOpen() && !string.IsNullOrWhiteSpace(CommitMessage);
|
/// <summary>
|
||||||
|
/// [커밋 수정] 을 켤 조건. <b>작업 중에는 끈다</b>(11차 C-1) - 병합 · rebase · cherry-pick · revert 가
|
||||||
|
/// 도는 중에 누르면 "cannot create a tree from a not fully merged index" 로 실패했다.
|
||||||
|
/// </summary>
|
||||||
|
private bool CanAmend() =>
|
||||||
|
CommitSelection.CanAmend(IsOpen(), !string.IsNullOrWhiteSpace(CommitMessage), AmendBlockedByOperation);
|
||||||
|
|
||||||
|
/// <summary>병합 · rebase · cherry-pick · revert 가 도는 중인가.</summary>
|
||||||
|
private bool AmendBlockedByOperation =>
|
||||||
|
_workspace.IsMergeInProgress || _workspace.IsRebaseInProgress || _workspace.IsOperationInProgress;
|
||||||
|
|
||||||
|
/// <summary>단추 설명. 작업 중이면 왜 꺼졌는지 말한다.</summary>
|
||||||
|
public string AmendHint => CommitSelection.AmendHint(AmendBlockedByOperation);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 마지막 커밋을 고쳐 쓴다(`git commit --amend`).
|
/// 마지막 커밋을 고쳐 쓴다(`git commit --amend`).
|
||||||
///
|
///
|
||||||
/// 오타 난 메시지나 빠뜨린 파일을 <b>새 커밋을 쌓지 않고</b> 바로잡을 때 쓴다.
|
/// 오타 난 메시지나 빠뜨린 파일을 <b>새 커밋을 쌓지 않고</b> 바로잡을 때 쓴다.
|
||||||
/// 이미 올린 커밋을 고치면 남의 이력과 갈라지므로, <b>푸시 전에만</b> 쓰는 것이 원칙이다.
|
/// 이미 올린 커밋을 고치면 남의 이력과 갈라지므로, <b>푸시 전에만</b> 쓰는 것이 원칙이다.
|
||||||
|
///
|
||||||
|
/// 고치기 전 해시를 알림에 남긴다(11차 C-1) - 예전에는 새 해시만 알려 되돌릴 실마리가 없었다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RelayCommand(CanExecute = nameof(CanAmend))]
|
[RelayCommand(CanExecute = nameof(CanAmend))]
|
||||||
private Task AmendAsync() => _workspace.RunAndRefreshAsync("커밋 수정", () =>
|
private Task AmendAsync()
|
||||||
{
|
{
|
||||||
var sha = _workspace.Git.Commit(CommitMessage, amend: true);
|
var oldSha = _workspace.HeadFullSha;
|
||||||
_workspace.OnUi(() =>
|
|
||||||
|
return _workspace.RunAndRefreshAsync("커밋 수정", () =>
|
||||||
{
|
{
|
||||||
CommitMessage = string.Empty;
|
var staged = _workspace.Git.GetStatus().StagedCount;
|
||||||
MessageUtil.ShowSuccessToast($"커밋 수정 완료 ({sha.Substring(0, 7)})");
|
var sha = _workspace.Git.Commit(CommitMessage, amend: true);
|
||||||
|
_workspace.OnUi(() =>
|
||||||
|
{
|
||||||
|
CommitMessage = string.Empty;
|
||||||
|
MessageUtil.ShowSuccessToast(CommitSelection.AmendDone(oldSha, sha, staged));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
private bool CanLoadLastMessage() => IsOpen() && _workspace.Commits.Count > 0;
|
private bool CanLoadLastMessage() => IsOpen() && _workspace.Commits.Count > 0;
|
||||||
|
|
||||||
/// <summary>고칠 메시지를 처음부터 다시 치지 않도록 마지막 커밋의 메시지를 가져온다.</summary>
|
/// <summary>
|
||||||
|
/// 고칠 메시지를 처음부터 다시 치지 않도록 <b>HEAD 커밋</b>의 메시지를 가져온다.
|
||||||
|
///
|
||||||
|
/// 예전에는 이력 목록의 맨 위(<c>Commits[0]</c>)를 가져왔다. [모든 브랜치] 를 켜면 맨 위가 다른 브랜치의
|
||||||
|
/// 더 새 커밋이라, 그대로 [커밋 수정] 하면 <b>HEAD 제목이 남의 커밋 메시지로 바뀌었다</b>(11차 C-1).
|
||||||
|
/// </summary>
|
||||||
[RelayCommand(CanExecute = nameof(CanLoadLastMessage))]
|
[RelayCommand(CanExecute = nameof(CanLoadLastMessage))]
|
||||||
private void LoadLastMessage() => CommitMessage = _workspace.Commits[0].Message.TrimEnd();
|
private void LoadLastMessage()
|
||||||
|
{
|
||||||
|
var pairs = _workspace.Commits.Select(c => (c.Sha, c.Message)).ToList();
|
||||||
|
var message = CommitSelection.MessageOfHead(pairs, _workspace.HeadFullSha);
|
||||||
|
|
||||||
|
if (message is null)
|
||||||
|
{
|
||||||
|
MessageUtil.ShowWarningToast("HEAD 커밋이 이력 목록에 없어 메시지를 가져오지 못했습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CommitMessage = message.TrimEnd();
|
||||||
|
}
|
||||||
|
|
||||||
// ================= stash 목록 =================
|
// ================= stash 목록 =================
|
||||||
|
|
||||||
@ -965,6 +1002,7 @@ namespace MergeHub.ViewModels
|
|||||||
RegisterMergeToolCommand.NotifyCanExecuteChanged();
|
RegisterMergeToolCommand.NotifyCanExecuteChanged();
|
||||||
|
|
||||||
AmendCommand.NotifyCanExecuteChanged();
|
AmendCommand.NotifyCanExecuteChanged();
|
||||||
|
OnPropertyChanged(nameof(AmendHint)); // 작업이 시작 · 끝나면 단추 설명도 바뀐다(11차 C-1)
|
||||||
LoadLastMessageCommand.NotifyCanExecuteChanged();
|
LoadLastMessageCommand.NotifyCanExecuteChanged();
|
||||||
StashApplySelectedCommand.NotifyCanExecuteChanged();
|
StashApplySelectedCommand.NotifyCanExecuteChanged();
|
||||||
StashDropSelectedCommand.NotifyCanExecuteChanged();
|
StashDropSelectedCommand.NotifyCanExecuteChanged();
|
||||||
|
|||||||
@ -391,8 +391,9 @@
|
|||||||
<Button Grid.Column="2" Content="마지막 메시지" Command="{Binding LoadLastMessageCommand}"
|
<Button Grid.Column="2" Content="마지막 메시지" Command="{Binding LoadLastMessageCommand}"
|
||||||
ToolTip="고쳐 쓰려는 메시지를 처음부터 다시 치지 않게, 마지막 커밋의 메시지를 가져옵니다"/>
|
ToolTip="고쳐 쓰려는 메시지를 처음부터 다시 치지 않게, 마지막 커밋의 메시지를 가져옵니다"/>
|
||||||
<Button Grid.Column="3" Content="커밋" Command="{Binding CommitCommand}"/>
|
<Button Grid.Column="3" Content="커밋" Command="{Binding CommitCommand}"/>
|
||||||
|
<!-- 설명은 상황에 따라 바뀐다 - 작업 중이면 왜 꺼졌는지 말한다(11차 C-1) -->
|
||||||
<Button Grid.Column="4" Content="커밋 수정" Command="{Binding AmendCommand}"
|
<Button Grid.Column="4" Content="커밋 수정" Command="{Binding AmendCommand}"
|
||||||
ToolTip="마지막 커밋을 고쳐 씁니다 (git commit --amend). 푸시하기 전에만 쓰세요"/>
|
ToolTip="{Binding AmendHint}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user