단계와 충돌 표시
5. 단계
앞의 것이 없으면 뒤의 것을 확인할 수 없는 순서입니다.
| 단계 | 무엇 | 쓰기 | 크기 | 게이트 |
|---|---|---|---|---|
| 1 | --diff — 워크북 2개의 표 단위 차이 | 없음 | 작음 | 됨 — §5.1 |
| 2 | 3-way 판정과 충돌 보고 | 없음 | 중간 | 됨 — §5.2 |
| 3 | 셀 값 쓰기 | 셀 값만 | 중간 | 됨 — §5.3 |
| 4 | 행 추가·삭제 | 행 | 큼 | 됨 — §5.4 |
| 5 | SCM 연동 — git 병합 드라이버 | — | 중간 | 됨 — §5.5 |
| 6 | 충돌을 보는 페이지 | — | 작음 | 됨 — §6 |
5.1 1단계 — 됨
tools/mabbit/에 --diff가 있습니다. 격자 읽기는 SheetGridReader를 그대로 쓰고, 표는
HeuristicSchema가 정하며(§4.2), 행은 키로 정합합니다. 보고는 변경마다 셀 주소를 함께
냅니다(Item!C2). 게이트는 MabbitDiffTests 15개입니다.
구현 중에 확인된 것 3가지입니다.
| 무엇 | 결과 |
|---|---|
| 확장자 없는 임시 파일(§8에 미결로 두었던 것) | 해소되었습니다. SheetGridReader.Open이 형식을 확장자에서만 판정하고 있었고, 형식을 지정하는 이름을 따로 받는 매개변수를 더했습니다. 게이트가 확장자 없는 사본을 실제로 거부하고 --path가 주는 이름으로는 읽는 것을 확인합니다 |
| 주석을 차이로 계산하던 것 | 중복 키와 키 없는 행은 한쪽 파일의 성질이지 두 파일의 차이가 아닙니다. 처음에는 그것들이 테이블을 「변경됨」으로 만들어, 워크북을 자기 자신과 비교해도 표 1개가 변경으로 보고되었습니다. 보고의 별도 구역으로 옮겼습니다 — 실제 샘플로 끝단을 돌려 보고 나서야 드러난 것입니다 |
HeuristicSchema의 한계가 실물에서 보이는 것 | 샘플 워크북의 참고용 시트는 키 있는 표가 아니어서 주석이 195건 나옵니다. 결손이 아니라 recipe 없이 동작할 때의 정확한 상태이고, RecipeSchema가 필요한 이유가 그것입니다 |
| 첫 시트를 건너뛰던 것 | 리더는 생성 시점에 이미 첫 시트에 있으므로 첫 호출이 이동하면 안 됩니다. 시트가 20개인 워크북에서는 보이지 않고 1개인 워크북에서는 전부입니다. 픽스처를 .xlsx·.xlsb 두 개로 둔 덕분에 잡혔습니다 |
5.2 2단계 — 됨
--merge가 워크북 3개를 받아 판정하고 보고합니다. 파일은 쓰지 않습니다 — --result를
주면 거부합니다. 그것을 주는 사람은 병합 드라이버로 등록하는 중이고, 결과를 쓰지 않으면서
성공을 보고하는 드라이버는 하루치 작업이 사라지는 경로입니다.
| 무엇 | 내용 |
|---|---|
| 판정 | §4.3의 셀 규칙, §4.4의 행·컬럼·테이블 규칙, §4.5의 표 밖 지문 |
| 충돌 보고 | 셋을 한 줄씩 함께 냅니다 — base · mine · theirs와 셀 주소. 어느 것이 맞는지는 사람의 판단이고, 손대기 전의 값을 못 보면 그 판단이 안 됩니다 |
| 종료 코드 | 0 완료 · 1 충돌 있음 · 2 실행 불가 |
| 게이트 | 판정표의 전 항목을 하나씩. 표 밖 4가지 포함. 41개 |
표 밖의 변경은 「상대만 고쳤어도」 충돌입니다. §4.6이 표 사각형 안만 쓰기로 정했으므로 그 변경은 옮길 수 없고, 옮기지 못하는 것을 성공으로 보고하면 조용한 소실이 됩니다.
판정 코드에서 한 자리를 고쳤습니다 — 세 경우(base 대 mine · base 대 theirs · mine 대 theirs) 를 불리언 인자 2개로 가르고 있었는데, 틀리게 넘겨도 조용히 틀리는 자리여서 이름 있는 함수 3개로 갈랐습니다.
5.3 3단계 — 됨
--result를 주면 mine의 패키지를 복사하면서 해당 시트 파트만 다시 씁니다. 나머지 파트는
바이트로 통과합니다.
| 무엇 | 내용 |
|---|---|
| 보존 | 게이트가 바이트 동일을 확인합니다. 픽스처가 주석·도형·vml·테마·스타일을 갖고 있어서, 라이브러리로 열었다 저장했으면 사라졌을 것들이 그대로 있는지 실제로 대조됩니다 |
| 새 문자열 | t="inlineStr". 공유 문자열 테이블에 항목을 더하면 다른 시트가 참조하는 인덱스가 밀립니다 |
| 숫자 | 왕복하는 경우에만 숫자로 씁니다. 텍스트로 쓰면 다음 비교가 스스로 만든 차이를 봅니다 |
| 수식 셀 | 값을 쓰지 않고 거부합니다. 다음 재계산에서 되돌아가기 때문입니다 |
| 재계산 | xl/calcChain.xml을 버리고 fullCalcOnLoad를 켭니다 |
dimension·spans | 지웁니다. 셀을 하나 넣으면 둘 다 거짓이 되고, 없으면 스프레드시트가 다시 셉니다 |
| 원자성 | 임시 이름으로 쓰고 옮깁니다. 중간에 실패한 실행이 반쪽 워크북을 남기지 않습니다 |
쓸 수 없는 것은 쓰지 않고 이유를 댑니다. 충돌이 남아 있거나, 행·컬럼·테이블이 오가야 하거나,
.xlsb이면 거부하고 무엇 때문인지 줄마다 적습니다. .xlsb는 확장자가 아니라 패키지 안쪽으로
판정합니다 — .xlsb도 zip이라 PK 검사로는 갈리지 않고, 안이 xl/workbook.bin인 것으로
가릅니다. 게이트가 이것을 검출하였습니다.
엑셀이 실제로 여는지는 자동으로 확인하지 못합니다. 게이트가 하는 것은 되읽기와 바이트 대조까지입니다.
5.4 4단계 — 됨, 다만 예상과 다른 방법으로
행 삭제에 새 기계 장치가 필요하지 않았습니다. 행을 잘라내는 대신 표 사각형 안의 셀을 비웁니다. 잘라내면 아래 행이 전부 올라오고 병합된 범위·정의된 이름·그곳을 가리키는 수식이 함께 따라와야 하는데, 표 안에서 빈 행은 리더가 건너뛰므로 데이터는 어느 쪽이든 같습니다. 비용이 큰 절반을 치르지 않고 같은 결과에 도달합니다.
행 추가는 표 아래에 덧붙입니다. 정렬해 끼워 넣지 않습니다 — 행의 자리는 사람이 정한 것이고 병합이 그것에 투표할 권한은 없습니다. 덧붙일 자리에 무엇이 있으면 거부하고 그 셀 주소를 댑니다.
패처 쪽도 일반화 하나로 끝났습니다 — 시트에 없는 행 번호의 셀 편집이 들어오면 그 행을 만 듭니다. 행 삽입 전용 경로가 따로 없고, 행은 오름차순이어야 하므로 스트림에서 그 번호에 도달하는 지점에 씁니다.
5.5 5단계 — 됨
실제 git이 실제 저장소에서 병합합니다. 게이트가 저장소를 만들고 드라이버를 등록한 뒤
브랜치 둘에서 각각 수정하고 git merge를 돌립니다.
| 확인하는 것 |
|---|
| 서로 다른 행을 고친 두 사람의 병합이 종료 코드 0으로 끝나고, 결과 파일에 양쪽 수정이 다 있는 것 |
| 같은 셀을 고쳤을 때 0이 아닌 코드로 끝나 git이 충돌로 표시하고, 이쪽 파일이 반쯤 병합된 상태로 남지 않는 것 |
git이 넘기는 확장자 없는 임시 파일이 --path 없이는 거부되고 있으면 읽히는 것 |
여기서 실제 결함이 하나 나왔습니다. git은 --result를 --mine과 같은 경로로 줍니다.
읽기용으로 연 패키지를 닫기 전에 결과를 옮기고 있었고, 윈도우에서는 그 이동이 실패합니다.
문서만 읽어서는 나오지 않는 종류이고, 통합 게이트가 있어야 나오는 자리입니다.
5.6 4단계가 큰 이유
행 추가는 그 아래 행들의 위치를 이동시킵 니다. 이동에 함께 따라와야 하는 것이 셋입니다 — 정의된 이름의 참조 범위, 병합된 셀의 범위, 그 영역을 가리키는 수식과 조건부 서식.
그래서 4단계는 아래가 비어 있을 때만 추가하는 것에서 시작합니다. 표 사각형 아래에 다른 내용이 있으면 충돌로 보고합니다. 레이아웃 문서가 이미 엔티티 사이를 한 칸 이상 띄우도록 규정하고 있으므로 이 제한에 걸리는 배치는 많지 않을 것으로 보이나, 미측정입니다 — 3단계를 마친 뒤 샘플 워크북에서 실측하여 시프트 구현이 필요한지, 필요하다면 §4.6의 라이브러리 도입이 그 대안인지 결정합니다.
6. 충돌을 보는 페이지 — 됨
--format html이 브라우저로 열 페이지를 냅니다. UI 프레임워크를 도입하지 않았습니다 —
2단계가 산출한 충돌의 형태를 보고 나니, 필요한 것이 값 3개를 나란히 놓는 것이었기
때문입니다. 터미널에서는 그 세 줄이 나머지와 같은 크기인데, 페이지에서는 그것이 화면의
주인공이 되고 병합기가 알아서 처리한 것은 아래로 접힙니다.
| 성질 | 근거 |
|---|---|
| 파일 하나. 스타일시트도 스크립트도 폰트도 이미지도 없습니다 | 무엇이든 가져오는 페이지는 닫힌 망에서 열리지 않는 페이지입니다. 게이트가 http와 <script가 없 는 것을 확인합니다 |
| 밝은 화면·어두운 화면 둘 다 | 한밤중에 충돌을 푸는 사람에게 흰 화면이 하나 더 얹히지 않게 합니다 |
| 값은 텍스트로 | 마크업이 든 셀 값이 요소가 되지 않도록 이스케이프합니다. 게이트가 확인합니다 |
브라우저에서 실제로 어떻게 보이는지는 확인하지 않았습니다. 게이트가 하는 것은 구조와 자립성까지입니다.