이 글의 위치: 영어(English) → 어원(Etymology) → 개발 영어(Developer English)
시리즈 hub: 원래 다섯 편의 낱말 카드로 나눠 쓰려던 것을 한 페이지로 묶어 다시 정리했다. 이유는 아래 첫 절에 적었다.
어원은 Online Etymology Dictionary · Cambridge Dictionary 로 교차 확인한 것만 실었고, 개발 맥락 해석은 내 판단이라 그렇게 표시했다. 작성 기준은 Editorial Policy 참조.
왜 다섯 편이 아니라 한 편인가
처음에는 단어마다 카드 한 장씩 쓸 생각이었다. deploy 카드를 쓰고, 다음 날 commit 카드를 쓰고, 그다음 compile… 그렇게 초안을 다섯 개까지 만들고 나서 다시 읽어보니 문제가 보였다. 다섯 편이 전부 같은 골격이었다. 어원 분해 → 뿌리 가족 → 개발에서의 쓰임 → 예문. 단어만 갈아 끼운 같은 글을 다섯 번 쓰고 있었다.
그리고 더 중요한 걸 놓치고 있었다. 이 다섯 단어는 따로 놓였을 때보다 나란히 놓였을 때 훨씬 잘 읽힌다. 다섯이 전부 하나의 파이프라인 위에 순서대로 놓여 있기 때문이다.
compile → commit → deploy → migrate → deprecate
그러모아 맡겨 펼쳐 거처를 그만 쓰길
쌓고 보내고 널고 바꾸고 빈다
코드를 한 덩어리로 그러모으고(compile), 그 변경을 이력에 맡겨 보내고(commit), 접혀 있던 걸 프로덕션에 펼치고(deploy), 데이터가 살 자리를 바꾸고(migrate), 낡은 것은 그만 쓰기를 빈다(deprecate). 개발 파이프라인의 각 단계 이름이 사실은 다섯 개의 서로 다른 물리적 동작에서 왔다. 그래서 한 페이지로 묶는다.
한 장 요약
| 단어 | 라틴어 뿌리 | 원래 뜻 | 개발에서의 자리 |
|---|---|---|---|
| compile | com-(함께) + pilare(눌러 쌓다) |
여기저기서 그러모아 한 더미로 쌓다 | 흩어진 소스를 하나의 산출물로 |
| commit | com-(함께) + mittere(보내다) |
함께 보내 맞붙여 맡기다 | 변경을 되돌릴 수 없게 확정 |
| deploy | dis-(흩어) + plicare(접다) |
접힌 것을 펼쳐 자리에 널다 | 산출물을 프로덕션에 전개 |
| migrate | *mei-(바꾸다) → migrare |
살던 거처를 바꿔 옮겨가다 | 스키마·데이터를 새 구조로 |
| deprecate | de-(물리쳐) + precari(빌다) |
그것이 오지 않기를 빌어 물리치다 | 폐기 예고 — 아직 죽이진 않음 |
마지막 칸이 이 글의 목적지다. 아래에서 하나씩, 왜 하필 그 단어가 그 자리에 앉게 됐는지를 본다.
1. compile — 그러모아 눌러 쌓다
compile
└── 라틴어 compilare (여기저기서 그러모으다)
├── com- (함께, 한데)
└── pilare (눌러 쌓다) ← 명사 pila(기둥·더미)와 한 뿌리
= "흩어진 것을 한데 그러모아 눌러 쌓다"
핵심은 pilare(눌러 쌓다)다. 여기서 나온 명사 pila가 "기둥·돌더미"를 뜻하고, 영어 pile(더미)이 바로 그 후손이다. 그러니 compile은 어원 그대로 "여러 데서 긁어모아 한 더미로 쌓는" 행위다. 로마 시대의 compilare에는 "남의 것을 긁어모아 약탈하다"는 뉘앙스까지 있었다. 여기저기서 모은다는 감각이 그만큼 강했던 탓이다.
나는 이 단어를 오래 "compile = 번역"으로만 외웠는데, 뿌리를 알고 나니 오히려 흩어진 소스 파일을 한데 그러모으는 일이 먼저 떠오른다.
pile 가족 — pile(쌓은 더미) · compiler(그러모아 번역하는 것) · compilation(모음집) · pillage(긁어모아 약탈).
음악의 "컴필레이션 앨범"과 코드의 "컴파일"이 같은 단어라는 게 처음엔 낯설다. 그런데 뿌리로 보면 완전히 같다. 컴필레이션 앨범은 흩어진 곡을 한 판에 그러모아 엮은 것이고, 컴파일은 여러 .c·.ts 파일을 한 실행물로 그러모아 엮는 것이다.
실무 문장 하나. 코드 리뷰에서 하루에도 몇 번씩 듣는 말이 있다.
"The code won’t compile because of a missing semicolon."
세미콜론이 빠져서 코드가 컴파일되지 않는다.
"won’t run(안 돈다)"이 아니라 "won’t compile(안 쌓인다)"인 이유가 어원에 있다. 실행 이전에, 애초에 한 무더기로 엮이는 단계에서 막힌 것이다. compile-time 오류와 runtime 오류를 굳이 나눠 부르는 이유도 여기 있다고 본다. 전자는 쌓다가 막힌 것이고, 후자는 다 쌓아 돌리다 터진 것이다.
헷갈리는 이웃. 나는 "더미의 크기"로 정리한다. compile은 소스 더미를 실행물로, build는 그 결과까지 포함한 더 큰 배포 가능 더미로, transpile(trans + compile)은 소스에서 또 다른 소스로 옮긴다. interpret는 아예 더미를 안 쌓고 그 자리에서 읽어 실행하니 이름 그대로 "풀이"에 가깝다.
2. commit — 함께 보내 맡기다
commit
└── 라틴어 committere (맞붙이다, 맡기다, 저지르다)
├── com- (함께)
└── mittere (보내다) ← 손에서 "떠나보내는" 감각
= "함께 보내 하나로 맞붙여 맡기다"
핵심은 mittere(보내다)인데, 여기서 "보내다"는 단순한 전송이 아니라 손에서 떠나보내 맡긴다는 감각이다. 그래서 commit oneself(전념하다)는 자신을 어떤 일에 통째로 보내 맡기는 것이고, commit a crime(죄를 저지르다)은 되돌릴 수 없는 행위를 세상에 보내버린 것이며, git의 commit은 작업 트리의 변경을 이력이라는 손에 맡겨 확정하는 것이다. 세 뜻이 흩어진 게 아니라 "보내 맡겨 되돌릴 수 없게 한다"는 한 감각에서 갈라져 나왔다.
mittere 가족 — submit(아래로 보내 제출) · transmit(가로질러 전송) · permit(통과시켜 허가) · admit(들여 인정) · emit(밖으로 방출) · omit(지나쳐 생략) · message(보내진 것) · promise(앞으로 보내겠다 함).
form을 submit하고, 데이터를 transmit하고, 권한을 permit하고, 변경을 commit한다. 개발이 이토록 mittere 가족으로 가득한 건 우연이 아니라고 본다. 소프트웨어가 하는 일의 상당수가 결국 무언가를 어디론가 보내는 일이기 때문이다.
왜 세 층위가 전부 이 단어인가. 버전 관리의 git commit, 데이터베이스의 COMMIT, 분산 합의의 two-phase commit — 층위가 다른데 이름이 같다. 공통점은 명확하다. 셋 다 "여기까지의 변경을 되돌릴 수 없게 확정해 맡긴다"는 순간을 가리킨다. 그전까지는 임시고, commit하는 그 순간에 비로소 손을 떠나 영구히 맞붙는다.
"The transaction won’t be durable until you commit."
커밋하기 전까지 트랜잭션은 영구적이지 않다.
"아직 commit 안 했어"라는 말이 안도가 되는 이유도 같다. commit 전까지는 아무것도 보내지 않았으니 git에선 reset으로, DB에선 ROLLBACK으로 되돌릴 수 있다. 좋은 커밋 메시지가 단순한 로그가 아니라 미래의 누군가에게 보내는 편지에 가까운 것도 이 어원과 맞닿아 있다고 생각한다.
헷갈리는 이웃. stage → commit → push → merge 순서가 곧 git 워크플로다. 되돌릴 수 없음의 무게가 가장 큰 지점이 commit이다. stage는 아직 리허설이고, push는 이미 확정된 걸 옮기는 일이다. save는 결이 아예 다르다. 파일을 보관할 뿐 "보내 맡긴" 이력을 남기지 않는다.
3. deploy — 접힌 것을 펼쳐 널다
deploy
└── 고대 프랑스어 desploier (펼치다, 널다)
└── 라틴어 displicare
├── dis- (떨어져, 흩어)
└── plicare (접다)
= "접혀 포개져 있던 것을 흩어 펼쳐 자리에 널다" = unfold
핵심은 plicare(접다)다. 종이를 접으면 부피는 작아지지만 안이 감춰진다. 거기에 "떨어뜨리는" dis-가 붙으면 반대 동작, 즉 접힌 것을 펼쳐 널어 놓는 게 된다. deploy는 어원 그대로 unfold다. 접혀 뭉쳐 있던 병력을 벌판에 벌여 세우고, 접어 두었던 논거를 하나씩 펼쳐 내보이고, 저장소에 접혀 있던 코드를 프로덕션이라는 자리에 펼쳐 너는 것. 뿌리 하나로 셋이 같은 그림이 된다.
plicare 가족 — apply(접어 갖다 붙이다 → 적용) · reply(접어 되돌리다 → 답장) · imply(안으로 접어넣다 → 함축) · complicate(함께 접다 → 얽히다) · complex(여러 겹 접힌) · multiply(여러 겹 접다) · display(펼쳐 보이다) · replica(되접어 만든 복제).
이 가족의 백미는 display와 deploy가 쌍둥이라는 점이다. 둘 다 dis- + plicare, 곧 "펼치다"에서 왔는데 display는 눈앞에 펼쳐 보이는 쪽으로, deploy는 자리에 펼쳐 놓는 쪽으로 뜻이 굳었다. replica까지 이 가족이라는 걸 알면 쿠버네티스에서 replicas: 3을 deploy한다는 문장이 어원 층위에서 "여러 겹으로 되접은 것을 펼쳐 널다"로 겹쳐 읽힌다.
왜 upload가 아니라 deploy인가. 저장소 안에 접혀 뭉쳐 있던 코드를 프로덕션이라는 넓은 자리에 펼쳐 벌여 세우는 그림이, 군대를 전개(deploy)하는 그림과 정확히 겹치기 때문이다. blue-green으로 두 전선을 벌여 두고 트래픽을 옮기고, canary로 선발대를 5%만 먼저 펼쳐 관찰하는 — 배포 전략 이름들이 죄다 군사 용어처럼 들리는 것도 우연이 아니다. 어원이 원래 병력 전개다.
"We deploy to production every Friday afternoon."
우리는 매주 금요일 오후에 프로덕션으로 배포한다.
금요일 오후의 deploy가 늘 조금 긴장돼 들리는 이유를 어원이 설명해준다. 한번 펼쳐 놓으면 접기 전만큼 간단히 되돌릴 수 없다. put이나 copy를 썼다면 이 무게는 실리지 않는다.
헷갈리는 이웃. provision은 펼치기 전에 자리를 미리 마련하는 것, deploy는 그 자리에 실제로 펼쳐 세우는 것, release는 그렇게 세운 것을 사용자에게 풀어 주는 결정이다. 그래서 "deploy했지만 아직 release하지 않았다"(피처 플래그로 코드는 펼쳐 뒀지만 아직 켜지 않음)는 문장이 성립한다. rollout은 그 펼침을 한꺼번에가 아니라 서서히 굴려 넓히는 방식이다.
4. migrate — 거처를 바꿔 옮겨가다
migrate
└── 라틴어 migrare (거처를 바꾸다, 옮겨가다)
└── 인도유럽조어 *mei- (바꾸다 — change)
= "있던 자리를 바꿔 다른 곳으로 옮겨가다"
가장 깊은 뿌리는 *mei-, 곧 "바꾸다"다. migrate는 단순히 이동한다(move)가 아니라 살던 자리 자체를 바꿔 새 거처로 옮겨간다는 감각을 품는다. 철새가 계절이 되면 서식지를 통째로 바꾸듯이. 같은 뿌리에서 mutate(변이하다)가 갈라져 나온 것도 재미있다. 자리를 바꾸면 migrate, 성질을 바꾸면 mutate인 셈이다.
migr- 가족 — immigrate(안으로 옮겨오다 → 이민 오다) · emigrate(밖으로 옮겨가다 → 이민 가다) · migration(이주) · migrant(철새·이주민) · mutate(변이).
immigrate와 emigrate가 헷갈리면 접두사 방향만 기억하면 된다. im-(안으로)이면 오는 것, e-(밖으로)면 가는 것. 개발에서 쓰는 migrate도 방향만 다를 뿐 정확히 같은 동작이다. 데이터를 옛 저장소에서 빼내(emigrate) 새 저장소로 들여오는(immigrate) 일이니까.
왜 move가 아니라 migrate인가. DB 스키마 변경, 온프렘에서 클라우드로의 이주, 레거시에서 새 프레임워크로의 이관 — "구조를 통째로 바꿔 옮기는" 일에는 거의 예외 없이 migrate가 붙는다. 파일 위치만 바꾸는 move와 달리, migrate에는 옛 자리를 떠나 새 구조에 자리 잡되 그 과정을 버전으로 관리하며 되돌릴 수 있게 한다는 뉘앙스가 있다. Flyway의 V2__add_email.sql도, Alembic의 upgrade/downgrade 짝도 이 감각 위에 서 있다. 철새가 봄에 왔다 가을에 돌아가듯, 스키마도 앞으로 옮겼다 문제가 생기면 뒤로 되돌린다.
"A failed migration left the schema half-updated."
실패한 마이그레이션이 스키마를 절반만 갱신된 채로 남겼다.
이사가 도중에 멈추면 짐 절반은 옛 집에, 절반은 새 집에 남는다. 스키마 마이그레이션이 중간에 실패했을 때가 정확히 그렇다. 성숙한 도구일수록 이동을 트랜잭션으로 감싸 "끝까지 옮겨가거나, 아예 옛 자리에 그대로 있거나" 둘 중 하나만 허용하는 이유다.
헷갈리는 이웃. move는 자리만 바꿀 뿐 내용은 그대로, transfer는 "넘겨줌"에, port는 "새 환경에 맞춰 이식"에 방점이 있다. migrate만이 거처 자체를 바꿔 새 구조에 자리 잡는다는 감각을 갖는다. port의 뿌리는 라틴어 어근 한 페이지에서 따로 다뤘다.
5. deprecate — 오지 않기를 빌어 물리치다
deprecate
└── 라틴어 deprecari (빌어서 물리치다)
├── de- (멀리, 물리쳐)
└── precari (빌다, 기도하다) ← pray 와 같은 뿌리
= "그 일이 나에게 닥치지 않기를 빌어 물리치다"
핵심은 precari(빌다)이고, pray와 같은 뿌리다. 원래 deprecate는 "재앙이 나에게 닥치지 않기를 신께 빌어 물리치다"라는 뜻이었다. 물리적으로 막거나 금지하는 게 아니라 "제발 그러지 않기를" 하고 비는 태도다. 이 뉘앙스가 그대로 남아 오늘날의 "못마땅해하며 그만두라고 완곡히 말리다"가 되었다.
precari 가족 — pray(빌다) · prayer(기도) · precarious(빌어야 얻는 → 위태로운) · imprecate(저주하다).
precarious가 한 가족이라는 게 이 뿌리를 잘 보여준다. 빌어야만 겨우 손에 넣는 것은 곧 내 뜻대로 되지 않아 아슬아슬한 것이다. deprecate 역시 강제가 아니라 빎에 기대므로, 상대가 안 들어주면 그만이다.
왜 remove가 아니라 deprecate인가. API를 없앨 때 대뜸 지우지 않는다. 먼저 "곧 사라질 예정이니 그만 쓰세요"라고 표시하고, 한동안 경고만 띄우며 동작은 유지한다. 이 단계에 붙는 이름이 deprecate다. 어원 그대로 "제발 이제 이건 쓰지 않기를 빈다"는 정중한 만류라서, 당장 막지는 않되 완곡히 권하는 그 온도가 폐기 예고의 성격과 정확히 맞는다.
"warning: this method is deprecated and will be removed in a future release."
경고: 이 메서드는 폐기 예정이며 향후 릴리스에서 제거됩니다.
이 문장을 어원으로 읽으면 메인테이너의 목소리가 들린다. 내 코드를 강제로 멈추지 않았다. 다만 빌고 있는 것이다. deleted도 forbidden도 아니라 deprecated인 이유가 여기 있다. 아직 문은 열려 있고, 다만 그 문으로 들어오지 말아 달라는 부탁이다. 그 부탁을 흘려들으면 다음 메이저 업그레이드에서 빎은 물리침으로 바뀌고 빌드가 깨진다.
헷갈리는 이웃. 넷은 시간축 위에 나란히 놓인다. 기능은 먼저 deprecate되어(그만 쓰길 빎) 한동안 경고와 함께 살아 있고, 그 사이 obsolete해지며, sunset 일정을 따라 저물다가, 끝내 remove된다. deprecate만이 유일하게 아직 동작하는 상태라는 점이 실무에서 가장 자주 오해된다.
다섯을 파이프라인 위에 다시 놓으면
| 단계 | 동사 | 어원이 말하는 동작 | 되돌릴 수 있나 |
|---|---|---|---|
| 빌드 | compile | 흩어진 걸 한 더미로 쌓는다 | 다시 쌓으면 됨 |
| 확정 | commit | 손에서 떠나보내 맡긴다 | reset·revert로 어렵게 |
| 배포 | deploy | 접힌 걸 자리에 펼친다 | rollback, 다만 비쌈 |
| 이전 | migrate | 거처 자체를 바꾼다 | downgrade 경로가 있을 때만 |
| 폐기 | deprecate | 오지 않기를 빈다 | 아직 안 죽였으므로 언제든 |
재미있는 건 되돌리기 난이도가 어원의 물리적 무게와 거의 같은 순서라는 점이다. 더미를 다시 쌓는 일(compile)은 쉽고, 손에서 떠나보낸 것(commit)은 회수가 번거롭고, 펼쳐 널어 놓은 진영(deploy)을 도로 접는 일은 더 비싸며, 거처를 옮겨버린 것(migrate)은 downgrade 경로를 미리 마련해두지 않았다면 되돌아갈 길 자체가 없다. 반대로 deprecate는 아직 아무것도 하지 않고 빌기만 한 단계라 언제든 무를 수 있다.
이건 어원이 증명해주는 사실이 아니라 내 해석이다. 다만 새 파이프라인 단계를 설계할 때 "이 동작은 다섯 중 어느 무게에 가까운가"를 자문하는 데는 쓸모가 있었다.
예문 모음
compile
- The code won’t compile because of a missing semicolon. — 세미콜론이 빠져서 컴파일되지 않는다.
- TypeScript compiles down to plain JavaScript. — 타입스크립트는 순수 자바스크립트로 컴파일된다.
- The compiler gathers every source file into one binary. — 컴파일러는 모든 소스 파일을 하나의 바이너리로 그러모은다.
commit
- Commit your changes before switching branches. — 브랜치를 바꾸기 전에 변경을 커밋해라.
- Don’t commit secrets or API keys to the repository. — 비밀 값이나 API 키를 저장소에 커밋하지 마라.
- Two-phase commit keeps the nodes in agreement. — 2단계 커밋이 노드들을 합의 상태로 유지한다.
deploy
- Deploy the canary to 5% of traffic first. — 먼저 카나리를 트래픽 5%에 배포해라.
- The rollback failed, so the broken build stayed deployed. — 롤백이 실패해서 깨진 빌드가 배포된 채로 남았다.
- The rescue team was deployed within hours. — 구조대는 몇 시간 안에 투입되었다.
migrate
- We migrated the database from MySQL to Postgres. — DB를 MySQL에서 Postgres로 이전했다.
- Always test the downgrade path before you migrate. — 마이그레이션 전에 downgrade 경로를 먼저 테스트해라.
- Many birds migrate south for the winter. — 많은 새가 겨울이면 남쪽으로 이동한다.
deprecate
- This method is deprecated; use the async version instead. — 이 메서드는 폐기 예정이니 비동기 버전을 써라.
- We deprecate the endpoint before we delete it. — 엔드포인트를 삭제하기 전에 먼저 폐기 예고한다.
- He made a self-deprecating joke about his own code. — 그는 자기 코드를 두고 자신을 낮추는 농담을 했다.
함께 읽으면 좋은 글
- 개발 문서에서 매일 보는 라틴어 접두사 7개 한 페이지 —
re·pre·pro·trans·per·un·e/ex. 이 글의com-,de-,dis-가 어떻게 방향을 정하는지 - 개발 문서의 명사·형용사를 만드는 영어 접미사 8개 —
deployment,migration처럼 동사를 명사로 굳히는-ment,-tion - 코드에 박혀 있는 라틴어 어근 6개 한 페이지 —
port·duct·vis·spect·man·per. migrate와 짝을 이루는port가 여기 있다 - 손의 동작으로 읽는 라틴어 어근 7개 — commit이 속한
mit/miss어근 전체를 여섯 형제와 함께 - 컴퓨터가 빌려온 이름 6개 — 어근으로 쪼개지지 않는
queue·bootstrap·algorithm·cipher·robot·daemon - [어원] manifest — manus(손) + festus(붙잡은) — 배포 대상을 적어두는 그 manifest
참고
- Online Etymology Dictionary — compile, commit, deploy, migrate, deprecate
- Cambridge Dictionary — deploy, deprecate
- Kubernetes Documentation — Deployments
- MDN Web Docs — Deprecated (Glossary)
답글 남기기