1. Git이란?
개발자라면 git을 한번 써봐야 한다는 소리는 누구나 한 번씩 들어본 경험이 있을 것입니다. 또한 요즘 신입 개발자들은 자신을 pr 하기 위해 github에 자기 작업물들을 올리는 것이 기본 소양입니다.
하지만 실제 실무를 경험해보지 못한 신입 개발자가 git으로 프로젝트를 version 별로 관리하는 경험하기란 쉽지 않습니다. 그래서 최소한 면접장에 가서 git이 어떠한 기능이 있고, 특징이 무엇인지 말할 수 있도록 자세하게 알아보겠습니다.
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.
2. 왜 Git을 써야 하나?
소스 코드는 소프트웨어 기업들의 핵심 자산입니다. 거의 대부분의 소프트웨어는 서비스를 시작하고도 새로운 기능을 추가하거나 유지보수를 합니다.
VSC에 대한 지식이 없던 시절 필자의 팀 프로젝트는 파일들의 수정사항을 복사본을 생성하면서 관리했습니다.
위와 같은 대참사를 피하고자 개발자들은 소스 코드를 안정적으로 관리하고, 시간에 따른 코드의 변경 사항을 추적하고 여러 명이 작업한 파일들을 하나의 저장소로 통합하는 기능을 필요로 했습니다.
이러한 기능을 제공하는 것이 Version Control System
입니다.
3. 버전 관리 시스템(Version Control System)
버전 관리 시스템은 파일 변화를 시간에 따라 기록했다가 나중에 특정 시점의 버전을 다시 꺼내올 수 있는 시스템입니다. VCS가 제공하는 기능은 다음과 같습니다.
- 무언가 잘못되었을 때 복구를 돕기 위하여
- 프로젝트 진행 중 과거의 어떤 시점으로 돌아갈 수 있게 하기 위하여
- 여러 사람이 같은 프로젝트에 참여할 경우, 각자가 수정한 부분을 팀원 전체가 동기화하는 과정을 자동화하기 위하여
- 소스 코드의 변경 사항을 추적하기 위하여
- 소스 코드에서 누가 수정했는지 추적하기 위하여
- 대규모 수정 작업을 더욱 안전하게 진행하기 위하여
- 가지내기(Branch)로 프로젝트에 영향을 최소화하면서 새로운 부분을 개발하기 위하여
- 접붙이기(Merge)로 검증이 끝난 후 새로이 개발된 부분을 본류(trunk)에 합치기 위하여
- 많은 오픈 소스 프로젝트에서 어떠한 형태로든 버전 관리를 사용하고 있으므로
- 코드의 특정 부분이 왜 그렇게 쓰였는지 의미를 추적하기 위하여
3.1 로컬 버전 관리 시스템(Local Vesion Control System)
로컬 버전 관리 시스템은 개인 컴퓨터에서 간단한 데이터베이스를 통해 파일의 변경 정보를 관리하는 시스템입니다.
많이 쓰는 VCS 도구 중에 RCS(Revision Control System)라고 부르는 것이 있는데 오늘날까지도 아직 많은 회사가 사용하고 있습니다.
하지만 로컬 버전 관리 시스템은 개인이 간단히 사용할 수 있는 장점은 있지만, 여러 개발자가 협업하는 데 사용하기엔 적절하지는 않습니다.
3.2 중앙집중식 버전 관리 시스템(Centralized Vesion Control System)
중앙집중식 버전 관리는 저장소를 서버로 올려서 여러 개발자가 함께 작업할 수 있게 한 시스템입니다. 원격 저장소가 모든 파일의 이력을 관리하고 각 개발자는 서버로부터 특정 버전의 스냅샷을 로컬로 내려받아 협업합니다. 이때 특정 버전의 스냅샷을 받는 것을 체크아웃(checkout)
이라고 합니다.
하지만 CVCS에도 몇 가지 치명적인 단점이 있습니다.
- 서버에 문제가 생기면 버전 관리를 하지 못한다.
- 서버의 하드디스크 문제가 생기면 프로젝트의 모든 기록을 잃는다.
- 오프라인 상태에서는 사용할 수 없다.
- 모든 버전 관리 동작이 서버를 통해 이루어지기 때문에 서버의 부하가 크다.
3.3 분산 버전 관리 시스템(Distributed Version Control System)
분산식 버전관리 시스템은 모든 버전관리를 서버가 독점하면서 생기는 여러 문제를 해결한 버전 관리 시스템입니다.
분산 버전 관리 시스템은 중앙식과는 다르게 서버뿐만 아니라 모든 로컬 저장소에 파일과 히스토리까지 전부 복제합니다.
분산되어 있어서 서버에 문제가 생겨도 다른 로컬에 복제된 것으로 복구할 수 있습니다.
또한 여러 변경 사항들을 오프라인 상태에서 로컬에 기록하고 있다가 한 번에 서버에 반영하기만 하면 되기 때문에 서버의 부하도 줄일 수가 있습니다.
GitHub는 Git 저장소를 호스팅 하는 원격 서버를 제공하는 서비스로, Git 개발자가 원격 저장소를 위해 직접 서버 구축을 할 필요가 없습니다.
4. Git의 특징
- 오프라인 작업이 가능하다.
- 속도가 빠르다.
- git의 거의 모든 명령은 로컬 파일과 데이터만 사용하기 때문에 다른 네트워크에 접속할 필요 없습니다. 마지막에 원격 저장소에 push 할 때만 서버에 접속하기만 하면 됩니다.
- 무결성
- git은 데이터 저장 전 항상 체크섬을 구하고, 그 체크섬으로 데이터를 관리합니다. 체크섬은 40자 길이의 16진수 문자열이고 해시를 이용하여 구합니다.
- 데이터를 추가만 한다.
- 일단 git으로 작업한 내용을 commit 하고 나면 데이터베이스에 데이터가 추가됩니다. 데이터를 삭제할 방법이 없습니다. 다만 이전 스냅샷으로 되돌릴 수 있어서 크게 걱정할 필요는 없습니다.
5. Git의 구조
Git은 작업폴더에 있는 파일들을 총 5가지 상태로 분류하고 각 명령들을 수행합니다.
- Untracked(추적되지 않음)
- Git 저장소에 새로 생성된 파일이나 이전에 Git에서 추적되지 않았던 파일이다.
- Git은 이 파일을 관리하지 않고 변경 사항을 추적하지 않는다.
- Modified(수정됨)
- Git에서 추적 중인 파일이 수정되었지만, 아직 커밋되지 않은 상태입니다.
- 수정된 파일의 변경 사항은 다음 커밋에 포함될 것입니다.
- Staged(스테이징 됨)
- 수정된 파일 중에서 다음 커밋에 포함시킬 파일을 선택한 상태입니다.
- git add 명령을 사용하여 파일을 스테이징 할 수 있습니다.
- Committed(커밋됨)
- 스테이징 된 파일들이 커밋되어 Git 저장소에 영구적으로 기록된 상태입니다.
- 커밋된 파일은 변경 이력과 함께 저장소의 특정 시점을 나타냅니다.
- Ignored(무시됨)
.gitignore
파일에 명시된 패턴에 일치하는 파일들은 Git에서 완전히 무시됩니다.- 일반적으로 컴파일된 바이너리 파일, 개인 설정 파일 등을 무시하는 데 사용됩니다.
또한 수정한 파일을 Local에 저장하고 모든 개발자가 공유하는 Remote Repository에도 반영하기 위해 아래와 같은 명령들을 수행합니다.
- git init
- 새로운 Git 저장소를 초기화합니다. 이 명령은 디렉터리를 Git 저장소로 만들고, 버전 관리를 시작할 수 있도록 합니다.
- git clone
- 원격 저장소에서 로컬로 프로젝트를 복제합니다. 이 명령은 원격 저장소의 내용을 가져와 로컬에서 작업할 수 있도록 합니다.
- git add
- 작업 디렉터리에서 변경된 파일을 스테이징 영역에 추가합니다. 변경된 파일을 커밋할 준비 단계로 이동시킵니다.
- git commit
- 스테이징 영역의 변경 내용을 커밋하여 버전을 기록합니다. 커밋은 변경 사항에 대한 설명과 함께 고유한 식별자를 갖습니다.
- git merge
- 브랜치를 병합하는 명령입니다. 다른 브랜치의 변경 내용을 현재 브랜치에 통합합니다.
- git push
- 로컬 저장소의 커밋을 원격 저장소로 업로드합니다. 이 명령은 로컬 커밋을 원격 저장소에 공유하고 다른 사람과 협업할 때 사용됩니다.
- git pull
- 원격 저장소의 변경 내용을 가져와 현재 브랜치에 병합합니다. 이 명령은
git fetch
와git merge
를 결합한 작업을 수행합니다.
- 원격 저장소의 변경 내용을 가져와 현재 브랜치에 병합합니다. 이 명령은
6. 충돌(Conflict)
충돌은 여러 개발자가 각자의 로컬에서 동일한 파일의 동일한 부분을 수정한 후 원격저장소에 Push
했을 때 발생하는 상황입니다.
충돌이 발생한 파일을 개발자들은 수동으로 확인하고 수정하여 충돌을 해결해야 합니다. Git은 충돌이 발생한 파일을 알려주고 이를 확인한 개발자는 해당 파일을 이전 상태로 되돌려야 충돌을 해결할 수 있습니다.
하지만 이렇게 매번 push
할 때마다 merge
를 수행하게 되면 commit history
가 복잡해질 수가 있습니다.
우리는 VCS의 강력한 기능 중 하나인 branch
를 사용하여 충돌 상황을 최소화할 수 있습니다. branch
에 대해서는 다음 시간에 알아봅시다.