- 발행일
카테고리 하나에 폴더 하나 — 복붙 열한 벌
카테고리 하나에 폴더 하나 — 복붙 열한 벌
이 글은 2026년 9월에 당시 커밋 이력을 다시 보며 정리한 것입니다. 날짜는 작업한 날 기준입니다.
큐피트에는 운동 영상 목록과 패션 추천 목록이 있었습니다. 운동은 팔·등·배·가슴·하체·어깨·전신 일곱 부위, 패션은 남녀 × 봄여름·가을겨울 네 가지. 화면 모양은 전부 같았어요. 카드가 줄지어 있고, 검색이 있고, 더 보기가 있는 목록입니다.
저는 카테고리마다 폴더를 하나씩 만들었습니다. Arm/, Back/, Belly/… 그리고 MenFW/, MenSS/, WomenFW/, WomenSS/. 열한 개예요.
다른 줄은 다섯 줄
저장소 마지막 커밋에서 남성 가을겨울 목록과 여성 봄여름 목록을 공백을 빼고 비교하면 이렇습니다.
3c3 import MFWpage from "./MFWpage"; → import WSSpage from "./WSSpage";
28c28 class MFWList extends Component { → class WSSList extends Component {
50c50 '/api/fassion/men/fw?page=' → '/api/fassion/women/ss?page='
80c80 <MFWpage Clothes=… /> → <WSSpage Clothes=… />
93c93 export default … (MFWList) → export default … (WSSList)
93줄짜리 파일에서 다른 건 이름과 API 경로뿐입니다. 운동 쪽도 같아요. ArmList.js와 BackList.js를 비교하면 import·클래스명·경로가 다르고, 한 곳은 복사한 흔적이 그대로 남아 있습니다.
// BackList.js
import ArmSearch from "./BackSearch";
BackSearch를 가져오면서 변수 이름은 ArmSearch인 채로 뒀어요. 동작에는 문제가 없어서 눈에 안 띄었습니다.
App.js의 라우트는 17개인데 그중 11개가 이 목록 화면입니다.
<Route exact path="/women_ss" component={WSSList}/>
<Route exact path="/women_fw" component={WFWList}/>
<Route exact path="/men_ss" component={MSSList}/>
<Route exact path="/men_fw" component={MFWList}/>
<Route path="/arm" component={ArmList}/>
<Route path="/back" component={BackList}/>
...
하루에 1,235줄을 넣고 16분 뒤 312줄을 지웠다
만든 순서를 커밋으로 보면 이렇습니다.
| 시각 | 커밋 | 내용 |
|---|---|---|
| 11/19 00:38 | e6417a3 "패션 알고리즘" | 패션 4파일 181줄. 커밋 본문은 "사진 하나만 됩니다" |
| 11/20 02:11 | 7e358be "패션 고치기" | 패션 폴더 넷으로 12파일, +659 |
| 11/21 06:46 | c643320 "exercise -1" | 팔·등·배 세 폴더 21파일, +1,193 |
| 11/22 01:51 | 1f2d6f8 "Exercise 총괄" | 일곱 부위를 Exercise/ 아래로, 26파일 +1,235 |
| 11/22 02:07 | 4112264 "Page 오류 정리" | 6파일 −312 |
패션이 하나 되자 넷으로 늘렸고, 운동은 셋을 먼저 만들고 이튿날 일곱으로 늘렸습니다. 부위 하나가 되면 나머지는 폴더를 복사해 이름을 바꾸는 일이었어요.
16분 뒤 지운 312줄은 파일 여섯 개, 각 52줄입니다. Armpage.js와 ArmPage.js가 같은 폴더에 같이 있었어요. 공백을 빼고 비교하면 내용이 같습니다. 21일 판은 Armpage, 22일 판은 ArmPage로 만들었는데, 대소문자를 구분하지 않는 파일 시스템에서는 하나로 보였을 테고 저장소에는 둘 다 올라갔습니다. 어떤 환경에서 작업했는지는 커밋에 없어요. 여섯 부위에서 같은 일이 났고, 그걸 지운 게 "Page 오류 정리"예요.
그 사이 새벽 2시 34분부터 50분까지 팀원이 GitHub 웹에서 파일을 지우고 다시 올린 커밋 41개가 끼어 있습니다. 로컬과 원격이 어긋난 걸 그렇게 맞춘 거예요. 그건 제 커밋이 아니라 여기서는 세지 않습니다.
그때는 왜 그랬나
커밋에 이유는 없습니다. 코드로 보이는 건 이거예요.
- 화면 하나를 완성하는 게 먼저였고, 그게 되니 나머지는 복사가 제일 빨랐습니다. 2023년에 쓴 이력서를 보면 이 프로젝트(2020-09
12)와 같은 기간에 동아리 사이트(2020-0412)도 프런트로 참여하고 있었어요. 그게 복사를 고른 이유였는지는 커밋에 없습니다. - props로 부위 이름과 API 경로를 넘기면 된다는 걸 몰랐다기보다, 그렇게 바꾸는 동안 되던 화면이 깨질까 봐 안 건드렸을 가능성이 커 보입니다. 다만 그건 코드에서 읽히는 게 아니라 짐작이에요.
- 열흘 전
Logout.js를 고친 커밋(1e79d25, 11/11)은 파일 안의 클래스가Logout에서Login으로 바뀌어 있습니다. 로그인 코드를 통째로 붙여 넣은 diff예요. 복사가 습관이었습니다.
검증
그날 확인한 것:
- 열한 화면이 각각 뜨고 카드가 나오는 것. 발표용으로는 그걸로 충분했습니다.
이 글을 쓰며 git show·diff -w로 확인한 것:
MFWList.js와WSSList.js의 공백 무시 diff가 다섯 줄인 것.BackList.js의import ArmSearch from "./BackSearch"가 마지막 커밋에 그대로인 것.1f2d6f8시점에Exercise/Arm/에Armpage.js와ArmPage.js가 같이 있고 내용이 같은 것,4112264가 소문자 여섯을 지운 것.App.js라우트 17개 중 목록 화면이 11개인 것.- 2023년 12월 이력서의 담당 범위(운동 페이지·옷 페이지 포함, 프런트 전담)와 이 폴더들의 커밋 저자가 전부 저인 것이 맞는 것. 이력서는 프런트 1명이라 적었지만 저장소에는 다른 팀원 커밋 46개가 있고, 그중 41개가 이 글에 나온 11월 22일 새벽의 지우고 다시 올리기입니다.
남은 것 · 한계
- 공통 컴포넌트로 합치지 않았습니다. 저장소 마지막 커밋까지 열한 폴더 그대로예요. 합쳤다면 파일 수십 개가 두세 개로 줄었을 텐데, 그걸 시도한 커밋은 없습니다.
- API 주소가 파일마다 박혀 있습니다. 서버 주소가 바뀌면 열한 곳을 고쳐야 했어요.
- 왜 복사를 택했는지는 짐작입니다. 위에 적은 이유는 코드에서 읽은 것이지 그때의 판단 기록이 아닙니다.
- 같은 유형을 5년 뒤에도 만났습니다. 지금 회사에서 분류체계 트리와 메타클래스 트리의 공통 로직을 헬퍼 4종으로 뽑았고2026-05-16분류체계와 메타클래스 트리 공통 로직을 헬퍼 4종으로 추출한 회고두 페이지가 따로 들고 있던 jstree 옵션과 이벤트 핸들러를 비교해 차이가 거의 없음을 확인하고, 공통 헬퍼 4종으로 추출한 리팩토링 회고입니다., 그다음 해에는 관계도 11개 화면을 렌더러 한 곳에서 바꿨어요2026-08-10관계도 11개 화면을 렌더러 한 곳에서 바꿨다 — 클릭이 이동에서 선택으로노드를 클릭하면 곧바로 화면이 떠나서, 이 노드가 뭔지 보려다가 보던 그림을 잃었습니다. 클릭을 선택으로 바꾸고 다음 행동을 우측 패널로 옮겼어요. 공용 렌더러와 공용 본문을 고쳐 공개 6 · 관리자 5, 11개 화면에 한 번에 걸었고, 설정을 템플릿 set에 두면 include로 안 넘어간다는 함정도 같이 정리했습니다.. 복붙 열한 벌이 그 축의 첫 장면입니다.
관련 글: 큐피트 — 대학 졸업작품으로 만든 홈트레이닝 웹2020-12-31큐피트 — 대학 졸업작품으로 만든 홈트레이닝 웹, 그리고 처음 만난 성능 문제코로나로 헬스장에 못 가던 시기에 만든 홈트레이닝 웹 서비스입니다. 대학 종합설계 프로젝트로 진행했고 프런트엔드를 맡았어요. 자세 교정 영상 처리가 너무 느려 서버 처리에서 브라우저 처리(TensorFlow.js·ml5)로 옮긴 게 제 첫 성능 개선 경험이었습니다. · 분류체계와 메타클래스 트리 공통 로직을 헬퍼 4종으로 추출한 회고2026-05-16분류체계와 메타클래스 트리 공통 로직을 헬퍼 4종으로 추출한 회고두 페이지가 따로 들고 있던 jstree 옵션과 이벤트 핸들러를 비교해 차이가 거의 없음을 확인하고, 공통 헬퍼 4종으로 추출한 리팩토링 회고입니다. · 관계도 11개 화면을 렌더러 한 곳에서 바꿨다2026-08-10관계도 11개 화면을 렌더러 한 곳에서 바꿨다 — 클릭이 이동에서 선택으로노드를 클릭하면 곧바로 화면이 떠나서, 이 노드가 뭔지 보려다가 보던 그림을 잃었습니다. 클릭을 선택으로 바꾸고 다음 행동을 우측 패널로 옮겼어요. 공용 렌더러와 공용 본문을 고쳐 공개 6 · 관리자 5, 11개 화면에 한 번에 걸었고, 설정을 템플릿 set에 두면 include로 안 넘어간다는 함정도 같이 정리했습니다. · 로그인이 계속 풀려서 조건을 바꿨다2020-11-15로그인이 계속 풀려서 조건을 바꿨다 — 원인은 setState 바로 다음 줄에 있었다졸업작품 큐피트에서 마일리지 화면을 열면 "로그인 해주세요"가 떴습니다. 새벽 2시에 else를 else if로 바꿔 메시지가 안 뜨게 했고, 커밋 제목은 "로그인이 계속 풀려서 다르게 처리"였어요. 이 글을 쓰며 코드를 다시 보니 로그인 화면이 setState 바로 다음 줄에서 아직 비어 있는 state를 쿠키에 저장하고 있었습니다. 증상을 조건으로 덮은 첫 기록입니다. · 클래스 팔레트 20종이 다섯 파일에 복사돼 있고 Redux는 import만 남았다2022-07-24클래스 팔레트 20종이 다섯 파일에 복사돼 있고 Redux는 import만 남았다 — 경력기술서의 "Redux"를 코드로 다시 확인하기경력기술서에 기술 스택으로 Redux를 적어 두었는데, 보관해 둔 스냅샷을 열어 보니 스토어는 주석 처리돼 있고 useSelector는 import만 남아 있었습니다. 판정 클래스 스무 종의 이름과 색 팔레트는 App.js와 리듀서 파일 넷에 그대로 복사돼 있었고, 실제 선택 상태는 localStorage가 들고 있었어요. 한 시점의 코드로 확인되는 것과 안 되는 것을 갈라 적습니다.