8차 B-3: MERGED 칸 줄 번호를 결과 파일 번호로
네 칸 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>
This commit is contained in:
parent
90f662ba9b
commit
2d3201cda0
@ -157,3 +157,48 @@ cherry-pick 의 BASE 제목에 꼬리가 없는 것은 맞다 — 그때 BASE
|
|||||||
### 정하지 않은 것
|
### 정하지 않은 것
|
||||||
|
|
||||||
- git 의 `--allow-empty` 처럼 **빈 cherry-pick 을 커밋으로 남기는 길**은 지시서대로 두지 않았다. 사용자와 정한 뒤에 넣는다.
|
- git 의 `--allow-empty` 처럼 **빈 cherry-pick 을 커밋으로 남기는 길**은 지시서대로 두지 않았다. 사용자와 정한 뒤에 넣는다.
|
||||||
|
|
||||||
|
## B-3. MERGED 칸 줄 번호가 결과 파일 번호가 아니다 (2026-09-16, 완료)
|
||||||
|
|
||||||
|
**정한 것 (2026-09-16, 사용자)** — 두 가지를 보이고 골랐다. ① 결과 파일 번호로(고름) ② 지금처럼 내 쪽 번호로 두고 그렇다고 적기.
|
||||||
|
결과 파일 번호는 상태바 · [이동] 칸 · 코드 검사의 "N행" 과 같은 기준이다.
|
||||||
|
|
||||||
|
### 고치기 전에 다시 났다 (새로 만든 저장소, 병합 중 `Motion/Unit0.cs` 를 네 칸으로)
|
||||||
|
|
||||||
|
충돌 6개를 Take Theirs 하면 고른 줄 · 머지 주석으로 결과가 늘어난다.
|
||||||
|
|
||||||
|
| 확인 | 값 |
|
||||||
|
|---|---|
|
||||||
|
| 상태바 | **총 3369줄** |
|
||||||
|
| [이동] 칸에 3369 | 3369행으로 감 |
|
||||||
|
| **MERGED 칸 끝 번호** | **3363** — 여섯 줄이 모자란다 |
|
||||||
|
| LOCAL (Mine) 칸 끝 번호 | 3361 (내 파일 그대로 · 맞다) |
|
||||||
|
|
||||||
|
### 원인
|
||||||
|
|
||||||
|
MERGED 칸 번호는 `MergeLine.LocalNumber` 인데, 이 값은 **정렬기가 짝지을 때 한 번 정해지고 그대로**다.
|
||||||
|
머지 주석 줄은 새로 끼워 넣으면서 번호를 주지 않았고(`Lines.Insert`), 그 뒤의 줄들도 번호를 다시 매기지 않았다.
|
||||||
|
그래서 결과가 길어질수록 어긋난다.
|
||||||
|
|
||||||
|
### 고친 것
|
||||||
|
|
||||||
|
| 파일 | 무엇 |
|
||||||
|
|---|---|
|
||||||
|
| `Services/MergedNumbering.cs` (새 파일) | `Assign(결과에 들어가는가[])` — 결과에 들어가는 줄만 1부터 센다. `Count` — 결과 줄 수 |
|
||||||
|
| `ViewModels/HomeViewModel.cs` | `RenumberMerged(rows)` — 줄 목록에 결과 번호를 다시 매긴다. 두 줄 만들기(두 칸 · 네 칸) 끝과 **요약을 그릴 때마다**(고르기 · 편집 · 되돌리기 · 주석 끼우기 뒤) 부른다 |
|
||||||
|
| 하네스 `MergeSaveTest` | 번호 검사 7건(결과에 없는 줄 · 끝 번호 = 결과 줄 수 · 빈 목록 · null 등) |
|
||||||
|
|
||||||
|
결과 파일은 `BuildLocalText` 가 `HasLocal` 인 줄만 이어 붙인 것이라, 번호도 같은 기준으로 센다.
|
||||||
|
LOCAL (Mine) 칸은 `OriginalLocalNumber`(내 파일 번호)를 그대로 쓴다 — 바꾸지 않았다.
|
||||||
|
|
||||||
|
### 확인한 것 (같은 순서로 다시)
|
||||||
|
|
||||||
|
| 확인 | 값 |
|
||||||
|
|---|---|
|
||||||
|
| 상태바 | 총 3369줄 |
|
||||||
|
| **MERGED 칸 끝 번호** | **3369** (3352 ~ 3369) |
|
||||||
|
| [이동] 칸에 3369 | 3369행 |
|
||||||
|
| **[Save] 한 뒤 워킹트리 파일** | **3369줄** — 화면 번호와 같다 |
|
||||||
|
| LOCAL (Mine) 칸 | 3346 ~ 3361 그대로 |
|
||||||
|
|
||||||
|
하네스 18벌 928건 통과(MergeSaveTest 162). 빌드 경고 0 · 오류 0. 설정 파일은 바이트 그대로 되돌림.
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
| 날짜 | 항목 | 커밋 |
|
| 날짜 | 항목 | 커밋 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
|
| 2026-09-16 | **8차 B-3** — 네 칸 MERGED 칸 줄 번호가 정렬할 때 정해진 채 굳어, 고른 줄 · 머지 주석으로 결과가 늘어도 그대로였다(끝 번호 3363 · 상태바 총 3369줄). 사용자가 "결과 파일 번호로" 를 골라, 결과에 들어가는 줄만 1부터 다시 매긴다(MergedNumbering). 줄을 만들 때와 요약을 그릴 때마다 다시 매겨 고르기 · 편집 · 되돌리기 뒤에도 맞는다. 저장된 파일 줄 수(3369)와 화면 번호가 같아짐 | 아래 |
|
||||||
| 2026-09-16 | **8차 B-2** — 이미 들어 있는 커밋을 cherry-pick 하면 [커밋] 이 켜지는데 누르면 로그에 "실패: No changes; nothing to commit." 만 남고 진행 줄도 그대로라 같은 단추를 또 누르게 됐다. 커밋할 것이 있는지(HasStagedChanges)를 상태로 들고 있다가 [커밋] 을 끄고, 진행 줄 · 적용 로그가 "가져올(되돌릴) 변경이 없습니다 - [작업 취소] 로 끝냅니다" 라고 말한다. 커밋 직전에도 사람 말로 막는다. 병합 커밋은 트리가 같아도 정상이라 걸지 않음 | 아래 |
|
| 2026-09-16 | **8차 B-2** — 이미 들어 있는 커밋을 cherry-pick 하면 [커밋] 이 켜지는데 누르면 로그에 "실패: No changes; nothing to commit." 만 남고 진행 줄도 그대로라 같은 단추를 또 누르게 됐다. 커밋할 것이 있는지(HasStagedChanges)를 상태로 들고 있다가 [커밋] 을 끄고, 진행 줄 · 적용 로그가 "가져올(되돌릴) 변경이 없습니다 - [작업 취소] 로 끝냅니다" 라고 말한다. 커밋 직전에도 사람 말로 막는다. 병합 커밋은 트리가 같아도 정상이라 걸지 않음 | 아래 |
|
||||||
| 2026-09-16 | **8차 B-1** — rebase · cherry-pick 에서 마지막 충돌을 [Save] 하면 파일 비교 탭이 "남은 차이 6줄" 로 떨어져 충돌 탭과 다른 말을 했다(7차 A-1 이 병합 전용이었고 화면도 MERGE_HEAD 기준으로 물었다). 요약 · BASE 제목을 작업 상태(GitOperationState)에 맞춰 OperationLabels 로 옮김 — 끝말은 충돌 탭 진행 줄과 같은 FinishHint, 차이 줄은 작업별로(받은 · 올린 · 가져온 · 되돌린 변경), 제목 꼬리는 병합 "병합 전 내 쪽" · rebase "올릴 자리" 등. 병합 글은 그대로 | 아래 |
|
| 2026-09-16 | **8차 B-1** — rebase · cherry-pick 에서 마지막 충돌을 [Save] 하면 파일 비교 탭이 "남은 차이 6줄" 로 떨어져 충돌 탭과 다른 말을 했다(7차 A-1 이 병합 전용이었고 화면도 MERGE_HEAD 기준으로 물었다). 요약 · BASE 제목을 작업 상태(GitOperationState)에 맞춰 OperationLabels 로 옮김 — 끝말은 충돌 탭 진행 줄과 같은 FinishHint, 차이 줄은 작업별로(받은 · 올린 · 가져온 · 되돌린 변경), 제목 꼬리는 병합 "병합 전 내 쪽" · rebase "올릴 자리" 등. 병합 글은 그대로 | 아래 |
|
||||||
| 2026-09-16 | **8차 A-1** — 파일 비교 탭을 처음 여는 것이 [3분할로 열기] 면 고른 파일 대신 첫 충돌 파일이 보였고, 그 화면을 [Save] 하면 **고른 파일에 그 내용이 써졌다**(Unit47 이 Unit15 내용으로 스테이징). 탭을 만들 때의 목록 세우기와 고른 파일 열기가 겹쳐, 늦게 끝난 읽기가 화면을 덮은 것. 읽기는 경로 · 커밋이 바뀌었으면 버리고 한 번 더 읽게, 쓰기(저장 · Save & Commit · 파일 지우기/남기기)는 화면에 실린 파일과 다르면 아무것도 쓰지 않게 했다. 네 길 모두 고른 파일이 열리고 저장이 그 파일에만 감, 병합은 사람 순서 그대로 끝까지(줄끝 0/33 · 내용 검사 0) | 아래 |
|
| 2026-09-16 | **8차 A-1** — 파일 비교 탭을 처음 여는 것이 [3분할로 열기] 면 고른 파일 대신 첫 충돌 파일이 보였고, 그 화면을 [Save] 하면 **고른 파일에 그 내용이 써졌다**(Unit47 이 Unit15 내용으로 스테이징). 탭을 만들 때의 목록 세우기와 고른 파일 열기가 겹쳐, 늦게 끝난 읽기가 화면을 덮은 것. 읽기는 경로 · 커밋이 바뀌었으면 버리고 한 번 더 읽게, 쓰기(저장 · Save & Commit · 파일 지우기/남기기)는 화면에 실린 파일과 다르면 아무것도 쓰지 않게 했다. 네 길 모두 고른 파일이 열리고 저장이 그 파일에만 감, 병합은 사람 순서 그대로 끝까지(줄끝 0/33 · 내용 검사 0) | 아래 |
|
||||||
|
|||||||
@ -207,7 +207,7 @@
|
|||||||
|---|---|
|
|---|---|
|
||||||
| **완료** | B-1 rebase · cherry-pick 에서 마지막 저장 뒤 "남은 차이" 가 뜬다 — 요약 · BASE 제목이 작업(병합 · rebase · cherry-pick · revert)을 따른다. rebase 는 "충돌 정리 끝 · [계속] 으로 rebase 를 이어 갑니다 · 올릴 자리 대비 올린 변경 N줄" · 제목 "올릴 자리". 병합 글은 그대로 |
|
| **완료** | B-1 rebase · cherry-pick 에서 마지막 저장 뒤 "남은 차이" 가 뜬다 — 요약 · BASE 제목이 작업(병합 · rebase · cherry-pick · revert)을 따른다. rebase 는 "충돌 정리 끝 · [계속] 으로 rebase 를 이어 갑니다 · 올릴 자리 대비 올린 변경 N줄" · 제목 "올릴 자리". 병합 글은 그대로 |
|
||||||
| **완료** | B-2 바뀌는 것 없는 cherry-pick 에서 [커밋] 이 켜지고 누르면 실패한다 — 커밋할 것이 없으면 [커밋] 이 꺼지고 진행 줄 · 로그가 "가져올 변경이 없습니다 - [작업 취소] 로 끝냅니다". 병합 커밋은 그대로(트리가 같아도 정상). `--allow-empty` 는 사용자와 정한 뒤 |
|
| **완료** | B-2 바뀌는 것 없는 cherry-pick 에서 [커밋] 이 켜지고 누르면 실패한다 — 커밋할 것이 없으면 [커밋] 이 꺼지고 진행 줄 · 로그가 "가져올 변경이 없습니다 - [작업 취소] 로 끝냅니다". 병합 커밋은 그대로(트리가 같아도 정상). `--allow-empty` 는 사용자와 정한 뒤 |
|
||||||
| 대기 | B-3 MERGED 칸 줄 번호가 결과 파일 번호가 아니다 (먼저 사용자와 정함) |
|
| **완료** | B-3 MERGED 칸 줄 번호가 결과 파일 번호가 아니다 — 사용자가 "결과 파일 번호로" 를 고름(2026-09-16). 결과에 들어가는 줄만 1부터 다시 매긴다. 끝 번호 3363 → 3369 로 상태바 · [이동] 칸 · 저장된 파일(3369줄)과 같아짐 |
|
||||||
|
|
||||||
### C. 7차에서 남긴 것
|
### C. 7차에서 남긴 것
|
||||||
|
|
||||||
|
|||||||
42
src/MergeHub/Services/MergedNumbering.cs
Normal file
42
src/MergeHub/Services/MergedNumbering.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MergeHub.Services
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// MERGED 칸(네 칸의 결과)에 매길 줄 번호(8차 B-3).
|
||||||
|
///
|
||||||
|
/// <b>따로 뺀 까닭</b> - 예전에는 번호를 정렬기가 준 대로 두었다. 줄을 고르거나 머지 주석이 끼어들어
|
||||||
|
/// 결과 줄이 늘어도 다시 매기지 않아, MERGED 칸 끝 번호(3363)와 상태바 줄 수(3366)가 어긋났다.
|
||||||
|
/// 사용자가 결과 파일 번호로 맞추기로 정했다(2026-09-16) - 상태바 · [이동] 칸 · 코드 검사의 "N행" 과 같은 번호다.
|
||||||
|
///
|
||||||
|
/// 결과 파일은 <b>결과에 들어가는 줄만</b> 차례로 이어 붙인 것이다(BASE 에만 있던 줄은 빠진다).
|
||||||
|
/// 그래서 번호도 그 줄만 1부터 센다.
|
||||||
|
/// </summary>
|
||||||
|
public static class MergedNumbering
|
||||||
|
{
|
||||||
|
/// <summary>행마다 "결과 파일에 들어가는가" 를 받아 번호를 돌려준다. 들어가지 않는 행은 null.</summary>
|
||||||
|
public static int?[] Assign(IReadOnlyList<bool> inResult)
|
||||||
|
{
|
||||||
|
if (inResult is null) return Array.Empty<int?>();
|
||||||
|
|
||||||
|
var numbers = new int?[inResult.Count];
|
||||||
|
var n = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < inResult.Count; i++)
|
||||||
|
numbers[i] = inResult[i] ? ++n : (int?)null;
|
||||||
|
|
||||||
|
return numbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>결과 파일의 줄 수. 상태바가 말하는 "총 N줄" 과 같아야 한다.</summary>
|
||||||
|
public static int Count(IReadOnlyList<bool> inResult)
|
||||||
|
{
|
||||||
|
if (inResult is null) return 0;
|
||||||
|
|
||||||
|
var n = 0;
|
||||||
|
foreach (var yes in inResult) if (yes) n++;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1529,6 +1529,7 @@ namespace MergeHub.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
RefreshBlockCommentState(rows);
|
RefreshBlockCommentState(rows);
|
||||||
|
RenumberMerged(rows); // MERGED 칸은 결과 파일 번호로(8차 B-3)
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1595,6 +1596,7 @@ namespace MergeHub.ViewModels
|
|||||||
|
|
||||||
MarkMoves(aligned, rows);
|
MarkMoves(aligned, rows);
|
||||||
RefreshBlockCommentState(rows);
|
RefreshBlockCommentState(rows);
|
||||||
|
RenumberMerged(rows); // MERGED 칸은 결과 파일 번호로(8차 B-3)
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3417,6 +3419,9 @@ namespace MergeHub.ViewModels
|
|||||||
|
|
||||||
private void UpdateSummaries()
|
private void UpdateSummaries()
|
||||||
{
|
{
|
||||||
|
// 줄을 고르거나 머지 주석이 끼어들면 결과 줄 수가 바뀐다. 그릴 때마다 번호를 다시 매긴다(8차 B-3).
|
||||||
|
RenumberMerged(Lines);
|
||||||
|
|
||||||
var total = Lines.Count;
|
var total = Lines.Count;
|
||||||
var diff = Lines.Count(l => l.IsDifferent);
|
var diff = Lines.Count(l => l.IsDifferent);
|
||||||
|
|
||||||
@ -3756,6 +3761,23 @@ namespace MergeHub.ViewModels
|
|||||||
SaveResolvedCommand.NotifyCanExecuteChanged();
|
SaveResolvedCommand.NotifyCanExecuteChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// MERGED 칸 번호를 <b>결과 파일 번호</b>로 다시 매긴다(8차 B-3).
|
||||||
|
///
|
||||||
|
/// 줄을 고르거나 머지 주석이 끼어들면 결과 줄 수가 바뀐다. 정렬기가 준 번호를 그대로 두면
|
||||||
|
/// 끝 번호가 상태바의 "총 N줄" 과 어긋났다. 결과에 들어가는 줄(<see cref="MergeLine.HasLocal"/>)만 1부터 센다.
|
||||||
|
/// </summary>
|
||||||
|
private static void RenumberMerged(IList<MergeLine> rows)
|
||||||
|
{
|
||||||
|
if (rows is null || rows.Count == 0) return;
|
||||||
|
|
||||||
|
var inResult = new bool[rows.Count];
|
||||||
|
for (var i = 0; i < rows.Count; i++) inResult[i] = rows[i].HasLocal;
|
||||||
|
|
||||||
|
var numbers = MergedNumbering.Assign(inResult);
|
||||||
|
for (var i = 0; i < rows.Count; i++) rows[i].LocalNumber = numbers[i];
|
||||||
|
}
|
||||||
|
|
||||||
private string BuildLocalText()
|
private string BuildLocalText()
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user