<p style="text-align:justify;">요즘 깃(Git)이나 깃허브(GitHub)로 대표되는 버전 관리는 협업을 위한 툴이라는 인식이 강합니다. 여러 개발자가 하나의 프로젝트에 대해서 작업할 때 독립적으로 작업하기 위해, 그리고 릴리즈된 버전과 개발 중인 버전을 구분하기 위해 브랜치를 나누기 때문이죠.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">이러한 인식으로 혼자 하는 프로젝트에서는 버전 관리를 굳이 신경 쓰지 않는 경우가 많습니다. 취업을 위한 개인 프로젝트, 현직 개발자가 하는 사이드 프로젝트, 심지어 회사 프로젝트도 규모가 크지 않아 혼자 하는 상황이라면, 브랜치와 커밋을 관리하기보다는 코드를 작성하는 데 더욱 집중합니다. 다른 개발자의 코드와 내 코드가 섞이는 것도 아니고, 모든 코드의 권한이 나 자신에게 있기 때문에 굳이 버전 관리가 필요한가도 싶죠. 커밋 메시지를 대충 적어도, 한 커밋에 이것저것 아무렇게나 넣어도 상관없을 것 같습니다. 열심히 관리해 봤자 볼 사람도 없으니 귀찮기만 하죠.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">그러나 버전 관리는 잘 활용하면 혼자 하는 프로젝트에서도 강력한 도움을 줄 수 있습니다. 이번 글에서는 협업을 위한 버전 관리에서 벗어나, 개인 프로젝트에서의 버전 관리가 프로젝트의 진행에서 그리고 개발자로서의 발전에 어떤 도움을 주는지 활용법을 알아보겠습니다.</p><div class="page-break" style="page-break-after:always;"><span style="display:none;"> </span></div><h3 style="text-align:justify;"><strong>버전 관리 알아보기</strong></h3><p style="text-align:justify;">“버전 관리”는 말 그대로 코드의 버전을 관리하는 것입니다. 이렇게 코드의 변경 사항을 시간에 따라 기록하고 관리하는 시스템을 버전 관리 시스템 (Version Control System, VCS)이라고 합니다. 이름에서 알 수 있듯이 버전 관리는 협업과 큰 관련이 없습니다. 그저 코드의 변경 내역을 관리할 뿐이죠.</p><p style="text-align:justify;"> </p><figure class="image image_resized" style="width:100%;"><img src="https://www.wishket.com/media/news/2973/image1.png"><figcaption>깃허브의 옥토캣 <출처: <a href="https://unsplash.com/ko/%EC%82%AC%EC%A7%84/%ED%9D%91%EC%9D%B8%EA%B3%BC-%EB%B0%B1%EC%9D%B8-%ED%8E%AD%EA%B7%84-%EC%9E%A5%EB%82%9C%EA%B0%90-wX2L8L-fGeA"><u>Unsplash</u> - <u>Roman Synkevych</u></a>></figcaption></figure><p style="text-align:justify;"> </p><h4 style="text-align:justify;"><strong>1) 깃과 깃허브</strong></h4><p style="text-align:justify;">버전 관리가 익숙하지 않으면 깃과 깃허브를 혼동하고는 합니다. 깃과 깃허브는 둘 다 버전 관리에 주로 사용되지만, 전혀 다른 개념입니다.</p><p style="text-align:justify;"> </p><ul><li style="text-align:justify;">깃: 버전 관리 <strong>시스템</strong></li><li style="text-align:justify;">깃허브: 깃 저장소를 호스팅하는 <strong>웹 서비스</strong></li></ul><p style="text-align:justify;"> </p><p style="text-align:justify;">즉, 버전 관리는 깃의 역할이며, 깃허브는 이것을 온라인에 저장할 수 있도록 호스팅하는 서비스일 뿐입니다. 깃허브 외에도 깃랩, 빗버킷등 다양한 깃 호스팅 사이트가 있습니다. 또 이러한 온라인 호스팅 사이트를 이용하지 않더라도, 로컬에서도 충분히 깃 관리가 가능합니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">이번 글에서는 대표적인 버전 관리 시스템인 깃을 위주로 설명하려고 합니다. 다만 깃 외의 다른 시스템들도 버전을 관리한다는 목적은 같으므로, 어떠한 버전 관리 시스템을 이용하더라도 모두 적용할 수 있습니다.</p><p style="text-align:justify;"> </p><h4 style="text-align:justify;"><strong>2) 기본 용어</strong></h4><p style="text-align:justify;">우선 개인 프로젝트에서의 버전 관리를 위한 기본적인 깃 용어를 몇 가지를 살펴보겠습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;"><strong>커밋</strong>은 코드의 변경 사항을 저장하는 작업입니다. 하나의 커밋은 코드의 변경 사항과 커밋 메시지로 구성됩니다. 변경 사항을 잘 나타낼 수 있는 커밋 메시지를 작성하는 것이 효율적인 커밋의 핵심이라고 할 수 있습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;"><strong>브랜치</strong>는 독립적인 개발을 위해 코드를 분기시킨 것입니다. 개인 프로젝트에서는 여러 기능을 동시에 개발하려고 할 때, 실험적인 기능에 도전해 보고자 할 때 주로 사용할 수 있습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;"><strong>병합</strong>은 여러 브랜치를 합치는 것입니다. 독립적으로 진행한 개발이 완료되었을 때, 해당 사항을 병합시킴으로써 프로젝트에 실제로 반영시킬 수 있습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;"><strong>리포지토리</strong>는 코드의 변경 이력을 저장하는 공간입니다. 여러 커밋과 브랜치 등 버전 관리를 위한 데이터는 모두 리포지토리 안에 저장됩니다. 일반적으로 하나의 프로젝트를 하나의 리포지토리로 관리하지만, 항상 일대일로 대응되는 것은 아닙니다. 실제로 구글은 대부분의 프로젝트를 단 하나의 리포지토리로 관리하는 모노-리포 방식으로 유명합니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;"> </p><h3 style="text-align:justify;"><strong>버전 관리 활용 1. 코드 복구하기</strong></h3><p style="text-align:justify;">열심히 코드를 작성하다가 어느 순간 하나 둘씩 꼬이기 시작하고, 그러다 결국 코드가 전부 엉켜버려서 모두 엎어야 했던 경험이 있으신가요? 분명 어느 순간까지는 괜찮았던 것 같은데, 정신을 차려보니 아무것도 할 수 없는 코드가 되어 있습니다. Ctrl+Z로 되돌리는 것도 한계가 있고, 언제까지 괜찮았는지도 모르겠습니다. 처음부터 다시 시작하든, 이 악물고 어떻게든 엉킨 코드를 풀든, 힘든 고행의 길만 남아있죠.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">이때 버전 관리를 잘해 놓았다면 스트레스받는 상황이 아니라, 몇 번의 명령어만으로 해결할 수 있는 간단한 일이 됩니다. 그저 <strong>작업한 커밋 내역을 살펴보고, 괜찮아 보이는 시점으로 돌아가기만 하면 됩니다.</strong> 깃에서는 이러한 작업을 몇 개의 명령어로 수행할 수 있습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">우선 git log를 활용해 지금까지 작업한 커밋 내역을 확인합니다. 커밋 메시지를 보고 적당한 시점으로 git reset만 해주면 됩니다. 마지막 커밋으로 돌아가고, 커밋되지 않은 모든 변경 사항을 삭제하려면 git reset–hard HEAD를 사용할 수 있습니다. </p><p style="text-align:justify;"> </p><p style="text-align:justify;">과거의 특정 커밋으로 돌아가고, 그 이후의 모든 커밋을 삭제하기 위해서는 git log로 확인한 해당 커밋의 해시를 활용해 git reset –hard <해시>와 같이 활용합니다. 만약 과거의 커밋으로 돌아가고는 싶지만, 그 이후의 커밋을 삭제하지 않고 남겨두고 싶다면 git checkout <해시>를 할 수 있습니다. 이 명령어를 사용하면 특정 브랜치에 속하지 않은 독립적인 커밋을 가리키게 됩니다. 여기에서부터 코드를 이어 나가다가 코드가 마음에 든다면, git branch를 통해 새로운 브랜치를 만들어 코드를 커밋하면 됩니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">이처럼 버전 관리를 활용하면 코드가 얼마나 망가졌던지, 잘 작성해 놓은 코드로 언제든지 돌아갈 수 있습니다. 되돌아간 시점에서 다시 코드를 작성할 수 있으니, 억지로 코드를 살리려고 스트레스받지 않아도 됩니다. 대신 새롭게 알게 된 것들을 적용하여, 다시 코드를 작성해 보면 좋습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;"> </p><h3 style="text-align:justify;"><strong>버전 관리 활용 2. 여러 작업 독립적으로 하기</strong></h3><p style="text-align:justify;">언제든지 돌아갈 수 있는 코드가 있다는 것은 어떤 코드라도 마음껏 시도해 볼 수 있다는 의미입니다. 조심스럽게 진행해야 하는 큰 규모의 리팩토링이나, 여러 기능의 추가 등 <strong>새로운 형태의 코드 작성에 도전</strong>할 수 있습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">그러나 종종 이러한 작업들은 서로 겹치기도 합니다. 프로젝트의 코드가 별로인 것 같아 리팩토링하고 있는데, 새로운 기능을 만들어야 하는 경우처럼 말이죠. 리팩토링이 한창 진행 중인 코드에 새로운 기능을 만들면 코드가 엉키기 쉽습니다. 이럴 때 <strong>브랜치를 활용하여 코드를 분리한다면, 진행 중인 실험적 코드를 서로 독립적으로 작업</strong>할 수 있게 됩니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">큰 규모의 리팩토링이나 신기능을 만들 때 git branch를 통해 작업 공간을 분리해 보세요. 그리고 작업이 완료되지 않았는데 다른 작업을 시작할 때가 오면, 상위 브랜치에서 다시 별도의 브랜치를 생성해 보세요. 여러 작업을 서로 독립적으로 작업할 수 있으므로, 리팩토링이나 새로운 코드를 언제든 시도할 수 있습니다.</p><p style="text-align:justify;"> </p><figure class="image image_resized" style="width:100%;"><img src="https://www.wishket.com/media/news/2973/image2.png"><figcaption>기능별 브랜치 관리 <출처: 작가></figcaption></figure><p style="text-align:justify;"> </p><p style="text-align:justify;">예를 들어, develop이라는 이름의 브랜치에서 작업 중이라면, 리팩토링을 위해서는 git branch refactoring 후, git checkout refactoring으로 브랜치를 생성하고 해당 브랜치로 이동할 수 있습니다. </p><p style="text-align:justify;"> </p><p style="text-align:justify;">리팩토링 도중 로그인 기능을 구현해야 한다면, git checkout develop를 통해 상위 브랜치로 이동하고, git branch login 후 git checkout login으로, 리팩토링 중인 코드와는 무관하게 로그인 코드를 작업할 수 있습니다. (git branch <브랜치> 후 git checkout <브랜치>는 git checkout -b <브랜치> 로 줄여서 사용 가능합니다.) </p><p style="text-align:justify;"> </p><p style="text-align:justify;">작업이 끝나면 git merge를 통해 브랜치의 변경 사항을 상위 브랜치에 반영합니다. 이렇게 하면 하나의 작업이 완벽하게 완성되었을 때만 작업 결과를 반영할 수 있게 됩니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">로그인 기능의 작업이 완료되었다면, git checkout develop로 이동해 git merge login을 통해 로그인의 작업 결과를 반영할 수 있습니다. 그리고 ‘git checkout refactoring’으로 리팩토링 브랜치로 돌아간 후, ‘git merge develop’를 실행하면 리팩토링 브랜치에서도 로그인 코드를 확인할 수 있습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;"> </p><h3 style="text-align:justify;"><strong>버전 관리 활용 3. 과거로부터 배우기</strong></h3><p style="text-align:justify;">우리는 한 번 경험했던 일이라도 금방 잊어버립니다. 분명 프로젝트를 하면서 전에 했던 작업인데, 어떻게 했는지 기억나지 않아 자료 조사부터 다시 해야 하죠. 작성해 둔 코드를 찾아본다고 해도, 하나의 작업이 하나의 코드에만 연관된 것이 아니라, 관련 코드를 모두 찾아보느라 시간을 허비합니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">예를 들어, 지도 API를 연동해 방문한 장소에 그 이력을 핀 형식으로 표시해야 하는 상황을 한 번 겪었다면, API 연동, 핀 표시, 방문 이력 UI, 서버에 데이터 요청과 파싱 등 많은 작업을 했을 겁니다. 여러 파일에 걸쳐 있는 코드를 살펴보기 위해선 일일이 파일을 열어 찾아봐야 합니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">이때 커밋을 잘해 놓았다면 관련된 변경 사항을 하나의 커밋에서 확인할 수 있어, 이러한 수고를 덜 수 있습니다. 예전에 작업할 때 어떤 코드들을 작성했고, 이것들이 어떻게 연관되어 있는지를 한눈에 파악할 수 있죠.</p><p style="text-align:justify;"> </p><figure class="image image_resized" style="width:100%;"><img src="https://www.wishket.com/media/news/2973/image3.png"><figcaption>관련된 작업들로 구분된 커밋 <출처: 작가></figcaption></figure><p style="text-align:justify;"> </p><p style="text-align:justify;">또 시간이 지나면서 새로운 기능이 계속해서 쌓인다면, 코드로 구분이 점점 더 어려워집니다. 만약 여러 지도를 지원했다면 다양한 지도 API 연동을 위한 리팩토링이 발생하고, 방문 이력뿐만 아니라 해당 지점의 상세 정보 표시가 추가됩니다. 또한 실시간 데이터를 반영하면서 서버에 보내는 요청 방식이 달라졌다면, 찾고자 하는 코드는 이미 알아보기 힘든 상황이 되어 있을 겁니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">그러나 커밋 히스토리는 모든 커밋에 대해 스냅샷을 저장하므로, 기능을 처음 구현했을 때 즉, 필수적인 변경 사항만 골라서 확인할 수 있죠. 이에 더해 여러 지도 API를 지원하기 위한 리팩토링은 어떻게 했는지, 실시간 데이터 요청은 어떻게 처리했는지 등 잘 정리된 경험을 쉽게 찾을 수 있습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;"> </p><h3 style="text-align:justify;"><strong>올바르게 커밋하기</strong></h3><p style="text-align:justify;">지금까지 살펴본 버전 관리 활용법을 통해 최대 효율을 이끌어내려면, 코드를 작성하는 과정에서 커밋을 올바르게 하는 것이 중요합니다. 프로젝트는 지향하는 하나의 큰 목표가 있습니다. 이 목표는 기능이나 사람, 우선순위 등에 따라 여러 작은 목표로 나뉘고, 이 목표들은 다시 구현 과정 등의 더 작은 목표들로 세분화됩니다. 이러한 과정을 통해 계속 목표를 점점 더 작게 구체화하다 보면, 간단하고 명확하게 구현할 수 있는 목표에 도달하게 됩니다. 저는 이것을 최소 목표 단위라고 부릅니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">예를 들어, 블로그 서비스에 게시글 리스트를 보여준다는 목표가 있을 때, 이것은 파이어베이스 연동, 게시글 리스트 가져오기, 리스트에 스타일 적용하기 등의 작은 목표로 나누어질 수 있습니다. 이때 최소 목표 단위라고 부르기 위한 목표의 크기는 사람마다 다를 수 있습니다. 게시글 리스트를 가져오는 작업과 스타일 적용하기를 합쳐 최소 단위라고 볼 수도 있습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">커밋은 하나의 최소 목표 단위를 담당해야 하기 때문에, 여러분만의 최소 목표 단위를 찾는 것이 중요합니다. 이때 커밋의 크기가 너무 커지지 않도록, 그리고 커밋에 포함되는 코드 변경 사항이 최소 단위 목표에만 집중될 수 있도록 신경 써야 합니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">만약 게시글 리스트를 가져오는 것과, 스타일을 적용하는 것 모두 간단하다면 하나의 커밋으로 합칠 수 있을 겁니다. 그러나 게시글 리스트를 가져올 때 정렬이나 특정 조건으로 필터링, 페이지네이션 등 추가적인 세부 사항을 구현하거나, 스타일에서도 라이트/다크 모드, 반응형 등 다뤄야 할 구체적인 로직이 있다면, 커밋을 나누는 것이 좋을 수도 있습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">핵심은 프로젝트를 구성하는 논리들이 서로 뒤섞이지 않고, 커밋으로 깔끔하게 정리된 상태를 유지하는 것입니다. 이렇게 목표를 세분화하고, 하나의 목표에만 집중하는 연습을 하다 보면, 프로젝트가 차근차근 진행되는 느낌을 받을 수 있습니다. 이때 선택과 집중에 대한 역량이 향상되고, 프로그래밍 실력도 크게 발전할 수 있는 것이죠.</p><p style="text-align:justify;"> </p><p style="text-align:justify;"> </p><h3 style="text-align:justify;"><strong>마치며</strong></h3><p style="text-align:justify;">버전 관리에 소홀한 프로젝트는 자칫 길을 잃기 쉽습니다. 조그마한 실수도 프로젝트가 진행에 따라 눈덩이처럼 커질 수 있고, 결국 프로젝트 전체가 걷잡을 수 없이 휘청일 수도 있습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">이때 버전 관리는 정신없이 달려가는 프로젝트에서 여러분의 작업 내역을 지켜주고, 목표 세분화를 통해 집중할 논리 단위를 고민함으로써, 더욱 성장할 수 있게 해주는 중요한 습관입니다. 만약 프로젝트를 혼자 진행하게 되더라도, 버전 관리를 통해 프로젝트 관리는 물론, 더욱 실력 있는 개발자가 되기 위한 기회로 활용해 보길 바랍니다.</p><p style="text-align:justify;"> </p><p style="text-align:center;"><span style="color:#999999;">©요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.</span></p>