카페인 중독자
Projects
microservice project
개발환경이슈
개요
example
week1
week2
Tutorial
Github tutorial
Templete tutorial
comment system
markdown guide
posting guide
visitor counter
cs-note
Abstract
쉬운코드
Web
개요
API
State
Transfer_Resource
dev-log
Home
tech-review
AI
BE
nginx
Communicate
Git
Contact
Copyright © 2024 |
Yankos
Home
>
tech-review
> Communicate
Now Loading ...
Communicate
Git의 object와 refs 저장방식
Git의 저장방식 git으로 프로젝트를 진행하다보면, .git이라는 숨김폴더가 생성되는 것을 볼 수 있다. 이러한 .git 폴더 안에는 프로젝트 작업을 수행하면서 commit add 등 명령어를 통해 수행한 작업들의 결과들이 생성되는데 이번 포스트에서 해당 정보에 대한 저장방식, 그 중에서도 git의 objects와 refs에 저장되는 정보에 대해 알아보자. Git objects 위의 그림에서 git이 실제로 어떻게 저장되느냐에 대한 설명이 잘 나와있다. 우리가 working directory의 작업을 commit을 수행하면, 해당 파일들과 디렉토리들은 Blob과 Tree라는 구조로 .git/objects에 저장된다. commit 객체가 생성되어 해당하는 커밋에 프로젝트 폴더를 가르키는 Tree 객체를 가르킨다. 또한 해당 커밋 이전의 부모 커밋 또한 가르킨다. commit object를 Head 포인터가 가르킨다. 자 전체적인 구조는 위와 같이 수행되지만, 하나하나가 잘 이해되지 않는다. 그러니 자세히 파악해보자. git objects 파일을 자세히 볼 땐 git cat-file -p 파일의 hash코드 명령을 통해 해당 오브젝트 파일을 자세히 살펴볼 수 있다. 이 글을 포스트하는 github 블로그 역시도 git으로 관리되고 있다. 그러면 한번 예시를 살펴봐볼까? abc83@develop MINGW64 ~/development/SeongWooJo.github.io/.git/objects (GIT_DIR!) $ ls 0a/ 1b/ 34/ 4c/ 67/ 7e/ 8f/ a2/ b5/ c1/ ca/ e8/ fb/ 0f/ 24/ 36/ 50/ 68/ 80/ 92/ a9/ b8/ c2/ d2/ ea/ fc/ 13/ 25/ 38/ 51/ 76/ 85/ 9a/ ae/ ba/ c4/ d3/ ee/ fd/ 19/ 2f/ 3e/ 60/ 7a/ 86/ 9e/ b0/ bc/ c5/ d5/ f3/ info/ 1a/ 30/ 44/ 62/ 7d/ 8b/ 9f/ b2/ bd/ c7/ db/ f9/ pack/ abc83@develop MINGW64 ~/development/SeongWooJo.github.io/.git/objects (GIT_DIR!) $ ls 1b/ 2948a17f027fd4f4359c53a60b9582a3b1c265 abc83@develop MINGW64 ~/development/SeongWooJo.github.io/.git/objects (GIT_DIR!) $ git cat-file -p 1b2948a17f027fd4f4359c53a60b9582a3b1c265 040000 tree 7a6a6a64b2bbae6b6cec73624b610e31830b56ac Projects 040000 tree 51fb9a02110fa88741738be230342544256e1f73 Tutorial 040000 tree 7a5657ae0999f622f6509b8416f659a0262eba33 cs-note 040000 tree c472bd9693f8ca55e7590d9ace65ee51b6f99179 dev-log 100644 blob a49ba48448f906d814cc83e50fc18f81cae53844 index.md 040000 tree b56fcfa45f3a0afaf2c480470f2b38f1b44fc26d tech-review abc83@develop MINGW64 ~/development/SeongWooJo.github.io/.git/objects (GIT_DIR!) $ git cat-file -p a49ba48448f906d814cc83e50fc18f81cae53844 --- --- 자 이러한 결과가 나왔다. 그러면 이 결과를 한번 자세히 분석해보자! Git Blob 먼저 git이 파일 버전 관리를 할 때 핵심이 되는 저장방식인 Blob(Binary Large Object)에 대해서 알아보자. abc83@develop MINGW64 ~/development/SeongWooJo.github.io/.git/objects (GIT_DIR!) $ git cat-file -p a49ba48448f906d814cc83e50fc18f81cae53844 --- --- 자 Blob파일을 우리가 열어보았을 때 해당 파일인 index.md의 실제 저장된 값과 정확히 일치하는 결과를 확인할 수 있다. 그렇다면 파일이 수정되었을 때 Blob은 어떻게 저장할까? # Blob 1 첫 번째 파일 # Blob 2 첫 번째 파일 두 번째 파일 파일이 위와 같이 수정되었을 때 Blob은 각 파일의 전체 내용을 기반으로 Hash함수를 통과시켜 40글자에 해당하는 문자열을 파일이름으로 사용한다. 이때 앞선 2글자는 폴더로, 뒤의 38글자는 파일이름으로 사용된다. 처음 objects의 폴더에 나온 수많은 2글자들은 이런 식으로 생성된 hash의 결과값들이다. git에서 각 오브젝트들은 이러한 hash값을 기반으로 접근할 수 있다. 각 파일이 조금의 수정이라도 일어난다면 git은 새로운 Blob파일로 저장하며, 수정이 일어나지 않았을 시 동일한 Blob파일로 저장된다. 이러한 구조의 장점은 무엇일까? 바로 hash함수의 특징인 같은 값을 통과시킬 땐 같은 결과가 나온다는 것이 핵심이다. git은 버전관리 프로그램이다. 커밋을 수행할 때마다 파일의 버전을 기록해야하고 변화를 추적할 수 있어야한다. 하지만 우리가 git을 사용할 때 항상 모든 파일들이 커밋을 수행할 때마다 바뀌는가? 아니다. 대부분의 파일들은 이전버전과 변하지 않는 경우가 많으며 수십 번의 커밋 후에도 바뀌지 않을 수도 있다. 이때 Blob의 저장방식이 강점을 발휘한다. Blob은 파일 내용을 기반으로 hash를 생성해 파일이름을 생성한다. 즉 어떤 컴퓨터에서든 어떤 파일로 저장되었든 어느 시점에 저장하든, 파일 내용이 동일하다면 동일한 Blob으로 저장된다. 이러한 방식은 git이 버전관리를 수행하면서도 저장 공간을 효율적으로 사용하게 해준다. 각 커밋을 수행할 때 시점별로 commit 오브젝트는 tree오브젝트를 가르키고 각 tree 오브젝트는 Blob을 가르키는데, 이때 동일한 내용은 여러 커밋 시점에서 하나의 Blob만을 가르키게 저장할 수 있다. 여기서 또 하나의 용량을 감소하는 트릭이 존재한다. git 저장구조, wikipedia Blob 파일의 생성 원리를 보면 파일 전체를 스냅샷처럼 저장해 전체 파일 내용을 기반으로 hash를 생성한다. 하지만 이런 말을 들어보았을 것이다. git은 파일의 수정된 내역만 저장하여 효율적이게 디스크 공간을 활용한다. 실제로 git은 델타압축이라는 파일의 수정된 내역만을 저장하여 공간을 절약시켜, 각각의 Blob을 이전 버전에서의 수정 내역만을 기반으로 생성시키고 checkout 등으로 특정 버전을 불러와야할 때 이러한 수정 내역을 일괄적으로 읽어 해당 버전을 복구한다. 그렇기에 전체 내용을 저장하는 것도 수정된 내역만 저장하는 것도 맞는 말이다. Git Tree abc83@develop MINGW64 ~/development/SeongWooJo.github.io/.git/objects (GIT_DIR!) $ ls 1b/ 2948a17f027fd4f4359c53a60b9582a3b1c265 abc83@develop MINGW64 ~/development/SeongWooJo.github.io/.git/objects (GIT_DIR!) $ git cat-file -p 1b2948a17f027fd4f4359c53a60b9582a3b1c265 040000 tree 7a6a6a64b2bbae6b6cec73624b610e31830b56ac Projects 040000 tree 51fb9a02110fa88741738be230342544256e1f73 Tutorial 040000 tree 7a5657ae0999f622f6509b8416f659a0262eba33 cs-note 040000 tree c472bd9693f8ca55e7590d9ace65ee51b6f99179 dev-log 100644 blob a49ba48448f906d814cc83e50fc18f81cae53844 index.md 040000 tree b56fcfa45f3a0afaf2c480470f2b38f1b44fc26d tech-review 이번엔 Tree 오브젝트를 살펴보자, 위의 그림을 보듯이 tree object는 자신이 가지고 있는 Tree와 Blob을 가르키는 오브젝트이다. 트리는 각 ‘디렉토리’별로 ‘파일 이름’을 저장한다. 현재 블로그에서 디렉토리를 담당하는 cs-note, dev-log 등은 tree로 저장되고ㅡ, index.md같은 실제 파일은 Blob으로 저장된 모습을 볼 수 있다. 또한 이러한 Tree 역시도 Blob과 마찬가지고 hash코드로 파일명이 지정된 것을 볼 수 있다. Blob과 달리 Tree는 디렉토리 전체를 기반으로 hash값을 생성하기에, 포함된 일부 파일이 하나만 수정되더라도 Tree 역시도 새로운 Tree 객체로 생성된다. 하지만 이를 통해 git은 파일의 내용만 저장하는 Blob과 달리 파일의 이름, 실행권한, 디렉토리 구조 등을 Tree 객체를 통해 저장할 수 있다. 여기서 .git/index 파일을 한번 살펴보자. $ git ls-files --stage | tail 100644 d344d060ac0c5db0f9bb01c4f1ce7e0d156598b9 0 search.html 100644 f259c5a08dd5d121a34a000017cd197ea02dc90b 0 sitemap.xml 100755 764df0355bdab53e2362b2f821e6c649162694d5 0 start.sh 100644 c9712bd9af8e82846391e82f7c50077b095f87fc 0 tag.html 100755 bdfb10641d93f265a382b3014341a15c68e4b139 0 tool/find-orphan-post-img.sh 100755 537c62c2bb5465d7594f085f8cf4935cf07ac4c4 0 tool/fix-image-references.sh 100755 01433e92888c8ce58bb79792ef786aa58d1acfc9 0 tool/pre-commit 100755 95b19d9863b6ad564bf6208f719a2bcc657a9ffc 0 tool/save-images.sh 100755 e36c4a696d2e351dc0efcd40db81d87e7ef1fb11 0 tool/to-skeleton.sh 100644 50fe65a76cb17611bb041bd5d2cc517ec863323f 0 utterances.json git index 자료 출처 해당 파일의 컬럼은 각각 staging area로 옮겨진 파일들에 대한 나열을 수행하며, 각 staged 파일들에 대해 [mode] : 파일의 타입과 권한을 의미 [object] : 해당 파일을 나타내는 .git 내부 hash값 [stage] : 기본값 0 충돌이 났을 때 충돌난 각 파일 그룹들을 구분해주는 키 [file] : 실제 파일 경로 를 의미한다. tree는 확실하게 commit된 디렉토리(Tree)와 Blob들을 기록하지만, Staging 공간은 오로지 add된 파일들을 Blob으로 생성하고 이들을 나열하는 차이를 확인할 수 있다. 하지만 만약 현재 staing 공간에 존재하는 파일들을 tree로 만들고 싶다면, git write-tree 명령을 통해 Tree객체를 생성해주고, 이에 대한 hash 값을 커맨드에 출력해준다. Git Commit 프로젝트의 디렉토리에 대한 정보와 파일 내용에 대한 정보를 Tree와 Blob을 통해 저장하였다. 하지만 이는 한 시점에 프로젝트의 상태를 기록하는 방법론일 뿐이다. git은 우리가 commit을 수행할 때마다 해당 시점에 누가 기록했는지, 이 이전 시점의 기록은 무엇인지 추적이 가능해야한다. 이러한 역할을 수행해주는 것이 commit 객체이다. abc83@develop MINGW64 ~/development/SeongWooJo.github.io/.git/objects (GIT_DIR!) $ git log commit f342a499d9ea17b2956f9bea91c33354d1870984 (HEAD -> main, origin/main, origin/HEAD) Author: SeongWooJo <abc8325767@gmail.com> Date: Wed Aug 13 22:35:28 2025 +0900 search commit 1a733fefb50c137ab2b95285b82f084dc60193aa Author: SeongWooJo <abc8325767@gmail.com> Date: Wed Aug 13 22:29:42 2025 +0900 Update _config.yml commit 80646a438cff8f50884f6bf2945b2f4e15887ff4 Author: SeongWooJo <abc8325767@gmail.com> Date: Wed Aug 13 22:23:09 2025 +0900 . commit 19781c03fd83f4c185f9ab5051c8bba72983bace Author: SeongWooJo <abc8325767@gmail.com> Date: Wed Aug 13 22:22:41 2025 +0900 우리가 git log 명령을 수행하면 위와 같이 hash값과 함께 각 커밋에 대한 정보를 나열해주는 것을 볼 수 있다. 어떻게 이런 작업이 가능한 것일까? 아까처럼 hash 코드를 기반으로 파일을 열어보자. abc83@develop MINGW64 ~/development/SeongWooJo.github.io/.git/objects (GIT_DIR!) $ git cat-file -p 19781c03fd83f4c185f9ab5051c8bba72983bace tree ba3c9fe46ea8e11d47e739b69c347cf1d5efd75e parent dba0935cb5910000496ffac60c49ba2534de4001 author SeongWooJo <abc8325767@gmail.com> 1755091361 +0900 committer SeongWooJo <abc8325767@gmail.com> 1755091361 +0900 robot 해당 커밋은 git blog를 배포하기 위해 robot.txt를 시험하던 시점의 커밋이다. commit 메세지로 robot으로 간단하게 적었다. 이 객체를 분석해보자. tree : 해당 커밋 시점의 프로젝트 전체를 가르키는 tree 객체의 hash값이다. parent : 해당 커밋의 이전 커밋 객체를 가르키는 hash값이다. author : 해당 커밋 시점의 코드를 작성한 사람에 대한 정보이다. committer : 해당 커밋을 작성한 사람에 대한 정보이다. “robot” 해당 커밋을 작성할 때 메세지이다. 이처럼 버전관리를 위해 필요한 추적을 위한 정보들이 커밋 객체에 담긴 것을 확인할 수 있으며, 커밋 객체역시도 tree,blob과 마찬가지로 내용을 기반으로 hash값을 폴더/파일명으로 삼는다. Git Tag 자 hash를 기반으로 Blob, Tree, Commit의 접근하는 것은 저장도 효율적이고 버전 관리도 될 수 있는 방법이지만, 40글자에 해당하는 hash 코드는 사람이 구분하기에 어렵다. 이를 해결해주기 위한 객체가 바로 Tag 객체이다. git tag [옵션] <tagname> [<commit>] git tag -a v1.0 -m "First release" git tag -s v1.0 -m "Signed release" git tag v1.1 <commit_hash> 우리는 위와 같은 명령을 통해 각 hash 코드에 사람이 접근하기 좋은 이름을 붙여줄 수 있다. 이를 기반으로 기존에는 git checkout hash코드 처럼 40글자의 hash코드를 사용해야하는 명령에서, git checkout 태그명으로 미리 지정한 tagname을 기반으로 hash코드를 대체할 수 있다. 다만 위의 예시처럼 우리가 어떻게 태그를 생성했느냐에 따라 구현방식이 조금씩 다르다. -a 옵션 $ git cat-file -p c3d5f2a object 7a9b74c6b6f4d4c85b8e4cf59ef1fa3e63c5c3ad type commit tag v1.0 tagger Alice <alice@example.com> 1713250000 +0900 First release -a 옵션을 사용했을 때는 해당 hash 파일에 대한 태그를 생성할 때 누가 태그를 붙였는지, 해당 태그를 붙일 떄 시점 및 메세지를 같이 남긴다. -s 옵션 object 7a9b74c6b6f4d4c85b8e4cf59ef1fa3e63c5c3ad type commit tag v1.0 tagger Alice <alice@example.com> 1713250000 +0900 Signed release -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEzBAABCAAdFiEE... -----END PGP SIGNATURE----- -s 옵션은 -a 옵션에 더해 해당 tagger를 검증할 수 있는 키를 남겨, public key를 통해 검증할 수 있게 한다. 그냥 만들시 이때는 tag 객체가 생성되는 것이 아닌, refs/tags에 해당 태그가 가르키는 hash코드에 대한 정보만이 한 줄로 기록된다. git refs .git/refs 폴더에는 이러한 객체를 가르키는 포인터를 만들 수 있으며 이곳에 저장되는 포인터 정보는 .git/refs/heads 각 브랜치별 최신 작업 커밋을 가르키는 hash값 및 working directory가 작업하고 있는 버전의 commit hash값 .git/refs/tags 사전에 태그로 등록한 commit, tree, blob hash값이 저장되는 장소 .git/refs/remotes local 저장소가 아닌 remote 저장소에 브랜치들에 대한 최신 commit hash값이 저장되는 장소 와 같이 앞서 공부한 git의 객체들에 대한 hash값을 refs 폴더에서 실제 git에서 작업되는 hash값을 관리해줌으로써 우리가 브랜치명, 원격 브랜치명, 태그명으로 실제 hash값을 사용하지 않고 쉽게 이동할 수 있다. 참고자료 git의 저장방식 영상 git blob, tree, commit git tags git에 대한 추후 볼 내용1
tech-review
· 2025-08-17
Git 정리
Git 개요 백엔드 시스템을 개발하면서, 기존의 연구 개발과는 달리 여러 사람이 병렬로 작업을 수행하게 되었다. 이에 따라 Git을 사용하게 되었고, 버전 및 브랜치 관리를 철저히 해야 할 필요성을 절실히 느꼈다. 이에 따라 Git에 대해 정리할 필요성을 느꼈고, 그 첫 번째로 Git의 공간과 파일의 상태에 대해 기초적인 내용을 정리한다. Git이란? Git이란 Version Control System의 일종으로, 소프트웨어 개발 및 협업 프로젝트에서 소스 코드, 문서, 기타 파일의 변경 사항을 추적하고 관리하는 데 사용된다. 혼자 작업하든 팀으로 작업하든, 버전 관리를 도입하면 다음과 같은 장점이 있다: 파일과 프로젝트를 이전 상태로 쉽게 되돌릴 수 있다. 누가 언제 어떤 작업을 했는지 추적할 수 있으며, 문제 발생 시 관련 이력을 확인할 수 있다. 파일을 잃어버리거나 실수로 수정했을 때 쉽게 복구할 수 있다. 서로의 작업을 덮어쓰지 않고 병렬로 작업하며, 변경 사항을 손쉽게 병합할 수 있다. 버전 관리 시스템(VCS)은 Git 외에도 다양한 도구들이 존재한다. 예를 들어 GUI 기반의 간편함을 선호하는 개발자들은 Mercurial을 사용하기도 하고, 코드 외의 리소스까지 통합 관리하는 Perforce (P4V) 도 있다. 하지만 현재까지 가장 널리 사용되는 VCS는 단연 Git이다. Git의 공간 Git은 파일들의 변경 이력을 추적하여 버전을 관리하는 도구다. 그렇다면 파일을 수정할 때마다 Git이 모든 변화를 자동으로 기록하는 것일까? → 그렇지 않다. Git은 우리가 작업하는 디렉토리의 파일 상태를 추적하고, 특정 명령을 실행할 때마다 스냅샷처럼 그 시점의 파일 상태를 기록한다(그러나 저장 방식은 파일을 복제하는 것이 아닌 변화를 기록하는 차이가 존재한다). 이러한 과정에서 Git은 변경된 파일들을 다양한 단계에서 관리한다. Git이 추적하는 파일 상태는 아래와 같은 네 가지 주요 공간을 통해 이해할 수 있다: 1. Working Directory Git으로 관리하기 위해 git init 등을 실행한 후 작업하게 되는 실제 디렉토리다. 이곳은 개발자가 직접 파일을 수정하거나 저장하는 공간이며, Git이 자동으로 버전을 기록하지 않는다. 즉, 파일을 수정하거나 새로 생성해도 git add 또는 git commit 명령을 실행하지 않으면, Git이 버전 이력에는 반영하지 않는다. 2. Staging Area Staging Area는 로컬 저장소에 기록(commit) 하기 전에 Git이 변경 내용을 임시로 저장하는 공간이다. 해당 공간이 존재함으로써 Merge 등의 작업을 수행할 때 충돌을 해결하거나, 한번에 커밋에 어떠한 정보들만 업데이트할지 천천히 파일들을 추가할 수 있다. 메모리 등에 임시로 저장되는게 아닌 별도의 공간에 존재하기에 이런 작업들을 오래 수행할 수 있다. git add 명령을 사용하면, 해당 파일은 Staging Area에 추가된다. Staging Area를 사용하면 원하는 변경 사항만 선택적으로 커밋할 수 있어, 커밋의 목적과 단위를 깔끔하게 분리할 수 있다. 3. Local Repo git commit 명령을 실행하면, Staging Area에 있던 변경 내용이 로컬 저장소에 커밋된다. 이 저장소는 .git 폴더 내부에 존재하며, 모든 커밋 이력, 브랜치 정보, 메타데이터 등을 포함한다. Git은 이곳에 실제 파일 내용뿐 아니라, 이전 버전과의 차이점, 커밋 메시지, 작성 시간, 작성자 등의 정보를 구조화하여 저장한다. 구체적인 .git 폴더의 저장 방식에 대해서는 링크를 참조하자 : 저장방법 로직 4. Remote Repo 로컬 저장소의 커밋 내역을 다른 사람과 공유하려면, git push 명령을 사용하여 Remote Repository로 전송한다. Remote Repository는 GitHub, GitLab, Bitbucket 등의 원격 저장소이며, .git 폴더와 동일한 커밋 이력을 저장하고 관리한다. 원격 저장소를 통해 팀원 간의 협업이 가능해지며, pull, fetch, merge 등을 통해 변경 사항을 주고받을 수 있다. Git의 파일의 상태 Git은 결국 각 파일이 시간에 따라 어떻게 변화해왔는지를 기록하는 도구이다. 이에 따라 각 공간으로 이동하는 것에 더해 Git은 사용자가 명시적으로 실행하는 명령에 따라 각 파일의 상태(state)를 구분하고 관리한다. Git에서 파일이 가질 수 있는 상태는 다음과 같다: Untracked / Tracked → (Unmodified, Modified, Staged) 1. Untracked Git은 파일의 변경 이력을 추적하고 버전을 관리하지만, 한 번도 Git에 추가되지 않은 파일은 Git 입장에서 “변경”이 아닌 “새로운 파일” 일 뿐이다. 즉, Git이 한 번도 기록한 적이 없는 파일은 과거 상태가 없기 때문에 변경 이력을 추적할 수 없다. 이러한 상태를 Untracked 이다. 실제 Git에선 git 프로젝트 내에서 새로운 파일을 생성시켰을 때, 기존의 추적되던 파일을 삭제하였을 때, 또한, .gitignore에 등록된 파일들도 일부러 추적하지 않기 때문에 Untracked 상태로 간주된다. 이는 예를 들어 다음과 같은 경우 유용하다: 대용량 파일로 인해 Git 저장소에 포함시키고 싶지 않은 경우 민감 정보(예: API 키, 비밀번호)가 포함된 파일을 외부 저장소에 업로드하고 싶지 않은 경우 위의 상태 도식과 달리 Tracked 상태의 파일을 삭제하지 않으면서 Untracked로 만들고 싶을 수 있다. 그런 경우 위처럼 git add, unstaged 같은 명령으론 수행할 수 없고 git rm --cached example.txt 라는 명령처럼 실수로 추적한 파일을 local repo와 staging area에서 없앨 수 있다. 2. Staged 위의 공간 설명에서 Staging Area란 공간은 commit을 수행하기 전 기록할 파일의 상태를 임시로 모아두는 공간이다. 이처럼 해당 공간에 파일들이 옮겨졌을 때 해당 파일들은 Staged 상태를 가지게 된다. 만약 Untracked 파일이 Staged 상태가 된다면 그 때부터 추적이 시작되는 것이고, 다시 unstaged하면 Untracked 상태로 돌아간다. 만약 당신이 파일을 Staged 상태로 바꾸고 워크 디렉토리에서 파일을 수정한다면 어떻게 될까? Staging Area에는 git add 시점의 파일 상태가 기록되는 것이다. 즉, 워킹 디렉토리의 파일과 Staged에 기록된 파일이 다른 것이다. 워킹 디렉토리에서 해당 파일을 수정하면, Git은 "Staging Area 버전" ≠ "Working Directory 버전" 인 것을 인식한다. 3. Unmodified Commit을 수행하면, Staging Area의 파일 상태가 Local Repository에 기록된다. 이후 git status 같은 명령이 실행될 때마다 Git은 Local Repo(HEAD) 와 워킹 디렉토리를 비교한다. 두 상태가 완전히 동일하다면 해당 파일은 Unmodified 상태이다. 예를 들어, 파일을 Staged 상태로 변경하고, 추가 수정 없이 commit을 하면 commit 직후 그 파일은 Unmodified 상태로 남는다. 4. Modified 위의 상태처럼 Commit 등을 통해 Staged를 Local Repo로 옮긴 후 추가적으로 워킹 디렉토리에서 파일을 수정했을 때, 해당 파일은 Local Repo와 상태가 다른 Modified 상태가 된다.
tech-review
· 2025-08-12
<
>
Touch background to close