SW 개발과 데이터 관리의 기술이 증대되고 있습니다. 이 환경에서 다양한 협업과 작업 흐름이 필연적으로 뒤따르게 됩니다.
이를 위해 버전 관리 시스템(VCS)과 그를 담는 파일 형식에 대해 이해할 필요가 있습니다.
예를 들어, Git, Github 같이 나만의 코드를 공유하는 것 뿐만 아니라 Fork, Pull Request 등 협업을 위한 도구로도 쓸 수 있습니다.
또한, Git은 해시 맵(SHA-1)을 사용해 쉽게 탐색하고, Git 개체 (Objects)를 통해 버전 관리를 하고 있습니다. 이를 살펴보겠습니다.
파일의 변경 이력을 기록하고, 여러 사람이 동시에 작업할 수 있도록 도와주는 시스템입니다.
주로 소스 코드 관리에 사용되고, 파일의 각 버전마다 변경 내용을 추적하고 필요할 때 이전 버전으로 되돌릴 수 있는 도구입니다.
분산 버전 관리 시스템으로, 중앙 서버 없이도 각 사용자가 전체 저장소(Repository)의 복사본을 가지고 작업할 수 있습니다.
2005년에 만들어진 DVCS입니다.
DVCS 답게 각 사용자가 히스토리를 보관하고, 인터넷 연결 없이도 기능 사용 가능하고, 변경 이력 모두 기록 및 롤백 가능한 버전 관리 툴입니다.
자주 쓰이는 것들 위주로 간단히 설명하고 넘어가겠습니다.
원격 - 로컬 저장소를 조작합니다. 시작, 복사, 연결 등을 할 수 있습니다.
git init
로컬 저장소를 초기화하는 명령어입니다. 새로운 Git 프로젝트를 시작할 때 사용합니다.
git init
git clone
원격 저장소를 복제해 로컬 저장소로 가져오는 명령어입니다. 기존 프로젝트를 자신의 로컬 환경에서 작업할 수 있도록 해줍니다.
git clone <원격 저장소 URL>
git remote
원격 저장소와 로컬 저장소를 연결하는 명령어입니다. 주로 GitHub와 같은 원격 저장소를 사용합니다.
git remote add origin <원격 저장소 URL>
원격 및 로컬의 리포지토리 하위에 존재하는 폴더 트리 같은 겁니다. main
브랜치가 기본이고, 여기서 파생된 하위 브랜치들을 조작합니다.
git branch
현재 브랜치를 확인하거나, 새로운 브랜치를 생성합니다. 브랜치를 사용해 독립적인 작업을 할 수 있습니다.
git branch <브랜치명>
git checkout
다른 브랜치로 전환하거나 특정 commit
으로 이동합니다. 브랜치를 변경할 때 주로 사용합니다.
git checkout <브랜치명>
git merge
다른 브랜치의 변경 내용을 현재 브랜치로 병합합니다. 협업 시 각자 작업한 내용을 통합할 때 사용합니다.
git merge <브랜치명>
여기서 나오는 개념인 추적안됨(Untracted), 수정 관련((Un)Modified), 스테이징(Staged) 등의 개념은 File 형식에 후술하겠습니다.
git add
추적되지 않은 파일을 스테이징(Staged) 영역에 추가해 commit
할 준비를 합니다. 변경된 파일이나 새로운 파일을 추적하도록 합니다.
git add <파일명>
git commit
스테이징 영역에 있는 파일들을 commit
해 변경 이력을 저장합니다. commit
메시지를 통해 어떤 변경을 했는지 설명합니다.
git commit -m "`commit` 메시지"
commit
이 완료 되면 스테이징 영역에서 수정되지 않음 상태로 넘어갑니다.
git push
로컬 저장소의 변경 내용을 원격 저장소에 푸시합니다. 팀원들과 변경 내용을 공유할 때 사용합니다.
git push origin <브랜치명>
git pull
원격 저장소의 변경 내용을 로컬 저장소로 가져옵니다. 다른 사람이 푸시한 변경 내용을 가져올 때 사용합니다.
git pull
commit
확인 명령어git status
현재 작업 디렉토리의 상태를 확인합니다. 추적되지 않은 파일, 변경된 파일, 스테이징 영역에 있는 파일 등을 보여줍니다.
git status
git log
commit
히스토리를 확인합니다. 프로젝트의 변경 이력을 한눈에 파악할 수 있으며, 각 commit
의 상세 정보를 확인할 수 있습니다.
git log
Git은 파일을
Untracked
,Unmodified
,Modified
,Staged
네 가지 상태로 관리합니다.
git add
명령어를 사용해 추적 대상으로 추가할 수 있습니다.commit
된 후 수정되지 않은 상태입니다. Git이 추적하고 있지만 현재 변경 사항이 없는 파일입니다.git add
명령어를 사용해 스테이징 영역에 추가할 수 있습니다.commit
에 포함될 준비가 된 파일입니다.git commit
명령어를 사용해 commit
할 수 있습니다.git add
명령어를 사용해 스테이징 영역에 추가합니다.git add <파일명>
git commit
명령어를 사용해 commit
합니다.git commit -m "`commit` 메시지"
Unmodified -> Modified : commit
된 파일을 수정하면 Modified 상태가 됩니다.
Modified -> Staged : 수정된 파일을 다시 git add
명령어를 사용해 스테이징 영역에 추가합니다.
git add <파일명>
commit
해 변경 내용을 저장합니다.git commit -m "변경 내용"
git rm
명령어를 사용해 Git에서 파일을 제거할 수 있습니다.git rm <파일명>
Git을 기반으로한 웹 호스팅 플랫폼입니다.
이를 기반으로 코드 호스팅, 버전 관리 등을 공유하며 다른 개발자와 협업이 가능합니다.
위 사이트에 들어가 회원가입 및 로그인 하고, 원격 리포지토리를 만듭니다. 로컬에서 clone
을 해오면 끝!
Repository 생성 및 관리
Fork
Pull Request
Issues
GitHub Actions
Projects(프로젝트 보드)
Git은 DVCS으로, 소스 코드 관리 및 이력을 도와주고, 여러 명이 동시에 작업이 가능하도록 해줍니다. 어떻게 가능한 걸까요?
Git의 데이터 저장 방식은 blob
(blob
), tree
(tree
), commit
(commit
), 태그(tag
) 네 가지 개체로 구성됩니다. 각 개체는 SHA-1
해시를 통해 고유하게 식별됩니다.
SHA-1 해시는 SHA-해시맵 관련 글을 쓸 때 작성하겠습니다.
blob
(blob)파일의 내용을 저장하는 개체입니다. 소스 코드 파일, 텍스트 파일 등의 내용 등을 말합니다.
git add
를 하면 생성됩니다.
파일 자체의 데이터만을 포함하고 있으며, 파일 이름이나 다른 메타데이터는 포함하지 않습니다.
파일의 내용이 동일하면 동일한 blob
해시를 가지게 됩니다.
tree
(tree)디렉토리 구조를 나타내는 개체입니다. 프로젝트의 폴더 구조와 그 안에 포함된 파일 목록을 말합니다.
git commit
을 하면 생깁니다.
tree
는 blob
과 다른 tree
에 대한 포인터(주소)를 포함하고, 각 포인터는 파일 이름과 모드(권한)를 가지고 있습니다.
이를 통해 파일 시스템의 계층 구조를 다시 만들 수 있습니다.
commit
(commit)
tree
에 대한 포인터와commit
메시지, 작성자 정보, 부모commit
등을 포함하는 개체입니다.
특정 시점의 프로젝트 상태,commit
메시지, 작성자 및 타임스탬프 등과 같은 변경 이력, 메타 데이터를 저장합니다.
마찬가지로git commit
을 하면 생깁니다.
commit
은 프로젝트의 특정 시점 상태를 나타내고, commit
간의 연속성을 통해 변경 이력을 관리합니다.
특정
commit
에 대한 포인터로, 주로 릴리스 버전을 표시할 때 사용됩니다.
주로 릴리스 버전을 나타내는 데 사용되고, 주석이 포함된 태그는 작성자 정보와 메시지를 포함할 수 있습니다.
git tag
를 할 때 생성합니다.
blob
: .txt
같은 순수 파일들.tree
: 디렉토리 구조를 정의한 개체, tree
안에 여러 blob
이 있음commit
: blob
tree
개체를 모두 포함하고, 메타데이터를 포함함.SHA (Secure Hash Algorithm)는 데이터 무결성을 보장하고 데이터를 고유하게 식별하기 위한 해시 함수입니다.
Git을 비롯해 다양한 해쉬 함수 중 하나인 SHA-1을 주로 사용하고 있습니다.
통칭 SHA-2라 불리는 SHA-224, SHA-256, SHA-384, SHA-512들도 있습니다.
SHA-1은 입력 데이터를 160비트로 고유한 해시 값으로 변환합니다. 현재 Git의 개체 정의에 쓰이고 있습니다.
하지만 현재는 더 강력한 보안 요구에 의해 SHA-2들이 더 많이 사용되기도 합니다.
import crypto from 'crypto';
function generateHash(data) {
return crypto.createHash('sha256').update(data).digest('hex');
}
Map
은JS Map
처럼 데이터를 키-값 쌍으로 저장하고, Key를 해시 함수를 사용해 키를 빠르게 검색할 수 있게 만들었습니다.
Git 내부에서도 Hash + Map을 사용해 각 개체를 효율적으로 관리합니다.
Git에서는 SHA-1과 SHA-256 해시와 Map 자료구조가 함께 사용됩니다. 모든 객체는 SHA 해시로 식별되고, Git은 이를 Map처럼 사용해 객체를 빠르게 검색하고 관리합니다.
Key를 가져다 탐색하는 시간이 O(1) 시간 복잡도를 가지기 때문에 빠릅니다.
이러한 구조를 구축해 Git은 효율적이고 신뢰성 있는 버전 관리 시스템을 제공합니다.