바이브코딩을 하다 보면 “Git으로 버전 관리 하라”는 말을 들어요. 그냥 저장이랑 뭐가 다른가 싶죠. 근데 이거 하나만 잡아두면 마음이 아주 편해져요.
Git은 코드의 변경 이력을 시점별로 저장하고, 언제든 되돌릴 수 있게 해주는 도구예요. 게임의 세이브 포인트를 떠올리면 딱이에요. 중요한 고비마다 저장해두면, 뒤에서 뭔가 크게 망쳐도 마지막 저장 지점으로 돌아갈 수 있잖아요. Git이 코드에 그걸 해줘요. “어제는 잘 됐는데” 싶을 때 어제로 되돌리는 거죠.
일반 저장이 ‘덮어쓰기’라면, Git은 ‘매 순간을 다 기억하는 저장’이에요.
특히 AI에게 코드를 맡기는 바이브코딩에선 이게 더 든든해요. AI가 크게 갈아엎었다가 오히려 망가지는 일이 있는데, Git으로 세이브해뒀으면 직전으로 되돌리면 그만이거든요. 그 세이브 한 판이 커밋이고, 이걸 인터넷에 백업·공유하는 곳이 GitHub예요.
30초 확인 퀴즈
'Git'을 가장 잘 설명한 건?
Git은 버전 관리 도구예요. 코드가 언제 어떻게 바뀌었는지 시점별로 기록해두고, 필요하면 예전 상태로 되돌릴 수 있어요.
“GitHub에 올려야 Vercel로 배포돼요” 같은 말을 들으면, Git이랑 GitHub이 같은 건지 다른 건지부터 헷갈려요. 이름도 비슷하니까요. 둘의 관계만 정리하면 깔끔해져요.
Git이 내 컴퓨터에서 버전을 관리하는 도구라면, GitHub은 그 코드를 인터넷에 올려 백업·공유·협업하는 서비스예요. 코드를 위한 구글 드라이브라고 보면 돼요. 내 Git 기록을 GitHub에 올려두면 컴퓨터가 고장 나도 안전하고, 링크로 남과 공유하거나 함께 작업할 수도 있어요.
Git은 ‘기록하는 습관’, GitHub은 ‘그 기록을 올려두는 창고’예요.
바이브코딩에서 GitHub이 중요한 또 하나의 이유는 배포예요. Vercel·Netlify 같은 서비스가 GitHub에 올라온 코드를 보고 자동으로 배포해주거든요. 그래서 “GitHub에 올린다 → 자동으로 사이트가 갱신된다”는 흐름이 요즘 표준이에요. 계정 하나 만들어두면 두고두고 쓰여요.
30초 확인 퀴즈
'Git'과 'GitHub'의 관계로 가장 알맞은 건?
Git은 내 컴퓨터에서 버전을 관리하는 도구고, GitHub은 그 결과물을 인터넷에 올려 백업·공유·협업하게 해주는 서비스예요.
Git·GitHub을 쓰기 시작하면 “repo 만들어”, “레포 클론해” 같은 말이 바로 나와요. repo가 폴더 같기도 하고 아닌 것 같기도 하고, 처음엔 감이 안 오죠.
리포지토리는 한 프로젝트의 코드와 변경 이력을 통째로 담는 저장 공간이에요. 프로젝트 하나를 담는 서랍이라고 보면 돼요. 그 서랍 안에 코드 파일들, 그리고 Git이 기록한 변경 이력이 함께 들어 있어요. 보통 프로젝트 하나에 리포지토리 하나예요. 흔히 ‘repo(레포)‘라고 줄여 불러요.
그냥 폴더와 다른 점은, 이 서랍엔 ‘변경의 역사’까지 같이 들어 있다는 거예요.
그래서 “레포를 클론한다”는 건 GitHub에 있는 그 서랍을 통째로 내 컴퓨터에 복제해온다는 뜻이에요. 남의 오픈소스 프로젝트를 가져와 볼 때도 이 방식이죠. 리포지토리가 ‘프로젝트 한 덩어리’라는 것만 알면, 관련된 말들이 훨씬 편하게 들려요.
30초 확인 퀴즈
'리포지토리(repo)'를 가장 잘 설명한 건?
리포지토리는 한 프로젝트의 코드와 그 변경 이력을 함께 담는 저장 공간이에요. 흔히 'repo(레포)'라고 줄여 불러요.
Git을 쓰면 “이쯤에서 커밋해”라는 말을 들어요. 파일 저장(Ctrl+S)은 이미 했는데 또 뭘 하라는 건가 싶죠. 저장과 커밋은 결이 조금 달라요.
커밋은 변경한 내용을 ‘여기까지’라고 한 묶음으로 저장하는, Git의 세이브 한 판이에요. 게임 세이브에 “보스 깨기 직전”이라고 메모를 붙이는 것과 같아요. 그냥 파일 저장은 지금 상태를 덮어쓰는 거고, 커밋은 “이 시점을 하나의 이정표로 남긴다”는 거예요. 그래서 각 커밋이 나중에 되돌아갈 수 있는 지점이 돼요.
커밋할 때 남기는 짧은 메시지가 ‘이 세이브가 뭐였는지’ 알려주는 메모예요.
바이브코딩에선 이 습관이 특히 유용해요. AI에게 큰 작업을 시키기 전에 커밋해두면, 결과가 마음에 안 들어도 그 지점으로 깔끔하게 되돌릴 수 있거든요. “잘 되던 상태에서 커밋 → 과감히 시도 → 별로면 되돌리기”가 안전한 리듬이에요. 이렇게 쌓인 커밋들을 GitHub에 올려 백업해요.
30초 확인 퀴즈
Git에서 '커밋(commit)'을 가장 잘 설명한 건?
커밋은 변경 내용을 '여기까지'라고 한 묶음으로 저장하는 거예요. 각 커밋이 되돌아갈 수 있는 지점이 되고, 메시지로 무슨 작업인지 남겨요.
같은 부분을 서로 다르게 고쳐서, 어느 쪽을 택할지 Git이 판단 못 할 때 생기는 충돌이에요.
한 줄 비유
같은 문장을 두 사람이 다르게 고쳐온 거예요. 편집자가 '둘 중 뭘 쓰죠?' 하고 멈추죠.
바이브코딩에서 언제 만나나
'merge conflict' 떴는데 뭘 어떻게 해야 할지 몰라 패닉 오는 그 순간이에요.
한동안 잘 쓰다가 어느 날 “merge conflict”라는 말과 마주치면 등골이 서늘해져요. 빨간 표시가 잔뜩 뜨고 코드에 이상한 기호가 껴 있죠. 뭘 잘못했나 싶지만, 사실 흔한 상황이에요.
컨플릭트는 같은 부분을 서로 다르게 고쳐서, 어느 쪽을 택할지 Git이 판단하지 못할 때 생기는 충돌이에요. 같은 문장을 두 사람이 다르게 고쳐 왔다고 해봐요. 편집자는 둘을 자동으로 합칠 수 없으니 “둘 중 어느 걸 쓸까요?” 하고 멈추잖아요. Git도 똑같아요. 자기가 함부로 못 정하니 사람에게 물어보는 거예요.
에러가 아니라 ‘사람이 골라줘야 하는 갈림길’이에요. 겁먹을 필요 없어요.
해결은 표시된 두 버전 중 맞는 쪽을 남기고 나머지를 지우는 거예요. 요즘은 AI에게 “이 컨플릭트 정리해줘” 하면 대부분 깔끔히 풀어줘요. 혼자 작업해도 여러 기기를 오가면 생길 수 있으니, “충돌 = 둘 중 택일” 정도만 알아두면 당황이 확 줄어요.
30초 확인 퀴즈
'머지 컨플릭트(merge conflict)'가 생기는 이유로 가장 알맞은 건?
컨플릭트는 같은 코드 부분을 서로 다르게 수정해 합칠 때 생겨요. Git이 어느 쪽이 맞는지 모르니, 사람이 골라줘야 해요.
바이브코딩을 시작하면 얼마 안 가 검은 창에 뭔가를 치라는 안내를 만나요. 영화 속 해킹 장면 같아서 처음엔 덜컥하죠. 그런데 알고 보면 그냥 ‘말로 시키는 창’이에요.
터미널은 마우스 대신 명령어를 타이핑해서 컴퓨터에 일을 시키는 창이에요. CLI(명령줄 인터페이스)라고도 해요. 버튼을 찾아 클릭하는 대신, 직원에게 “이거 설치해줘”, “이거 실행해줘”라고 문장으로 지시하는 창구라고 보면 돼요. 익숙해지면 클릭보다 오히려 빠르고 정확해요.
무섭게 생겼지만 하는 일은 단순해요. ‘명령을 받아 실행하는 창구’예요.
바이브코딩에서 터미널은 주로 도구 설치나 실행에 써요. AI가 “터미널에 이 명령어를 붙여넣으세요” 하고 알려주면, 그대로 복사해 붙이고 엔터만 치면 되는 경우가 대부분이에요. 예를 들어 남의 코드를 설치하는 npm 명령도 여기서 실행해요. 검은 창을 ‘적’이 아니라 ‘창구’로 보면 훨씬 편해져요.
30초 확인 퀴즈
'터미널(CLI)'을 가장 잘 설명한 건?
터미널(CLI)은 명령어를 타이핑해 컴퓨터에 직접 지시하는 도구예요. 마우스 클릭 대신 문장으로 시키는 방식이죠.
코드를 돌리려는데 “npm install 하세요”라는 안내를 자주 만나요. 뭔가 설치되는 것 같긴 한데, 정확히 무슨 일이 벌어지는지 감이 안 오죠.
패키지는 남이 만들어둔 코드 묶음이고, npm은 그 패키지를 찾아 설치해주는 도구예요. npm을 코드 앱스토어라고 보면 쉬워요. 앱스토어에서 필요한 앱을 검색해 설치하듯, npm으로 필요한 기능(패키지)을 내려받아 내 프로젝트에 붙이는 거죠. 달력, 결제, 차트 같은 기능을 처음부터 안 만들고 가져다 쓰는 거예요.
“npm install”은 곧 “필요한 남의 코드를 내려받아 설치해줘”라는 뜻이에요.
이렇게 설치한 패키지들이 내 앱이 기대는 재료가 되는데, 그걸 의존성이라고 불러요. 터미널에 npm 명령을 치면 필요한 재료가 착착 깔려요. 그래서 새 프로젝트를 받으면 대개 제일 먼저 하는 게 npm install이에요. 재료부터 채우는 거죠.
30초 확인 퀴즈
'npm install'이 하는 일로 가장 알맞은 건?
패키지는 남이 만든 재사용 코드 묶음이고, npm은 그걸 검색·설치·관리하는 도구예요. 'npm install'은 필요한 패키지를 내려받아 설치해요.
내 코드는 건드리지도 않았는데 “dependency error” 같은 게 뜰 때가 있어요. 억울하죠. 이때 알아야 할 개념이 의존성이에요.
의존성은 내 앱이 돌아가려고 기대는 외부 코드들이에요. 요리의 재료 목록을 떠올리면 돼요. 파스타를 만들려면 면·소스·치즈가 있어야 하잖아요. 재료 하나만 빠져도 요리가 완성이 안 되죠. 앱도 패키지라는 재료들에 기대서 돌아가는데, 그 재료를 의존성이라고 불러요.
그래서 dependency 에러는 대개 ‘재료가 없거나, 버전이 안 맞는다’는 뜻이에요.
내 코드를 안 건드렸는데 문제가 생기는 이유가 여기 있어요. 재료(의존성)가 빠졌거나, 재료끼리 버전이 안 맞아서죠. 그래서 새 프로젝트를 받으면 재료부터 채우려고 npm install을 먼저 해요. 이런 에러를 만나면 AI에게 그대로 붙여넣고 “이 의존성 문제 고쳐줘” 하면 대개 해결돼요.
30초 확인 퀴즈
코드에서 '의존성(dependency)'을 가장 잘 설명한 건?
의존성은 내 앱이 동작하려고 필요로 하는 외부 패키지들이에요. 필요한 의존성이 빠지거나 버전이 안 맞으면 앱이 제대로 안 돌아요.
배포하려는데 “build failed”라는 빨간 글씨와 함께 멈출 때가 있어요. 로컬에선 잘 되던 게 왜 여기서 실패라는 건지 답답하죠. 빌드가 뭔지 알면 이 상황이 이해돼요.
빌드는 작성한 코드를, 실제로 배포해 돌릴 수 있는 완성된 형태로 변환하는 과정이에요. 장 봐온 재료를 실제 요리로 조리해 포장하는 단계라고 보면 돼요. 재료(코드) 상태로는 손님에게 못 내잖아요. 조리하고 담아야(빌드) 낼 수 있죠. 배포 직전에 이 조리 과정이 자동으로 돌아가요.
“build failed”는 ‘조리 중에 뭔가 어긋났다’는 신호예요. 대개 원인이 로그에 찍혀요.
로컬에선 되는데 빌드에서 실패하는 건, 조리 환경이 조금 달라서 생기는 흔한 일이에요. 재료(의존성)가 빠졌거나 타입 문제 같은 게 흔한 원인이죠. 실패 메시지를 그대로 AI에게 붙여넣고 “이 빌드 에러 고쳐줘” 하면, 대개 어디가 문제인지 짚어줘요.
30초 확인 퀴즈
'빌드(build)'가 하는 일로 가장 알맞은 건?
빌드는 사람이 쓴 코드를 배포·실행에 맞는 완성 형태로 변환하는 과정이에요. 이 과정에서 문제가 있으면 'build failed'로 멈춰요.
뭔가 잘못되면 화면이나 콘솔에 빨간 글씨가 와르르 뜨죠. 양이 많아서 어디부터 읽어야 할지 막막해요. 그런데 이 빨간 덩어리엔 규칙이 있어요.
에러 메시지는 ‘무엇이 잘못됐나’, 스택 트레이스는 ‘그게 어디서 터졌나’를 알려줘요. 스택 트레이스는 사고 현장의 발자국 같은 거예요. 문제가 난 지점부터, 거기까지 어떤 경로로 왔는지 거슬러 보여주죠. 발자국을 거꾸로 따라가면 시작점이 나오듯, 이걸 위에서부터 보면 대개 첫 줄 근처에 진짜 원인이 있어요.
다 읽을 필요 없어요. 맨 윗줄 메시지와, 내 파일 이름이 보이는 줄부터 보면 돼요.
비전공자라면 이걸 해석하려 애쓰기보다, 빨간 메시지를 통째로 복사해 AI에게 주는 게 제일 빨라요. “이 에러 왜 나는지 설명하고 고쳐줘” 하면 발자국을 대신 읽어줘요. 겁먹고 화면을 닫기보다, 그 텍스트가 곧 해결의 단서라는 것만 기억하면 돼요.
30초 확인 퀴즈
'스택 트레이스(stack trace)'가 알려주는 것으로 가장 알맞은 건?
스택 트레이스는 에러가 발생한 지점과 거기까지 온 경로를 보여줘요. 거꾸로 따라가면 문제의 시작점을 찾을 수 있어요.
문제가 생기면 “콘솔 좀 봐봐”라는 말을 들어요. 근데 콘솔이 어디 있는 창인지부터 막막하죠. 로그랑 콘솔이 뭔지 짝지어 보면 쉬워요.
로그는 프로그램이 실행되며 남기는 기록이고, 콘솔은 그 기록을 보여주는 창이에요. 자동차 블랙박스를 떠올리면 돼요. 평소엔 조용히 기록만 남기다가, 사고가 나면 그 기록을 되짚어 무슨 일이 있었는지 알아내잖아요. 프로그램도 실행 중에 “여기까지 왔다”, “이 값이 이랬다” 하고 로그를 남기고, 그걸 콘솔에서 열어봐요.
뭔가 잘 안 되면 “디버깅해봐”라는 말을 들어요. 근데 뭘 어디서부터 봐야 할지 막막하죠. 사실 디버깅은 거창한 게 아니라 원인을 찾아가는 과정이에요.
디버깅은 코드가 의도대로 안 돌아가는 원인(버그)을 찾아 고치는 과정이에요. 고장 난 가전을 수리하는 것과 비슷해요. 무작정 뜯는 게 아니라, “전원은 들어와? 소리는 나?” 하고 하나씩 짚어가며 어디가 문제인지 좁히잖아요. 디버깅도 로그와 에러 메시지를 단서로 원인 지점을 좁혀가는 일이에요.
핵심은 ‘한 번에 다 고치기’가 아니라 ‘원인을 하나씩 좁히기’예요.
바이브코딩 시대엔 디버깅 방식도 좀 달라졌어요. 예전엔 코드를 직접 파고들었다면, 지금은 에러와 상황을 AI에게 정확히 전달하는 게 절반이에요. “이렇게 했더니 이 에러가 났어”라고 구체적으로 줄수록 AI가 원인을 잘 짚어요. 그래서 디버깅을 잘한다는 건, 문제 상황을 또렷하게 설명하는 능력에 가까워지고 있어요.
30초 확인 퀴즈
'디버깅(debugging)'을 가장 잘 설명한 건?
디버깅은 버그(오작동)의 원인을 찾아 고치는 과정이에요. 로그·에러 메시지를 단서 삼아 문제 지점을 좁혀가며 수리하는 일이죠.
코드를 짜다 보면 빨간 물결 줄과 함께 “type error”가 뜰 때가 있어요. 실행은 되는 것 같은데 왜 자꾸 화를 내나 싶죠. 이건 사실 사고를 미리 막아주는 잔소리예요.
타입은 값의 종류를 미리 정해두어, 엉뚱한 값이 들어가는 실수를 막는 장치예요. 물건마다 라벨을 붙이는 것과 같아요. “이 칸엔 숫자만” 하고 정해두면, 실수로 글자를 넣으려 할 때 바로 걸리잖아요. 이걸 코드에 적용한 게 TypeScript고, 정해둔 것과 다른 값이 오면 실행하기도 전에 미리 경고해줘요.
type error는 고장이 아니라, ‘이 자리엔 이런 값이 와야 하는데?‘라는 사전 경고예요.
귀찮게 느껴질 수 있지만, 실행한 뒤에 터지는 버그를 미리 잡아주니 오히려 안전망이에요. 특히 AI가 짠 코드가 커질수록 이 라벨이 실수를 크게 줄여줘요. type error를 만나면 메시지를 AI에게 그대로 주고 “이 타입 에러 고쳐줘” 하면, 어디가 어긋났는지 대개 바로 정리해줘요.
30초 확인 퀴즈
'타입(TypeScript)'의 역할로 가장 알맞은 건?
타입은 값의 종류(숫자·글자 등)를 미리 정해두는 장치예요. 정해둔 것과 다른 값이 들어가면 미리 경고해, 실수를 실행 전에 잡아줘요.
비밀번호·API 키처럼 코드에 직접 적으면 안 되는 값을, 코드 밖에 따로 보관하는 방식이에요.
한 줄 비유
현관 비밀번호를 대문에 적어두지 않고 금고에 넣어두는 거예요. 집(코드)은 공개해도 금고는 안 열리죠.
바이브코딩에서 언제 만나나
AI가 만들어준 코드에 API 키를 그대로 박아넣고 깃허브에 올리면 큰일 나요. 그때 필요한 게 환경변수예요.
바이브코딩을 하다 보면 API 키, 비밀번호, 접속 정보 같은 남에게 보이면 안 되는 값을 다루게 돼요. 문제는 AI가 짜준 코드에 이런 값이 그대로 적혀 있는 경우가 많다는 거예요.
이걸 그대로 두고 깃허브 같은 공개 저장소에 올리면, 전 세계가 내 키를 볼 수 있어요. 실제로 노출된 키로 요금 폭탄을 맞는 사고가 흔해요. 그래서 나온 게 환경변수예요. 비밀 값을 코드가 아니라 .env 같은 별도 파일이나 서버 설정에 넣어두고, 코드에선 이름표로만 불러 쓰는 거죠.
코드는 공개해도 되지만, 금고 안 내용물은 따로예요. 그 경계를 긋는 게 환경변수예요.
실전에선 규칙이 단순해요. .env 파일은 절대 커밋하지 않기(보통 .gitignore에 넣어요), 그리고 배포할 때는 그 서비스의 설정 화면에 값을 따로 넣기. AI에게 코드를 시킬 때도 “키는 환경변수로 빼줘” 한마디를 습관처럼 붙이면, 사고의 절반은 미리 막을 수 있어요.