티스토리 뷰

728x90
SMALL

git add 명령의 동작 원리

git init 명령 수행시 변경사항 확인

User@DESKTOP-VOH9EIA MINGW64 ~/Documents
$ mkdir git-test

User@DESKTOP-VOH9EIA MINGW64 ~/Documents
$ cd git-test

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test
$ git init
Initialized empty Git repository in C:/Users/User/Documents/git-test/.git/

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ ls -al
total 12
drwxr-xr-x 1 User 197121 0  7월  3 16:05 ./
drwxr-xr-x 1 User 197121 0  7월  3 16:05 ../
drwxr-xr-x 1 User 197121 0  7월  3 16:05 .git/

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ ls -al .git/
total 11
drwxr-xr-x 1 User 197121   0  7월  3 16:05 ./
drwxr-xr-x 1 User 197121   0  7월  3 16:05 ../
-rw-r--r-- 1 User 197121 130  7월  3 16:05 config
-rw-r--r-- 1 User 197121  73  7월  3 16:05 description
-rw-r--r-- 1 User 197121  23  7월  3 16:05 HEAD
drwxr-xr-x 1 User 197121   0  7월  3 16:05 hooks/
drwxr-xr-x 1 User 197121   0  7월  3 16:05 info/
drwxr-xr-x 1 User 197121   0  7월  3 16:05 objects/
drwxr-xr-x 1 User 197121   0  7월  3 16:05 refs/

 

저수준 명령어(low level)

git hash-object <파일명> : 일반 파일의 체크섬을 확인할 때 사용

git show <체크섬> : 해당 체크섬을 가진 객체의 내용을 표시

git ls-files --state : 스테이지 파일의 내용을 표시, 스테이지 파일은 git add 명령을 통해 생성되는데 .git/index 파일이 스테이지 파일이다.

 

파일 생성 및 워킹트리 상태 확인

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ echo "cat-hanbi" > cat.txt

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        cat.txt

nothing added to commit but untracked files present (use "git add" to track)

git status 명령은 워킹트리의 상태를 보는 명령.

워킹트리와 스테이지, HEAD 커밋 세가지 저장 공간의 차이를 비교해서 보여줌

------------ 지금은 워킹트리에만 cat.txt있다

 

 

파일 체크섬 확인

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git hash-object cat.txt
5fa99df9f02522cf1919990c8d21edfc0ced46da

 

스테이지에 파일 추가

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git add cat.txt

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   cat.txt


User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ ls -a .git
./  ../  config  description  HEAD  hooks/  index  info/  objects/  refs/

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ file .git/index
.git/index: Git index, version 2, 1 entries

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git ls-files --stage
100644 5fa99df9f02522cf1919990c8d21edfc0ced46da 0       cat.txt

이때 index는 스테이지의 다른 이름이다. 이 index파일이 바로 git의 스테이지다.

마지막 명령어로 스테이지의 내용을 확인하니 cat.txt 파일이 스테이지에 들어있고 체크섬은 좀 전에 확인한 값과 일치

 

.git 폴더 조금더 살펴봐

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ ls -a .git/objects/
./  ../  5f/  info/  pack/

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ ls -a .git/objects/5f
./  ../  a99df9f02522cf1919990c8d21edfc0ced46da

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git show 5fa99d
cat-hanbi

 5f + a00d~~  체크섬 앞 2자리가 폴더이름이고 그다음이 폴더안파일내용이네

git show로 객체내용은 cat-hanbi

------------ 지금은 워킹트리, stage에 cat.txt있다

 

체크섬을 이용해 객체의 종류와 내용을 확인할 수 있는 다른 명령어

git cat-file -t <체크섬> : 해당 체크섬을 가진 객체의 타입을 알려주는 명령

git cat-file <객체타입> <체크섬> :  객체의 타입을 알고 있을 때 해당 파일의 내용을 표시해준다.

$ git cat-file -t 5fa99d
blob

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git cat-file blob 5fa99d
cat-hanbi

 

-----정리

git add 명령은 워킹트리에 존재하는 파일을 stage에 추가하는 명령이라는 것을 확인.

해당 파일의 체크섬 값과 동일한 이름을 가지는 blob 객체가 생성되고 이 객체는 .git/objects 파일에 저장. 그리고 스테이지의 니용은 .git/index에 기록

git commit 명령의 동작 원리

평범한 커밋과 상태 확인

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git commit
[master (root-commit) cc72041] 而ㅻ컠 ?뺤씤??而ㅻ컠
 1 file changed, 1 insertion(+)
 create mode 100644 cat.txt

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git log
commit cc720419c4db2e421c98e3cd71478751597a8bce (HEAD -> master)
Author: yoonminsang <apdlyooapdl@naver.com>
Date:   Sat Jul 3 16:37:42 2021 +0900

    커밋 확인용 커밋

    커밋의 원리를 알아보고 싶어서 만들었다.

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git status
On branch master
nothing to commit, working tree clean

 

 

아니 왜 git bash에서 commit하면 저렇게 이상하게 한글이 깨질까?? vscode git bash에서는 안깨지고 git bash log도 안깨지는데...... 왜그럴까??? 구글링해봐도안나오는데

=> vscode에서 저장할때 인코딩 문제인듯... 해결하면 올리자

 

커밋 상태 확인2

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ ls -a .git/objects
./  ../  5f/  cc/  eb/  info/  pack/

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ ls -a .git/objects/cc
./  ../  720419c4db2e421c98e3cd71478751597a8bce

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git show cc7204
commit cc720419c4db2e421c98e3cd71478751597a8bce (HEAD -> master)
Author: yoonminsang <apdlyooapdl@naver.com>
Date:   Sat Jul 3 16:37:42 2021 +0900

    커밋 확인용 커밋

    커밋의 원리를 알아보고 싶어서 만들었다.

diff --git a/cat.txt b/cat.txt
new file mode 100644
index 0000000..5fa99df
--- /dev/null
+++ b/cat.txt
@@ -0,0 +1 @@
+cat-hanbi

역시 확인해보니 커밋객체. cc는 위에서 git log에서 그거보고 들어간거야. 그런데 eb폴더는 머지??

 

텅빈 스테이지 확인

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git ls-files --stage
100644 5fa99df9f02522cf1919990c8d21edfc0ced46da 0       cat.txt

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git status
On branch master
nothing to commit, working tree clean

 

스테이지가 비어있지 않아~~

git status로 clean한 상태는 워킹트리=스테이지=HEAD 커밋

 

수상한 객체 살펴보기

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ ls -a .git/objects/
./  ../  5f/  cc/  eb/  info/  pack/

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ ls -a .git/objects/eb/
./  ../  30916c5d0036a7524186aa1bb438bb2b0c6e1e

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git show eb3091
tree eb3091

cat.txt

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git ls-tree eb3091
100644 blob 5fa99df9f02522cf1919990c8d21edfc0ced46da    cat.txt

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git ls-files --stage
100644 5fa99df9f02522cf1919990c8d21edfc0ced46da 0       cat.txt

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git log --oneline -n1
cc72041 (HEAD -> master) 커밋 확인용 커밋

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git cat-file -t cc7204
commit

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git cat-file commit cc7204
tree eb30916c5d0036a7524186aa1bb438bb2b0c6e1e
author yoonminsang <apdlyooapdl@naver.com> 1625297862 +0900
committer yoonminsang <apdlyooapdl@naver.com> 1625297862 +0900

而ㅻ컠 ?뺤씤??而ㅻ컠

而ㅻ컠???먮━瑜??뚯븘蹂닿퀬 ?띠뼱??留뚮뱾?덈떎.


------------------ 오류나서 vscode에서 만듬
$ git cat-file commit cc7204
tree eb30916c5d0036a7524186aa1bb438bb2b0c6e1e
author yoonminsang <apdlyooapdl@naver.com> 1625297862 +0900   
committer yoonminsang <apdlyooapdl@naver.com> 1625297862 +0900

커밋 확인용 커밋

커밋의 원리를 알아보고 싶어서 만들었다.

 

수상한 객체는 tree라는 것을 확인. 

git ls-tree로 트리 객체의 내용을 보니 스테이지와 동일

커밋 객체의 체크섬을 이용해 타입을 확인해보면 commit

커밋 객체의 내용을 들여다보니 커밋 메시지와 트리 객체로 구성되어 있다. 트리 객체의 체크섬은 위에서(위 코드의 맨위) 확인한 객체와 일치.

 

요약

1. 커밋을 하면 스테이지의 객체로 트리가 만들어진다.

2. 커밋에는 커밋 메시지와 트리 객체가 포함된다.

 

수동 커밋하며 살펴보기

파일 내용 수정하고 파일 체크섬 확잉ㄴ

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ cat cat.txt
cat-hanbi

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git hash-object cat.txt
5fa99df9f02522cf1919990c8d21edfc0ced46da

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ echo "Hello, cat-hanbit" >> cat.txt

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git hash-object cat.txt
9b990c20055452bb450a3b8a8be57a5fedd9e416

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git ls-files --stage
100644 5fa99df9f02522cf1919990c8d21edfc0ced46da 0       cat.txt

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git ls-tree HEAD
100644 blob 5fa99df9f02522cf1919990c8d21edfc0ced46da    cat.txt

변경 내용 스테이지에 추가

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git add cat.txt
warning: LF will be replaced by CRLF in cat.txt.
The file will have its original line endings in your working directory

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git ls-files --stage
100644 9b990c20055452bb450a3b8a8be57a5fedd9e416 0       cat.txt

 

이번에는 직접 트리를 만들고 커밋. 저수준 명령어니까 외울필요없음

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master) // 트리생성
$ git write-tree
bdab1ce146a886354808a1601872d36fdf867bdf

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master) // 생성된 트리 객체 확인
$ git ls-tree bdab1c
100644 blob 9b990c20055452bb450a3b8a8be57a5fedd9e416    cat.txt

 

트리로 커밋하기

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master) // 트리로 커밋 생성
$ echo "트리로 커밋하기" | git commit-tree bdab1c -p HEAD
a9ab565d23387e16cc9bb7d94d5c93eccb182cad

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master) // 생성된 커밋 확인
$ git cat-file commit a9ab56
tree bdab1ce146a886354808a1601872d36fdf867bdf
parent cc720419c4db2e421c98e3cd71478751597a8bce
author yoonminsang <apdlyooapdl@naver.com> 1625302435 +0900
committer yoonminsang <apdlyooapdl@naver.com> 1625302435 +0900

트리로 커밋하기

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master) // 커밋 로그 확인
$ git log --oneline
cc72041 (HEAD -> master) 커밋 확인용 커밋

 

HEAD 갱신하기

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ ls .git
COMMIT_EDITMSG  config  description  HEAD  hooks  index  info  logs  objects  refs

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ cat .git/HEAD
ref: refs/heads/master

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ cat .git/refs/heads/master
cc720419c4db2e421c98e3cd71478751597a8bce

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master) // 직접 커밋한 객체로 업데이트
$ git update-ref refs/heads/master a9ab56

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master) // 업데이트 확인
$ cat .git/refs/heads/master
a9ab565d23387e16cc9bb7d94d5c93eccb182cad

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git log --oneline
a9ab565 (HEAD -> master) 트리로 커밋하기
cc72041 커밋 확인용 커밋

 

중복 파일 관리

git에서 파일은 blob 으로 관리가 되는데, git의 blog은 제목이나 생성 날짜와는 관계없이 내용이 같을 경우 같은 체크섬

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ cp cat.txt cat2.txt

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ echo "cat-hanbi" > cat3.txt

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git add cat2.txt cat3.txt
warning: LF will be replaced by CRLF in cat2.txt.
The file will have its original line endings in your working directory
warning: LF will be replaced by CRLF in cat3.txt.
The file will have its original line endings in your working directory

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git ls-files --stage
100644 9b990c20055452bb450a3b8a8be57a5fedd9e416 0       cat.txt
100644 9b990c20055452bb450a3b8a8be57a5fedd9e416 0       cat2.txt
100644 5fa99df9f02522cf1919990c8d21edfc0ced46da 0       cat3.txt

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git commit
[master 904e7e1] 중복 파일 관리 확인용 커밋
 2 files changed, 3 insertions(+)
 create mode 100644 cat2.txt
 create mode 100644 cat3.txt

 

브랜치 작업 살펴보기

브랜치 생성하고 확인해보기

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git branch test

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git log --oneline
904e7e1 (HEAD -> master, test) 중복 파일 관리 확인용 커밋
a9ab565 트리로 커밋하기
cc72041 커밋 확인용 커밋

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ ls .git/refs/heads/
master  test

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ cat .git/refs/heads/test
904e7e1bbad80072b5ad080f8ac18185057b525a

 

브랜치 삭제 및 재생성

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git branch -d test
Deleted branch test (was 904e7e1).

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ ls .git/refs/heads/
master

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git branch test2

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ ls .git/refs/heads
master  test2

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git log --oneline -n1
904e7e1 (HEAD -> master, test2) 중복 파일 관리 확인용 커밋

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ rm .git/refs/heads/test2

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git log --oneline -n1
904e7e1 (HEAD -> master) 중복 파일 관리 확인용 커밋

 

git checkout 관찰하기

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git branch test3 HEAD^

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git log --oneline -n2
904e7e1 (HEAD -> master) 중복 파일 관리 확인용 커밋
a9ab565 (test3) 트리로 커밋하기

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ cat .git/HEAD
ref: refs/heads/master

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git checkout test3
Switched to branch 'test3'

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (test3)
$ cat .git/HEAD
ref: refs/heads/test3

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (test3)
$ git status
On branch test3
nothing to commit, working tree clean

 

체크아웃은 '해당 브랜치로 HEAD를 이동시키고 스테이지와 워킹트리를 HEAD가 가르키는 커밋과 동일한 내용을 변경하는 것이다. 

 

수동 체크아웃

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (test3)
$ echo "ref: refs/heads/master" > .git/HEAD

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git log --oneline -n1
904e7e1 (HEAD -> master) 중복 파일 관리 확인용 커밋

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    cat2.txt
        deleted:    cat3.txt


User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git reset --hard
HEAD is now at 904e7e1 중복 파일 관리 확인용 커밋

User@DESKTOP-VOH9EIA MINGW64 ~/Documents/git-test (master)
$ git status
On branch master
nothing to commit, working tree clean

 

이번 장에서 배운 것들

1. git add 명령을 수행하면 워킹트리의 내용을 스테이지에 추가한다.

2. git commit 명령을 수행하면 스테이지의 내용으로 새로운 커밋을 만든다.

3. 커밋 이후 git status 명령을 내리면 clean한 상태임을 표시해 주는데, 이 상태는 워킹트리, 스테이지, HEAD 커밋들이 모두 동일한 내용을 담고 있다는 뜻이다.

4. 커밋 객체는 트리 객체와 blob 객체들의 조합으로 이루어져 있다.

5. 커밋 객체는 부모 커밋에 대한 참조를 가지고 있다.

6. 브랜치를 생성하면 단순히 브랜치 파일 하나를 추가하낟.

7. 브랜치를 체크아웃하면 head를 해당 브랜치로 변경하고

 

 

 

728x90
LIST
댓글
공지사항