구조를 한번 살펴보자.
이전 포스팅에서 내용을 한번 더 정리하면,
Git에서 remote는 "로컬 저장소와 동기화할 대상 Git 저장소 주소 정보"이고,
origin은 그 remote 주소에 붙인 이름(alias)이라고 볼 수 있다.
1. remote 연결
remote의 이름(alias)이 여러 의미로 나눌 수 있듯이 remote는 로컬일 수도 있고,
외부 서버(GitHub / GitLab / 회사 서버 / NAS / 로컬 폴더 / SSH 서버)일 수도 있다.
또는 하나의 로컬 저장소가 여러 원격 저장소(remote)에 동시에 연결될 수 있다.
① GitHub ( 가장 흔한 형태 )
origin → https://github.com/user/project.git
또는
origin → git@github.com:user/project.git
② 회사 서버
$ git remote add company git@192.168.0.10:/project.git
$ git remote add deploy ssh://git@192.168.0.10/srv/git/project.git
$ git remote -v
company → git@192.168.0.10:/srv/git/project.git
deploy → ssh://git@192.168.0.10/project.git
③ 사내 GitLab
$ git remote add company https://gitlab.company.com/project.git
$ git remote -v
company → https://gitlab.company.com/project.git
④ 로컬 폴더 (백업 저장소)
$ mkdir /mnt/backup/project.git
$ cd /mnt/backup/project.git
$ git init --bare
$ git remote add backup /mnt/backup/project.git
$ git remote add backup D:/git-backup/project.git (윈도우)
$ git remote -v
backup → /mnt/backup/project.git
👉 GitHub가 대신 해주던 걸 " 내가 직접 구축한 회사 내부 Git 서버 / NAS 백업 저장소 / 배포 서버 저장소 "에
공유, 저장, 동기화를 해야하는 상황에서 bare repository를 사용한다.
👉 이 경우에는 로컬 디스크의 Git 저장소로 push 된다.
2. bare repository
일반적으로 우리가 사용하는 GitHub는 작업 파일이 함께 존재하는 형태이다.
my-project/
├── index.html
├── app.js
├── style.css
└── .git/
여기서 눈에 보이는 index.html, app.js 같은 파일들은 실제로 우리가 수정하며 작업하는 파일들이다.
그리고 .git 폴더 안에는 Git이 사용하는 내부 데이터가 저장된다.
이 처럼 Git 저장소는 크게 두 영역으로 나뉜다
| 영역 | 역할 |
| Working Tree | 개발자가 실제 작업하는 파일 공간 |
| Git Database(.git) | commit, branch, 버전 정보 저장 공간 |
2.1. Working Tree는 무엇일까?
우리가 눈으로 보는 프로젝트 파일들은 사실 Git 내부 데이터가 “현재 시점 기준으로 꺼내진 상태”라고 이해하면 쉽다.
Working Tree는 우리가 눈으로 보고 직접 수정하고, 생성 및 삭제같은 작업을하는 실제 작업 공간이다.
예를 들어:
index.html
app.js
style.css
이 파일들은 단순한 원본 파일이라기보다는,
현재 브랜치와 현재 commit 상태를 기준으로 실제 작업 가능하게 펼쳐진 파일들 이라고 볼 수 있다.
즉, Git 내부 데이터 → Working Tree로 펼쳐진 구조인 셈이다.
한번 더 정리하면,
Working Tree = 작업 공간 자체 이고, 작업 파일 상태 = 작업 공간 안에서 수정 중인 상태 이라고 보면된다.
2.2. Git의 진짜 데이터는 어디에 저장될까?
프로젝트 파일 자체를 Git이 관리한다고 생각하지만, 실제로 Git의 핵심 데이터는 .git 폴더 안에 저장된다.
예를 들어 .git 내부에는 다음과 같은 정보들이 존재한다.
- commit 기록
- branch 정보
- tag 정보
- 파일 버전 데이터(objects)
- HEAD 위치 정보
즉, Git은 단순히 파일을 복사하는 것이 아니라, 파일의 변경 이력과 버전 정보를 내부 commit 데이터 형태로 저장하고 관리한다.
2.3 Git에서 Push는 무엇을 보내는 걸까?
다시 살펴보고 가자....
" git push" 는 Working Tree 자체를 업로드 하는 작업이 아니다.
실제 Git 흐름을 보면 git은 "현재 수정 중인 파일 상태 "를 보내는것이 아니라,
" 확정된 commit 데이터"를 전송한다.
👉 Working Tree → git add → git commit → Git Database(.git)에 commit 생성 → git push
예를 들어 파일을 수정만 하고, commit 하지 않았다면, "git push"를 해도 전송되지 않는다.
2.4. bare repository는 무엇일까?
bare repository는 Working Tree가 제거된 형태의 Git 저장소이다.
우리가 평소 작업하는 일반 저장소와 bare repository 저장소를 살펴보자.
일반 저장소는 실제 소스코드를 수정하고 파일을 생성하거나 삭제하는 작업 공간(Working Tree)이 포함되어 있다.
예를 들어 프로젝트 폴더 안에는 다음과 같은 요소들이 함께 존재한다.
< 일반 저장소 >
- 소스 코드 파일
- 수정 중인 작업 내용
- Git 히스토리 정보(.git)
my-project/
├── app.js
├── index.html
└── .git/
즉, 개발자가 직접 작업하기 위한 “작업용 저장소”인 셈이다.
일반 저장소와 달리 원격 저장소(remote)는 목적이 조금 다르다.
원격 저장소는 여러 사용자가 코드를 push하거나 pull하는 기준 저장소 역할을 해야 하기 때문에,
일반 작업 파일보다는 Git 히스토리와 브랜치 정보만 안정적으로 관리하는 형태가 더 적합하다.
그래서 Git에서는 보통 원격 저장소용으로 bare repository 형태를 사용한다.
구조를 한번 살펴보자.
< bare repository >
- 실제 작업 파일 없음
- 수정 중인 파일 없음
- commit, branch, tag 같은 Git 데이터만 관리
project.git/
├── objects/
├── refs/
├── HEAD
└── config
이처럼 Git 내부 관리 데이터만 존재한다.
반대로 일반 저장소에서 보이던 작업 파일은 존재하지 않는다.
index.html
app.js
style.css
여기서 중요한 점은 bare repository에도 commit 정보와 파일 버전 데이터는 모두 존재한다는 것이다.
다만 일반 저장소처럼 파일이 실제 작업 가능한 형태로 “체크아웃(checkout)” 되어 있지 않을 뿐이다.
👉 일반 저장소 = 개발자가 실제 작업하는 로컬 저장소 = 내 작업실
👉 bare repository = 원격 저장소(remote) 용도로 사용하는 Git 저장소 형태 = 공유 창고
2.5. 왜 Working Tree를 제거할까?
핵심은 "push 받는 저장소의 안정성" 때문이다.
원격 저장소는 여러 사용자가 동시에 접근하는 공유 공간이다.
만약 원격 저장소 안에도 실제 작업 파일(Working Tree)가 존재하고,
누군가 서버에서 직접 수정까지 가능하다면 다음과 같은 문제가 발생할 수 있다.
- Working Tree 상태 충돌
- 서버 작업 파일 불일치
- push 충돌 및 거부
- commit 상태 불일치
특히 누군가 서버에서 직접 파일을 수정한 상태에서 다른 개발자가 push를 수행하면 파일 상태 불일치나 충돌 문제가 발생할 수 있다.
실제 작업 파일을 수정하는 공간보다는, commit 기록과 branch 정보를 안정적으로 저장하고 공유하는 역할에 더 적합하다.
그래서 Git은 원격 저장소 용도로는 bare repository 방식을 사용한다.
👉 “코드 작업”은 개발자의 로컬 저장소에서 수행하고,
👉 “버전 기록 관리와 공유”는 bare repository가 담당하는 구조이다.
정리하면 ...
bare repository는 실제 작업 파일(Working Tree) 없이 commit, branch, tag 같은 Git 내부 데이터만 관리하는 저장소이며,
Working Tree를 제거함으로써 원격 저장소를 보다 안정적으로 운영할 수 있게 해준다.
2.6. 그럼 GitHub 저장소는 무엇?
GitHub 저장소도 GitHub 서버 위에 존재하는 bare repository 기반 저장소 라고 볼 수 있다.
GitHub 역시 " commit 저장 + branch 관리 + push/pull 처리 "를 중심으로 동작한다.
다만 GitHub는 여기에 추가로 아래와 같은 기능들을 제공하는 플랫폼이다.
- 웹 UI
- Pull Request
- Issues
- Actions(CI/CD)
- 권한 관리
👉 GitHub 저장소 = bare repository 기반 + 웹 협업 기능 제공 서비스 = 공유 창고 + 관리 시스템 + 웹 서비스
>> 그렇다면 GitHub 웹에서는 왜 파일 수정이 가능할까?
내부적으로는 GitHub도 결국 commit 기반으로 동작하기 때문에 웹 편집 또한 "웹 UI를 통해 commit 생성"이라고 보면된다.
3. <번외> Git Database(.git) 구조
Git의 실제 commit 데이터와 파일 버전 정보는 대부분 objects/ 안에 저장되며,
branch와 tag는 특정 commit을 가리키는 참조(reference) 형태로 refs/ 아래 관리된다.
구조를 한번 살펴보자.
.git/
├── objects/ → commit, 파일 데이터
├── refs/
│ ├── heads/ → branch 정보
│ └── tags/ → tag 정보
├── HEAD → 현재 branch 위치(HEAD 위치 정보)
└── config → remote 및 Git 설정
① objects/
→ commit 객체, commit 객체, tree 객체 같은 Git 데이터가 저장 된다.
→ commit 객체(SHA-1 해쉬 기준으로 저장) : commit 메시지, 작성자, 부모 commit, tree 정보 등
→ 파일 버전 데이터는 hash 기반 object 형태의 파일 데이터(blob)로 저장된다.
② refs/heads/[브랜치 디렉토리]/
→ commit hash 하나만 들어있다. 즉, branch는 현재 어떤 commit을 가리키는지만 저장한다.
③ refs/tags/[버전 디렉토리 예)v1.0]
→ 특정 commit hash를 가리킨다.
④ HEAD
→ 현재 어떤 branch를 보고 있는지
→ 예) ref: refs/heads/main
⑤ config
→ remote 정보 / 사용자 설정 / branch tracking 정보 등이 저장된다.
→ 예) [remote "origin"]
url = https://github.com/user/project.git
'DevOps > Git' 카테고리의 다른 글
| [GitHub]_HEAD와 브랜치의 관계 (0) | 2026.05.05 |
|---|---|
| [GitHub]_커밋(Commit)과 브랜치의 관계 (0) | 2026.05.04 |
| [GitHub]_Git Hub 저장소 생성, 기본 명령어+토큰 발급 (0) | 2026.05.04 |
| [GitHub]_Git 설치 및 환경 설정 (Windows / Linux) (0) | 2026.05.04 |
| [GitHub]_Git이 뭔데 다들 쓰는 걸까? (0) | 2026.05.04 |
댓글