✔️ Git이란, 버전 관리 시스템(Version Control System, VCS)의 하나이다.
쉽게 말하면, 말 그대로 '버전'을 관리할 수 있는 수단이다. 수정 사항이나, 업데이트 사항 등을 그때 그때 바로 반영 할 수 있도록 하는 시스템을 말한다.
깃에 대해 자세히 알아보기 전, '버전 관리 시스템'은 무엇인지에 대해서 먼저 알아보자.
✔️ 버전 관리 시스템(VCS)은 파일 내 변화를 시간의 흐름에 따라 기록했다가, 이후 필요한 상황에서 그 파일을 꺼내올 수 있는 시스템을 말한다.
우리가 어떤 문서를 작성할 때, 최초 시안에서 최종 시안으로 가는 과정까지 수 많은 수정과 업데이트가 발생한다. 우리는 그 상황에서 파일명을 '최종', '_최종', '최최종' 등으로 변경해가며 파일을 덮어쓰기 한다.
그렇게 되면 결국 최초의 파일 내용 A가 생기고, 그 위에 덮어 씌운 파일 B, 그 이후에 덮어 씌운 파일 C 등 수정을 할 때 마다 파일이 새로 생기게 된다.
🤔 이때, 과연 특정 시점의 내용으로 돌아가 그 내용을 파악하는 것이 가능할까? 물론 가능은 하다. 하지만 많은 시간과 노력을 들여야 할 것이다.
이런 상황을 대비해 활용할 수 있는 것이 바로 '버전 관리 시스템'이다.
버전 관리 시스템을 활용하면 동일한 정보에 대한 여러 버전을 관리하게 되며, 버전을 통해 시간에 따른 변경 사항 및 변경자를 확인 할 수 있다.
더불어, 이전 버전으로 돌아갈 수 있고, 다시 원래 버전으로 돌아올 수도 있으며 누가 문제를 일으켰는 지도 쉽게 파악 할 수 있다.
❓ 그렇다면 VCS의 종류로는 어떤 것이 있을까?
로컬 버전 관리 시스템에서는 'RCS (Revision Control System)을 활용한다.
RCS는 기본적으로 'Patch Set(파일에서 변경되는 부분)'을 관리한다. 이 Patch Set을 통해 모든 파일을 특정한 시점으로 되돌릴 수 있다.
중앙 집중식 버전 관리 시스템은 프로젝트 진행 중, 다른 개발자와 협업을 진행해야 할 때 사용한다. 파일 관리를 위한 서버가 별도로 존재하고, 클라이언트가 중앙 서버에서 파일을 받아서 사용한다.
CVCS를 사용하면 프로젝트에 참여한 사람들 중 누가 어떤 작업을 하는 지 쉽게 확인 가능하다는 장점이 있다. 또한 모든 클라이언트의 로컬 데이터베이스를 관리하는 것보다 VCS 하나를 관리하는 것이 훨씬 쉽기 때문에 협업 시 많이 사용된다.
하지만, 중앙 서버가 다운되는 등의 문제가 발생할 경우 그 상황 동안에는 작업이 불가능하다. 또한 하드디스크에 문제가 발생하면 모든 히스토리를 잃을 수도 있다는 단점 또한 존재한다.
분산 버전 관리 시스템은 '분산'이라는 단어에 집중한다.
즉, 개발자들이 독립적으로 작업한 다음에 변경 사항을 병합할 수 있기 때문이다.
분산 버전 관리 시스템에서의 클라이언트는 단순히 파일의 마지막 snapshot을 사용하지 않는다. 저장소를 히스토리와 더불어 전부 복제하는 방식이다. 만약 서버에 문제가 생긴다면, 복제했던 것을 통해 다시 작업을 시작할 수 있다. 또한 클라이언트 중에서 아무거나 골라도 서버를 복원할 수 있다.
따라서 다양한 협업 시 주로 사용되며, '깃'이 이 분산 버전 관리 시스템에 속한다.
✔️ 깃을 사용함으로서 얻는 장점은 매우 많다.
📚 우선, 앞서 언급했던 것처럼 쉬운 버전 관리가 가능하다.
개발자로서, 수 많은 코드들을 다루고 다른 개발자들과 협업을 진행하다 보면 잦은 업데이트 사항이 생긴다. 그럴 때마다 파일 명을 달리하여 새로 저장 해야 한다면? 한 프로젝트 당 코드 파일만 수 십, 수 백 수 천개가 될 수도 있다.
📌 깃을 사용하면 굳이 이러한 번거로운 과정 없이도 다른 개발자들과 손 쉽게 코드를 주고 받을 수 있으며, 여러 명이 동시에 한 코드를 가지고 작업하는 병렬적인 작업의 진행이 가능하다.
A라는 개발자가 코드를 작성하여 B에게 넘겨주고, B가 그 코드를 받아서 진행 한 뒤 C에게 넘겨주는 귀찮은 과정이 필요 없어진 것이다! 여러 브랜치를 형성해 작업한 뒤, 마지막에 합치는 방식을 통해 효율적인 작업이 가능하다.
또한 쉽게 이전 버전으로 이동할 수 있으며 다시 원래의 버전으로 돌아오는 것 또한 자유롭다.
📚 위에서 언급했듯, 깃은 분산 버전 관리 시스템이기 때문에 중앙 서버가 필요 없다. 즉, 인터넷이 연결 되어 있지 않은 상황에서도 작업이 가능하며, 도중에 이상이 생겨 저장소가 날라가버린다고 해도 쉽게 복구할 수 있다.
👋 깃과 깃 허브는 뗄레야 뗄 수 없는 관계이다.
그렇지만 두 가지 개념에 대해 혼동해서는 안된다!
✔️ 간단히 Git은 로컬에서 버전 관리 시스템을 운영하는 방식이고, Github는 '깃 허브'자체에서 제공해주는 클라우드 서버를 이용한다.
따라서 타 개발자들과의 협업 시, Github를 써서 오픈 소스를 공유하거나 타 개발자들과 의견을 교환할 수 있다. 만약 혼자서 작업하거나, 작은 범위에서 진행하는 협업이라면 굳이 Github를 사용하지 않고 Git으로만 진행해도 무방하다.
✔️ 깃을 사용하기 위해서 알아두어야 할 중요한 개념들에 대해 알아보자.
1️⃣ Repository (저장소) : 소스 코드들이 저장되어 있는 물리적인 공간을 의미한다. 저장소를 통해서 작업자가 진행, 변경했던 사항들에 대해 알 수 있다.
작업을 시작할 때 원격 저장소에서 로컬 저장소로 소스 코드를 복사해서 가져오고(Clone), 이후 소스 코드를 변경한 다음 커밋(Commit)한다. 이 때, 커밋한 소스는 로컬 저장소에 저장되며, Push 하기 전에는 원격 저장소에 반영되지 않는다.
2️⃣ Working Tree : 흔히 우리가 사용하는 '폴더'를 말한다.
3️⃣ Index (= Staging Area) : Commit을 실행하기 전의 저장소와 Working tree 사이에 존재하는 공간을 말한다. Working Tree -> Index -> Commit 순의 절차를 거친다.
4️⃣ Commit : 작업 과정들에 대한 점검을 마친 뒤, 저장소에 남기는 과정을 의미한다. 각각의 커밋 단계는 의미 있는 단계이다. 따라서 커밋 로그를 남긴다. git log라는 명령어를 통해 커밋된 사항들에 대해 확인 할 수 있다.
5️⃣ Checkout : 특정 시점이나 branch의 소스 코드로 이동하는 것을 의미한다. 이 과정을 통해 과거 여러 시점의 소스 코드로 이동할 수 있다.
6️⃣ Branch : Commit 단위로 구분된 소스 코드 타임라인에서 분기해서 새로운 commit을 쌓을 수 있는 가지를 만드는 것을 말한다. Branch에서 작업을 완료하면, Merge 작업을 수행한다.
7️⃣ Merge : Branch와 Branch의 내용을 합치는 작업, 즉 병합을 말한다. Branch와는 다소 반대되는 개념이다. 병합 과정 중 두 branch에서 하나의 동일한 파일에서 서로 다른게 수정한 경우 충돌이 발생하며, 병합이 일시정지 된다. 이 때, 충돌 부분에 대해 직접 수정하거나 Merge Tool 등을 활용하여 충돌을 해결한 뒤 병합을 계속 진행한다.
✔️ 깃의 명령어 중 자주 쓰이는 주요 명령어들에 대해 알아 보자.
git status : 깃 저장소의 상태를 확인한다. 이 명령어를 통해 현재 상태가 어떤 지 수시로 확인 가능하다.
git add : 커밋에 파일의 변경 사항을 포함하도록 한다. 이 명령이 저장소에 새 파일들을 직접적으로 추가하진 않는다.
git commit : "git commit -m '저장명'" 등과 같은 명령어로 주로 사용한다. 이 명령어를 통해 커밋을 생성하고, 변경 사항을 확정하여 반영한다.
git clone : 기존 소스 코드 다운로드 및 복제한다. 즉, 원격 저장소의 저장소를 로컬에서 이용할 수 있도록 복사해 가져온다.
git log : 나의 커밋 내역에 대해 알고 싶을 때 사용하면 현재 커밋 목록들을 확인 가능하다.
git checkout : 브랜치에서 브랜치로 이동 가능하다. 현재 버전에서 이전 버전의 커밋으로 이동하거나 변경 전의 브랜치로 접근 가능하다.
git checkout master : 이전 버전, 변경 전 브랜치에서 다시 현재의 (master) 브랜치로 되돌아 올 수 있다.
git push : 소스 코드의 변경 사항을 원격 저장소에 반영한다.
git pull : 원격 저장소의 변경 내용이 현재 디렉토리로 가져와진 뒤, (fetch) 병합된다.
git merge : 변경 사항 등이 모두 확정되고 난 후, 브랜치들을 병합한다. 작업 마무리 단계에서 시행한다.
✨ TIL을 마무리하며
오늘은 약간 버거운 하루였다. 아주 많은 양의 지식을 하루 만에 다량으로 습득한 날..
그래서 피곤하지만 글로 정리하며 다시 한 번 기록하고자 하는 마음이다!
앞으로 깃과 깃 허브를 적절히 활용하면서 효율적인 코드 작성 및 관리를 해야겠다.
개발의 세계는 알면 알수록 신기하고, 재밌고, 또 어렵다 😂
꾸준한 공부만이 살 길이라고 생각한다. 화이팅..!
지현님 넘 멋있어용~ :)