이번 주로 벌써 5주차가 되었다. 이번 글은 Git과 GitHub에 관한 주제로 작성하게 되었다. 사실 이 GitHub 특강은 대략 3주차에 들어있는 내용이었다. 그런데 왜 지금에서 작성하냐면...
이번 주 미션의 내용이 Git 특강 교육 후기이기 때문이다.

사실 Git과 GitHub는 개발자라면 반드시 한 번쯤 사용하게 되는 것 중 하나다. 하지만 혼자서 개발하는 초보 개발자에게 Git의 의미가 사실 크게 와닿지 않기도 한다. 나 또한 그런 사람 중 한 명이었다. 혼자서 간단한 프로그램만 만들어봤기 때문에 버전 관리라던가, 원격 레포지토리를 만들어야 한다던가 하는 필요성을 느끼지 못했었다.
하지만 이번에 특강을 들으면서, 생각보다 깃이 그냥 혼자서 개발할 때에도 꽤나 유용하겠다는걸 느끼게 되었다. 그래서 이번 글에는 내가 왜 그렇게 느꼈는지 작성해볼 생각이다.
Git 이 뭔가요?
Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.
Git is lightning fast and has a huge ecosystem of GUIs, hosting services, and command-line tools.
- git-scm.com
Git, 이하 깃은 하나의 분산 버전 관리 시스템이다. 깃의 핵심은 파일의 상태를 하나의 버전으로 기록한다는 것. 그래서 내가 무언가를 변경하거나 삭제하더라도, 이전의 버전이 존재한다면 해당 버전으로 복구도 가능하게 만들어준다.
말만 들어보면, 그렇게 크게 좋은건가 싶긴 하다. 버전 관리를 꼭 깃으로 해야 할 필요가 있나 싶기도 하고. 그냥 이전 파일을 저장해놓기만 하면 되는거 아닌가? 하지만 우리가 평소에 하던 짓들을 생각해보면, 깃의 역할은 꽤나 중요할지도 모르겠다.

다들 한 번쯤 이런 경험을 해 봤을 것이다. 내가 제출해야 하는 결과물이 있지만, 실제로 새롭게 추가되거나 변경될 때 기존의 내용을 잃어버리지 않기 위해서 새로운 파일을 하나 만들어 버린다. 결국 실제로 이전에 만들었던 자료들은 전부 교체되어서 사용하지 않게 되겠지만, 그놈의 만약을 위해서 남겨놓는 파일들만 하더라도 셀 수 없이 많은 파일들이 저장되어왔다.
이런 정말 바보같은 문제를, 우리의 Git은 곧바로 해결해 줄 수 있다. 우리 Git은 위와 같이 파일 형식으로 관리를 하는 것이 아니라, 파일이 변경된 것을 감지하는 관리 시스템이다. 그러니까, 저렇게 무식하게 중복되는 파일을 무한정 생산하지 않아도 된다는 것. 그저 내가 원하는 타이밍에 해당 시점의 파일을 저장하고, 필요하다면 해당 시점으로 되돌리는 역할만 한다는 것이다.
이것의 장점은, 아무래도 파일 데이터가 중복되지 않는다는 점이 좋겠다. 그리고, 역시나 파일 관리 자체가 쉬워지는 장점이 있겠다. 그런데 깃은, 분산 버전 관리 시스템 이라고 말했지. 산순히 버전 관리 뿐만이 아니라, 분산 시스템을 구현한다는 이야기다.
분산 버전 관리란?
버전 관리는 알겠다. 하지만 분산 관리는 또 뭘까. 분산의 의미는 한 곳에 몰아넣지 않고, 여러 곳으로 퍼트려서 관리한다는 의미다. 계란을 한 바구니에 담지 말라는 속담이 있는 것처럼, 분산 시스템은 꽤나 중요한 역할을 담당한다. 우리의 계란이 전부 깨져버려서 밥을 못 먹으면 너무나도 억울하지 않겠는가.

우리가 위 사진처럼, 여러 개의 파일을 나누어서 버전을 관리하기도 하고, Git을 이용해서 파일 하나로 여러 시점의 버전을 관리할 수 있다. 이 경우를 로컬 버전 관리 시스템(Local Version Control System)이라고 한다. 이 방식을 사용하면, 파일을 이전 버전으로 되돌리고 싶을 때 언제든지 가져와서 사용할 수 있으니까 안심이다. 그러면 우리는 이 방식을 고수하기만 한다면 안심할 수 있는걸까?
혼자서 심혈을 기울여서 개발하는 프로젝트가 있다고 하자. 평소에 카페에 들락날락 하면서 노트북으로 열심히 만들고 있는 자료가 있었다. 엄청난 노력 끝에 완벽한 결과물을 만들어 낼 수 있었다. 기분이 좋아진 나는 그동안의 노고에 작은 선물을 주고자 잠깐 밖에 나가 산책을 하게 되었다. 그렇게 기분좋게 꽃구경을 갔다 온 사이에, 내 프로젝트를 노리던 누군가가 내 노트북을 훔쳐가 버렸다. 그렇게 야심차게 만들었던 프로젝트는 한톨의 텍스트도 남기지 못한 채 사라져버렸고 나는 알거지가 되어버렸다.

무슨 말도 안되는 가정을 두는가 싶지만, 확실히 이해가 되는 예시라고 생각한다. 우리는 이런 문제를 예방하기 위해서 항상 파일을 이곳 저곳에 분산해서 보관해야만 한다. 외장하드에 프로젝트를 복사해 놓는다거나, 노트북 뿐만 아니라 데스크탑에도 프로젝트를 넣어놓는다거나 말이다. 내 사활을 건 프로젝트인데, 고작 복면 쓴 괴도 한명이 노트북을 홀랑 보쌈해가는 것으로 망해버릴 수는 없지 않겠는가.
당연하게도 사람들은 보통 프로젝트를 혼자 전부 처리하지는 않는다. 당연히 여러 사람이 모여서 진행해야 빠르고 더 크게 수행할 수 있기 때문이다. 하지만 모든 사람이 똑같은 파일로 똑같은 작업을 한다면 당연히 비효율적이겠지. 그래서 각자 역할을 분담하여 수행할 과제를 맡는다. 이전에 괴도에게 노트북을 헌납해버린 당신은, 그때의 기억을 되새기며 이를 갈게 되었다. 이번에는 절대로 훔치지 못하게 만들겠다는 집념과, 다같이 프로젝트를 진행해야 하는 문제를 동시에 해결하는 방법을 고안했다.
프로젝트 과제를 하나의 서버에 올려놓고, 사람들이 필요할 때마다 파일을 다운받아서 해당 파일을 교체, 변경, 업데이트와 개선을 하고, 다시 서버로 업로드를 하면 하나의 큰 프로젝트를 다같이 수행할 수 있겠다. 이걸 중앙집중형 버전관리 시스템 (Central Version Control System)이라고 말한다.

이 방식을 사용하면, 복면쓴 괴도에게서도 안전하다! 그 괴도가 훔치려면 노트북을 훔쳤지, 서버를 들고 도망칠 수는 없다. 더 이상 괴도에게 내 파일을 헌납하지 않겠다는 의지가 느껴진다. 그렇다면 당신은 이제 안심하고 살아도 되는걸까? 당연히 아니다.
괴도가 무시무시한 짓을 벌일 수 있기 때문이다.

만약에 괴도가 서버의 전원을 전부 내려버린다면... 그 누구도 프로젝트에 접근할 수 없게 된다. 그대로 밥줄이 끊겨서 단체로 알거지가 되어버리는 것이다. 분명 파일을 못 훔쳐가게 잘 관리한다고 생각했지만, 딸깍 한 번에 모든걸 무로 되돌려버리는 것이다.
그러면 오히려 노트북을 여러 대 두고 사람들끼리 돌려가면서 사용하는게 안전한게 아닐까. 하지만 그렇게 한다면 효율이 나올리가 없다. 그렇다면 도대체 어떻게 해야 괴도에게서 해방될 수 있을까?
그래서 당신은 조금 더 머리를 쓰기 시작했다. 지금처럼 서버에 데이터를 전부 두되, 내 노트북에도 모든 데이터를 가져다가 쓰자는 것이다. 그것이 바로 분산 버전 관리 시스템 (Distributed Version Control System) 가 되시겠다.

분산 버전 관리 시스템 (Distributed VCS) 은 중앙 집중형 버전 관리 시스템을 사용할 때 괴도에게 당했던, 서버 끊어버리기 문제를 해결할 수 있는 구조다. 각 개발자들의 로컬 머신에 전체 코드베이스와 변경 이력 전부를 복사본으로 가지고 있는 것이다. 내 노트북에도, 데스크탑에도, 서버에도, 동료의 노트북에도 전부 동일한 프로젝트 코드를 갖게 되는 것이다.
괴도가 아무리 날고 기더라도, 그에게 몸은 하나 뿐이다. 내 노트북을 훔치면서 서버도 차단하면서 동료의 노트북을 훔치는 짓까지는 할 수 없겠지. 이제는 안심할 수 있지 않을까.

그리고 우리의 Git은 이 D-VCS를 제공해준다는 것이다. 얼마나 감사한 일인가. 이 분산 시스템을 제공하기 위해서 Git은 원격 레포지토리인 GitHub를 제공한다. 우리가 서버에 데이터를 저장하는 것처럼, GitHub에 버전관리와 데이터 저장을 한꺼번에 수행할 수 있다는 것. 이제 우리는 괴도로부터 해방되었다.
Git의 구조

그럼 깃이 얼마나 유용한지를 알았으니, 깃이 어떻게 동작하는지도 알아야겠지. 그림을 보면, 깃의 상태 관리는 총 네개의 큰 구역으로 나눌 수 있는걸 알 수 있다. 첫번째로는 Working Directory. 우리가 프로젝트를 진행하면서 파일을 변경하는 영역에 해당한다.
두 번째는 Staging Area. 깃을 사용할 때, 버전을 저장하고 등록하기 위해서, 어떤 것이 변화하였는지 그리고 어떤 파일을 저장할 것인지를 선택할 수 있다. 해당 등록 방식이 `git add` 커맨드다. 해당 커맨드로 내가 커밋하고 싶은 내용을 등록하게 된다.
세 번째는 Local Repository. 깃이 버전관리를 수행하는 내 프로젝트 폴더 영역이다. 해당 부분에는 내가 `git add`로 등록해썬 파일들이 전부 하나의 커밋 버전으로 저장되는 공간이다. 디렉토리 내의 `.git` 폴더 안이라고 보면 된다.
마지막으로 Remote Repository. 깃허브가 이에 해당한다. 웹 호스팅 서비스에 생성한 프로젝트가 되며, 내 Local Repository와 동기화해서 사용할 수 있다. 개발자들은 자신이 작업한 내용을 Local Repository에 반영하고, Remote Reposiroy에 `git push` 하여 최신 코드를 공유할 수 있다.
그렇게 어려운 구조는 아니다. 총 네 단계로 구성이 된다는 것을 기억하기만 하면 되겠다.
Git 명령어들
| 도움말 | 저장소 생성 | 스냅샷 저장 | 브랜치 | 원격 | 커밋 수정하기 | 기타 |
| git help | git init | git add | git branch | git remote | git reset | git bisect |
| git config | git clone | git status | git checkout | git fetch | git rebase -i | git blame |
| git diff | git merge | git pull | git cherry-pick | git grep | ||
| git commit | git rebase | git push | git revert | git reflog | ||
| git log | git stash | |||||
| git rm | git tag | |||||
| git mv | ||||||
| git restore | ||||||
| git reset | ||||||
| git clean | ||||||
| git show | ||||||
| git describe |
위 표가 우리가 자주 쓰는 커맨드들이 되겠다. 뭔가 많아보이지만, 변경 사항을 저장하고 수정하고, 작업 공간을 나누고 합치고, 협업을 위해 원격 서버와 통신하는 것이 전부다. 명령어에 대해서는 공식 문서를 찾아보면서 읽거나, `git 명령어 --help` 으로 충분히 찾아볼 수 있을 것이다.
저장소 생성 및 복제
echo "# hello-git" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/your_own_repo/file.git
git push -u origin main
위와 같은 방식으로 로컬에서 Git 저장소를 생성하고 → 커밋을 만든 뒤 → 원격 저장소(GitHub)에 연결하고 → 최초 push까지 하는 전체 초기 세팅을 할 수 있다. `git init`으로 버전 관리의 시작을 알리고, `git add`로 버전 관리 대상을 선택, `git commit`으로 스냅샷을 생성한 뒤 `git push`로 협업용 공유를 하게 된다. 생각보다 그렇게 어렵지 않다.
그렇게 여러가지 커맨드들을 실습을 하고 난 후에, 팀으로 모여서 프로젝트 협업 시나리오를 진행하게 된다.
협업 시나리오
[버전 3 실습 과제]
목표:
Git을 개인 도구가 아니라 협업용 이력 관리 시스템으로 사용해본다.
규칙:
- main 직접 push 금지
- 모든 변경은 issue 기반
- 모든 커밋 메시지에 issue 번호 포함
- 모든 작업은 feature branch 에서 진행
- PR 후 최소 1명 리뷰
- pull 사용 금지, fetch 후 직접 merge/rebase 판단
과제:
- 팀 저장소 생성
- README, 팀 규칙 문서, 팀원 소개 문서, 주제 문서 작성
- 각자 feature branch 에서 작업
- PR 생성 및 리뷰
- 머지 방식 선택 후 반영
- README 수정 이력 테이블에서 conflict 발생시키고 해결
- fetch + rebase 로 remote 변경 반영
- 마지막에 팀별 git log 그래프 캡처 후 발표

실제로 협업을 하게 되면, commit의 메세지라던가, issue의 생성이라던가 다양한 작업을 할 때 하나의 정해진 기준에 맞춰서 수행하게 된다. 새로운 Feature를 생성할 때에 Issue를 먼저 생성한 후 Branch를 파고 작업을 시작한다는 룰처럼, 정해진 규칙을 따르는 것이 Git을 사용하는 올바른 방법이라고 한다.
이 이유는 Git 버전 관리에서 자주 발생하는 충돌 문제 때문이기도 하다.

실제로 프로젝트 협업 시나리오에서 충돌 문제를 발생시키게 된다. 충돌이 일어나는 경우는 보통 브랜치를 main 노드에 merge 하게 되는 경우 발생하게 된다. 다른 협업자와 동일한 파일을 수정하게 되는 경우 빈번하게 발생하는데, Git은 두 사람의 파일 중에서 어떤 것이 더 정확한 파일인지 알 수 없기 때문에 해당 부분은 사람이 직접 해결을 해 주어야 한다.
그리고 해당 충돌 해결을 내가 맡게 되었는데... 꽤나 곤란한 경험이었다.

`git rebase` 중 충돌이 나면, 충돌 해결 → 스테이징 → rebase 계속 진행 순서로 가야 한다는 점을 알게 되었다. 핵심은 merge 충돌 때와 비슷하지만, 마지막이 commit이 아니라 `rebase --continue` 라는 점이다.
충돌이 발생하면 Git이 먼저 멈춘다. 이 상태에서는 먼저 어떤 파일이 충돌났는지 확인해야 한다. 그러면 both modified 같은 식으로 충돌 파일이 보인다. 그 다음 충돌난 파일을 직접 열어서 고친다. 파일 안에는 보통 사진과 같이 나타나게 된다. 이 파일을 이제 내가 직접 바꿔야 했다. 어떤 내용을 남길지 직접 찾아서 고친 후에 결정한다. 필요하면 내용을 남겨도 되지만, 두 파일을 적절히 합치면 된다. 이후에 <<<<<<< 라던가 ======== 라던가 하는 것들을 전부 제거해줘야 한다. 즉, 파일이 정상 코드 상태가 되도록 직접 정리해야 한다.
수정이 끝났으면 해당 파일을 스테이징 해야한다. `git add 파일명` 으로 하나하나 올려도 되고, 여러 파일을 고쳤다면 `git add .`으로 한 번에 올려주게 된다. 이후에 rebase를 계속한다는 `git rebase --continue`를 수행해야 한다.
이러면 Git이 다음 커밋을 다시 적용하려고 시도하게 되고, 또 충돌이 발생하면 했던 과정을 반복해야 한다.
즉 전체 반복 구조는 이렇다.
git status
# 충돌 파일 확인
# 파일 직접 수정
git add 파일명
git rebase --continue
이 과정을 rebase가 끝날 때까지 반복해야만 한다.
이때 중요한 점은 충돌을 해결한 뒤에 git commit을 직접 하면 안 되는 경우가 많다. 내가 이 지점에서 계속해서 문제가 발생했었다. rebase는 Git이 커밋을 하나씩 다시 재적용하는 과정이라, 사용자가 직접 commit하는 것이 아니었다.
git add ...
git rebase --continue
이 흐름으로 가야 한다는 것이었다.

Git 특강 후기
그렇게 한바탕 시나리오를 진행하면서 여러가지 커맨드들을 써보기도 하고, 충돌 해결도 경험해봤다. 혼자서 git을 쓸 때에는 충돌 해결같은건 생각해보지 않았는데, 실제로 이렇게 충돌 해결을 해보고 나니... 생각보다 까다롭다는게 느껴지기도 했다.
그리고 이제 Git을 이용해서, 내 워크스페이스를 관리하려고 한다.

Git을 배웠는데, Git을 사용하지 않고 있었다. 그래서 매일같이 폴더가 생성되고 파일이 생성되고, 프로젝트가 생성되고 있었다. 현재 Vue.js를 바탕으로 실습이 진행되는데, 한 번의 프로젝트 생성 시에 50MB 정도의 모듈들을 다운받게 된다. 그걸 매일같이 하고 있었으니... 용량이 생각보다 꽤 나가게 되더라.
우리가 보통 사용하는 SSD는 정해진 쓰기 사용량이 있다. 바로 TBW (Terabytes Written) 으로, SSD의 수명에 해당하는 쓰기 용량이 있다. 그래서 해당 쓰기량을 전부 사용한다면 사실상 SSD가 사용불능이 된다.
문득 프로젝트를 계속해서 생성하는 것이 이 TBW를 갉아먹는 행위가 아닐까 하는 생각이 들었다. 물론 50MB짜리를 매일같이 생성한다고 해서 내가 늙어죽기 전에는 전부 소모되지는 않는다. 하지만 Git을 사용한다면 날짜별로, 공통된 모듈을 제외하고 현재와 같은 구조처럼 사용할 수 있지 않을까 생각했다.
그래서 KB IT's Your Life에서 실습할 때 사용하는 폴더를 하나의 Git 레포지토리로 관리하기 시작했다. 공통으로 사용하는 모듈에 대해서는 계속해서 종속성을 유지하고, 현재 주로 공부하는 테마와 단원에 대해서 Branch를 나눈 뒤 Commit 메세지로 기록하는 습관을 들이기로 했다. 이걸 이용하니 모듈을 새롭게 인스톨 하지 않아도 되고, Vue 앱의 관계도 깨지지 않아서 하나의 폴더로 여러 실습을 수행할 수 있게 되었다.

깃 덕분에 용량도 좀 더 아낄 수 있다는 생각이 들어 기분이 좋아졌다.
요즘 AI 때문에 SSD와 RAM 가격이 정신이 아득해질 정도로 비싸지고 있다.
가난한 우리들에게 청천벽력과도 같은 소리다.
조금이라도 아끼면서 살아야지.
티끌 모아 1GB가 될지 누가 알겠어.

'개발 > KB IT's Your Life 7기' 카테고리의 다른 글
| KB IT's Your Life 7기 - 스켈레톤 프로젝트 후기 (1) | 2026.04.19 |
|---|---|
| KB IT's Your Life 7기 - 프론트엔드 교육을 들으며 (0) | 2026.04.11 |
| KB IT's Your Life 7기 - 프론트엔드랑 친해지기 (1) | 2026.03.29 |
| KB IT's Your Life 7기 - 웹 인터페이스랑 친해지기 (0) | 2026.03.22 |
| KB IT's Your Life 7기 기자단 - 초보 블로그 운영 꿀팁 (1) | 2026.03.16 |