버전관리 시스템(Version Control System) 이란?
파일 변화를 시간에 따라 기록했다가 나중에 특정 시점의 버전을 다시 불러올 수 있는 시스템을 의미한다. 이를 통해 파일을 잃어버리거나 잘못 고쳤을 때 쉽게 복구가능하다.
로컬 버전 관리
간단히 데이터 베이스를 사용해 파일의 변경 정보를 관리
실수하기 쉽다는 단점 존재
중앙집중식 버전 관리
서버가 별도로 있고 클라이언트가 중앙 서버에서 파일을 받아서 사용하는 방식
중앙 서버에 문제가 발생하면 치명적이라는 단점 존재
분산 버전 관리
단순하게 마지막 스냅샷을 checkout 하지 않고, 저장소를 히스토리와 더불어 전부 복제
서버에 문제가 생기면 복제물로 다시 작업을 시작할 수 있음
Git은 분산 버전 관리 시스템으로 소스 코드 및 파일을 관리하기 위한 도구이다.
대충 깃이 분산 버전 관리 시스템이니까. 복구나 코드 비교가 쉬운 것은 알게 되었다.
좀 더 구체적인 예시로 장점을 알아보자
Git의 필요성
- 나와 내 동료가 같은 웹사이트에서 동시에 같은 'A'페이지를 업데이트하고 있다고 하자.
- 나는 무언가를 변경하고 저장한 다음 웹사이트에 'A'페이지를 업로드한다.
- 그런데 이때 동료가 동시에 'A'페이지에서 작업을 할 때 문제가 발생된다.
- 만약 확인하지 않고 동시에 작업을 한다면 누군가의 작업은 겹체 쓰일 것이고 지워질 것이기 때문이다.
- Git은 이와 같은 일을 사전에 방지해 준다.
- 나와 동료는 같은 페이지에 각자 수정사항을 업로드할 수 있고, 두 개의 복사본을 저장한다.
- 만약 내가 업로드할 때 충돌이 난다면 깃에서 이를 쉽게 해결할 수 있다.
때문에 깃의 필요성은 매우 중요하다.
또한 이로 인한 장점으로는 여러 명이 동시에 작업하는 병렬 개발이 가능하다는 것이 있다.
또한 분산 버전 관리 시스템이기에 인터넷이 연결되지 않은 곳에서도 개발을 진행할 수 있다.
버전 관리를 통해 체계적인 개발이 가능하다.
Git 작동 구조
Untracked : Working Directory에 존재는 하지만 git이 관리를 하지 않는 파일들의 상태이다.
- Working Directory에 새롭게 만들어진 파일들이 이에 해당한다.
Unmodified : 수정을 하지 않은 파일 상태이다.
- Unmodified 상태의 파일은 한 번 이상 commit 된 파일 중 수정을 하지 않은 파일 또는 다른 저장소의 파일들을 clone 하였을 때의 파일들을 의미한다.
Modified : 수정을 한 파일의 상태이다.
- Unmodified 상태의 파일을 수정을 하게 되면 Modified 상태 파일이 된다.
Staged : commit 하고자 하는 파일의 상태이다.
- 위에서 살펴본 Staging Area 영역에 있는 파일의 상태이다.
- Untracked 상태의 파일 혹은 commit 된 이후 수정이 진행된 파일(Modified 상태의 파일)을 git add 명령을 수행하게 되면 해당 파일들은 Staged 상태가 된다.
- git add 명령 이후 git status 명령을 실행하면 "changes to be committed : 파일이름"을 볼 수 있는데 해당 문구에 있는 파일이 바로 Staged 상태 파일이다.
로컬 저장소에서 작업한 내용을 원격 저장소로 보내거나, 원격 저장소의 최신 정보를 로컬로 당겨온다
로컬 vs 인덱스 vs 저장소
- 로컬 (Local) Working Directory, Working Copy: 프로젝트 폴더 내의 파일들을 의미한다.
- 인덱스 (Index), Staging Area, Cache: 커밋할 준비가 된 파일의 내용들을 담는 영역이다.
- . git/index 파일로 실제로 존재한다.
- 로컬에 발생한 변경 사항을 인덱스에 반영하기 위해 git add 명령어를 사용할 수 있다.
- 저장소 (Repository): 데이터를 저장하는 곳으로. git/objects/ 폴더에 저장된다.
- Blob 파일과 같이 버전 관리되는 파일의 내용들이 저장된다.
오브젝트 파일
- Blob 파일: 버전 관리하는 각 파일의 내용을 의미한다.
- 파일의 내용을 해싱 기법을 이용하여 Blob 파일의 이름을 얻는다.
- 내용이 동일한 파일들은 하나의 Blob 파일로 저장되어 중복을 피할 수 있다.
- Commit 파일: 하나의 버전을 생성하는 것을 의미하며, 하나의 Tree 파일을 가리킨다.
- Tree 파일에는 Blob 파일의 주소와 직전 버전에 해당하는 Commit 파일의 주소가 기록된다.
- Tree 파일: 커밋 시점의 파일들을 담고 있으며, 파일명과 해당 파일의 Blob 파일 주소가 기록된다.
tag - Git의 특정 commit에 tag를 달면 tag object가 생성된다.
Git 주요 명령어
git init
- . git 폴더를 생성하여 Git으로 버전 관리를 시작할 수 있도록 한다.
git add <파일명>
- 로컬의 변경 사항을 인덱스에 반영하기 위한 명령어이다.
- 새로 생성된 파일이나 수정/삭제된 파일을 추가한다.
- 파일명 대신. 기호를 사용하면 현재 디렉터리의 모든 파일이 인덱스에 반영된다.
git commit -m <메시지>
- 인덱스의 내용을 바탕으로 새로운 버전(Commit 파일)을 생성하는 명령어이다.
- 현재 시점의 파일들의 스냅샷을 찍어 저장한다.
- 메시지에는 해당 버전에 대한 설명을 작성한다.
git status
- 로컬의 내용과 인덱스의 내용을 비교하여 추가할 파일들과 커밋할 파일들의 목록을 표시한다.
- 변경 사항이 없는 경우 "nothing to commit" 메시지가 출력된다.
Git 브랜치
HEAD와 브랜치 포인터 HEAD는 현재 체크아웃되어 있는 브랜치의 포인터를 가리키는 포인터이다.
브랜치 포인터는. git/refs/heads/{브랜치명}에 저장되며, 해당 브랜치의 최신 Commit 파일을 가리킨다.
git reset & git checkout
- git reset 명령어를 통해 브랜치 포인터를 지정된 Commit 파일로 변경할 수 있다.
- git checkout 명령어를 통해 HEAD를 지정된 브랜치 포인터로 변경할 수 있다.
git merge
- git merge 명령어를 통해 지정된 브랜치의 내용을 현재 브랜치와 병합하여 새로운 Commit 파일을 생성하고, 브랜치 포인터를 변경한다.
- 병합할 때 충돌이 발생할 수 있으며, 충돌이 발생한 파일은 수동으로 해결해야 한다.
HEAD와 브랜치 포인터의 히스토리 ORIG_HEAD는 git reset 명령을 수행하기 전의 HEAD 값을 기록한 것이다.. git/logs/refs/heads/{브랜치명}에는 브랜치 포인터의 변경 이력이 저장됩니다.
원격 저장소 GitHub
원격 저장소
- 원격 저장소는 소스 코드를 관리하는 서버로, GitHub에서 제공하는 Repository가 대표적이다.
- 원격 저장소를 활용하면 팀원과의 협업이 용이해진다.
git remote
- git remote add 명령어를 통해 로컬과 원격 저장소를 연결한다.
- 원격 저장소 별칭으로는 보통 origin을 사용한다.
- git remote -v 명령어를 통해 연결된 원격 저장소들의 정보를 확인할 수 있다.
git push/fetch/pull
- git push 명령어를 통해 변경 사항을 원격 저장소로 전송한다.
- git fetch 명령어는 원격 저장소의 최신 내용을 로컬로 가져오며, git pull 명령어는 fetch와 merge를 한 번에 수행한다.
원격 브랜치 포인터
- . git/refs/remote/{원격 저장소 별칭}/{브랜치명}에 원격 브랜치의 포인터가 저장되며, push/fetch/pull 명령어를 실행할 때 업데이트된다.