형상과 변경 기준선
요구, 코드, 테스트, 실행 안내를 형상 항목으로 함께 식별하고, 검토를 마친 구성을 기준선으로 정합니다. 변경 통제, 상태 기록, 형상 감사의 역할을 구별하고, 버전 관리 도구가 도와주는 범위와 도와주지 못하는 범위를 정리합니다.
코드는 마감 뒤에도 취소를 받는데, 설명서에는 마감 뒤 취소가 금지라고 적혀 있습니다. 두 파일이 모두 있더라도 같은 버전의 제품을 설명한다고 볼 수는 없습니다. 소프트웨어를 이루는 구성 요소와 그 변경을 식별하고, 통제하고, 기록하고, 확인하는 활동을 형상 관리(configuration management)라고 합니다. 이 글에서는 무엇을 함께 관리해야 하는지 정하고, 변경이 기준선 사이를 어떻게 지나가는지 따라가 봅니다.
형상 항목과 기준선
형상 관리의 대상으로 고른 코드, 요구, 테스트, 설정, 문서를 형상 항목(configuration item)이라고 합니다. 그리고 검토를 마친 형상 항목들의 구성을 특정 시점의 기준으로 확정한 것을 기준선(baseline)이라고 합니다. 기준선은 더 이상 바꿀 수 없는 상태가 아니라, 그 뒤의 변경을 정해진 절차로 비교하고 관리할 출발점입니다.
모임 앱의 기준선에는 요구 R1–R6의 정책, core.mjs, core.test.mjs, 실행과 저장에 대한 안내를 함께 넣어 식별합니다. 버전 관리 도구의 커밋 번호가 있더라도, 그 시점에 어떤 정책이 받아들여졌고 어떤 확인을 거쳤는지가 함께 기록되어 있지 않다면 업무의 기준선으로는 부족할 수 있습니다.
기준선 사이의 변경을 요구와 검증으로 통제한다
현재 구성과 안내의 문제를 식별한다. 문구와 요구 설명의 일치를 확인한다. 각 단계의 값과 전환 이유를 비교합니다.
SOFTWARE ENGINEERING · READING CLUB
기준선 사이의 변경을 요구와 검증으로 통제한다
정책·코드·테스트·안내가 같은 버전을 가리키는지 확인합니다.
커밋은 파일 구성을 식별하는 수단입니다. 업무 승인·테스트 성공·배포 성공을 자동으로 증명하지 않습니다.
이 예의 조건
- 본문과 전체 도표의 예를 따라 v1과 문제부터 v2 검증까지 진행합니다.
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| v1과 문제 현재 구성과 안내의 문제를 식별한다. |
|
|
| 영향과 결정 CLOSED 유지 정책에 맞는 변경을 결정한다. |
|
|
| v2 검증 문구와 요구 설명의 일치를 확인한다. |
|
|
기준선 사이의 변경을 요구와 검증으로 통제한다
현재 구성과 안내의 문제를 식별한다. 문구와 요구 설명의 일치를 확인한다. 각 단계의 값과 전환 이유를 비교합니다.
SOFTWARE ENGINEERING · READING CLUB
기준선 사이의 변경을 요구와 검증으로 통제한다
정책·코드·테스트·안내가 같은 버전을 가리키는지 확인합니다.
커밋은 파일 구성을 식별하는 수단입니다. 업무 승인·테스트 성공·배포 성공을 자동으로 증명하지 않습니다.
이 예의 조건
- 본문과 전체 도표의 예를 따라 v1과 문제부터 v2 검증까지 진행합니다.
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| v1과 문제 현재 구성과 안내의 문제를 식별한다. |
|
|
| 영향과 결정 CLOSED 유지 정책에 맞는 변경을 결정한다. |
|
|
| v2 검증 문구와 요구 설명의 일치를 확인한다. |
|
|
변경 통제, 상태 기록, 형상 감사
그림처럼 변경은 문제를 찾는 데서 시작해, 영향을 분석하고 결정한 뒤, 새 기준선을 확인하는 데서 끝납니다. 이 과정에는 세 가지 활동이 들어갑니다. 변경 통제(change control)는 변경 요청의 이유, 영향, 승인할 사람을 확인하고 적용할지를 결정하는 활동입니다. 상태 기록(status accounting)은 각 요청이 검토 중인지, 적용 중인지, 확인 중인지를 남기는 활동이고, 형상 감사(configuration audit)는 실제 구성이 기록과 일치하며 정한 절차와 요구를 만족하는지 확인하는 활동입니다.
형상 감사에서 파일이 있는지 확인하는 것만으로 내용의 뜻까지 확인했다고 할 수는 없습니다. 변경 요청은 다음과 같이 이유, 영향, 결정, 적용한 버전, 확인 방법을 함께 기록합니다.
변경 번호: CH-03
이유: 마감 뒤 취소 안내를 사용자가 모집 재개로 잘못 이해함.
영향: 안내 문구, R6 설명, 마감 뒤 취소의 인수 사례.
결정: 마감 상태를 유지하는 정책에 맞추어 안내를 고친다.
적용한 버전: 코드와 문서의 식별자를 함께 적는다.
확인: 자동 회귀 테스트와 사용자 안내 검토를 각각 기록한다.버전 관리 도구가 도와주는 범위
Git 같은 버전 관리 도구(version control system)는 파일의 변경 내용과 이력을 추적합니다. 다음 명령은 저장소에서 바뀐 파일의 목록과 core.mjs의 변경 내용을 읽기만 하는 예이며, 직접 만든 reading-lab이 Git 저장소가 아니라면 실행하지 않아도 됩니다.
git status --short
git diff -- core.mjs브랜치(branch)는 변경의 흐름을 나누어 따로 작업하게 하고, 병합(merge)은 나뉜 변경을 다시 합칩니다. 그런데 Git이 충돌 없이 자동으로 병합했다고 요구의 충돌까지 사라지는 것은 아닙니다. 예를 들어 한 브랜치는 core.mjs에서 정원 검사를 중복 검사보다 앞으로 옮기고, 다른 브랜치는 요구 표의 R3 설명에 정원이 찬 모임에서도 중복을 먼저 거절한다는 예를 더했다고 해 봅시다. 두 브랜치는 서로 다른 파일을 고쳤으므로 Git은 충돌 없이 병합하지만, 병합한 코드와 요구 표는 서로 다른 정책을 따릅니다. 그래서 병합한 뒤에는 회귀 테스트를 실행하고 문서와 코드가 맞는지 다시 확인합니다.
버전의 이름과 내용의 같음을 확인하는 것도 다른 일입니다. 동시 저장과 복구에서 본 SHA-256 해시는 두 파일의 내용이 같은지 확인하는 데 쓸 수 있지만, 누가 그 내용을 승인했는지나 믿을 만한지까지 알려 주지는 않습니다. 해시가 정확히 맞는 파일에도 결함은 있을 수 있습니다.
더 깊이: Git의 커밋 번호는 내용에서 계산한다
Git이 커밋을 가리킬 때 쓰는 40자리 16진수는 차례로 붙인 번호가 아니라, 그 커밋의 내용을 해시 함수에 넣어 계산한 값입니다. 커밋에는 파일 트리, 부모 커밋, 작성자, 메시지가 들어 있으므로, 이 가운데 하나만 바뀌어도 번호가 달라지고, 번호가 같다면 그 커밋까지의 이력이 같다고 볼 수 있습니다. Git은 처음부터 이 계산에 SHA-1을 써 왔는데, Git 문서의 해시 함수 전환 설계는 2017년 2월의 SHAttered 공격이 SHA-1의 충돌을 실제로 만들어 보였고, Git 2.13.0부터는 이 공격에 걸리지 않도록 보강한 SHA-1을 기본으로 쓴다고 설명합니다.
그래서 Git은 SHA-256으로 옮겨 가는 중입니다. git init --object-format=sha256으로 SHA-256 저장소를 만들 수 있지만, git-init 문서에 따르면 지금은 SHA-1 저장소와 서로 오가며 쓸 수 없고 기본값은 여전히 SHA-1입니다. Git 프로젝트가 공개한 변경 예정 목록은 Git 3.0에서 새 저장소의 기본 해시를 SHA-256으로 바꾸겠다고 밝히며, 그 전제로 라이브러리와 저장소 호스팅 서비스 같은 생태계가 준비되어야 한다고 적습니다. 2026년 11월 현재 Git의 최신판은 2.56.0이므로, 이 변경은 아직 예정입니다.
정리
- 형상 관리는 소프트웨어의 구성 요소와 변경을 식별하고, 통제하고, 기록하고, 확인하는 활동입니다.
- 형상 항목에는 코드뿐 아니라 요구, 테스트, 설정, 문서가 들어가며, 기준선은 검토를 마친 구성을 이후 변경의 출발점으로 확정한 것입니다.
- 변경 통제는 적용 여부를 결정하고, 상태 기록은 요청의 진행 상태를 남기며, 형상 감사는 실제 구성과 기록이 맞는지 확인합니다.
- 버전 관리 도구는 파일의 차이와 이력을 추적하지만, 자동 병합이 성공해도 요구의 충돌은 남을 수 있습니다.
- 해시는 내용이 같은지 확인할 뿐, 승인이나 내용의 옳음을 알려 주지 않습니다.
연습 문제
1. 코드는 그대로이고 문서만 바뀔 때
마감 정책의 설명을 고쳤는데, 코어는 원래부터 정책대로 동작하고 있었습니다. 코드의 커밋만 기준선이라고 생각한 팀이 이 변경을 릴리스 기록에서 빼려고 합니다. 관리 대상과 확인 방법을 어떻게 정해야 할까요?
해설 보기
설명서와 안내 문구도 형상 항목이므로, 새 기준선과 변경 요약에 이 수정을 넣어야 합니다. 코어의 동작은 회귀 테스트로 그대로인지 확인하고, 고친 문구가 R6과 맞는지는 따로 검토합니다. 코드에 차이가 없다고 해서 사용자가 이해하는 제품의 동작이 바뀌지 않은 것은 아니므로, 고친 문서를 어느 릴리스부터 제공하는지도 식별해 둡니다.
2. 충돌 없이 병합된 두 변경
한 개발자는 결과 코드를 화면 안내로 바꾸는 messages의 문구를 고쳤고, 다른 개발자는 register의 정원 검사를 중복 검사보다 앞으로 옮겼습니다. 두 브랜치는 서로 다른 줄을 고쳤기 때문에 Git이 충돌 없이 병합했습니다. 병합한 뒤에 무엇을 확인해야 하나요?
해설 보기
정원 검사를 앞으로 옮긴 변경은 정원이 찬 모임에 이미 신청한 사람이 다시 신청할 때의 결과를 ALREADY_REGISTERED에서 FULL로 바꾸어 요구 R3을 어깁니다. 문법상의 충돌이 없었으므로 이 정책의 충돌은 병합 과정에서 드러나지 않습니다. 병합한 뒤에 회귀 테스트를 실행하면 R3 사례가 실패해 문제를 찾을 수 있고, 정책을 정말 바꾸려는 것이었다면 요구 표와 안내 문구, 테스트를 함께 바꾸는 별도의 변경 요청으로 다루어야 합니다.
3. 기준선에 무엇을 넣을까
모임 앱의 첫 기준선을 만들려고 합니다. 다음 가운데 형상 항목으로 넣을 것을 고르고 이유를 적으세요. ㉠ core.mjs ㉡ core.test.mjs ㉢ 요구 표 R1–R6 ㉣ 개발자 개인의 편집기 색 설정 ㉤ 실행 방법 안내
해설 보기
㉠, ㉡, ㉢, ㉤을 넣습니다. 코드와 테스트, 요구 표, 실행 안내는 함께 바뀌어야 서로 맞으며, 하나만 바뀌면 이 글의 처음처럼 코드와 설명이 서로 다른 버전을 가리키게 됩니다. ㉣은 개발자 개인의 환경일 뿐 제품의 동작이나 사용 방법에 영향을 주지 않으므로 형상 항목으로 관리할 필요가 없습니다. 다만 코드의 형식을 맞추는 포매터 설정처럼 팀 전체가 따라야 하는 설정이라면 형상 항목에 넣습니다.
기준선을 준비했다면 이제 그 구성을 사용자에게 전달하고, 문제가 생겼을 때 되돌릴 수 있어야 합니다. 다음 글 릴리스·복구·운영 피드백에서는 전달을 준비하고 백업에서 되살리는 과정을 실행해 봅니다.