본문 바로가기
기타/Git

[Git] Git 개체 - Commit

by 코딩하는 랄로 2023. 11. 22.
728x90

https://codingralro.tistory.com/248

 

[Git] Git 개체 - Tree

https://codingralro.tistory.com/247 [Git] Git 객체 - Blob Git의 명령어를 보다 잘 사용하기 위해서는 해당 명렁어가 깃 내부적으로 어떻게 동작하는지에 대해 알아야 한다. 또한 동작과정을 이해하기 위해서

codingralro.tistory.com

 

저번 글에서 다루었던 Tree 개체에 이어 이번 글에서는 Git 개체 중 마지막 남은 Commit 개체에 대해서 다루어보겠다. 이번 글에서 다루는 예제들은 저번 글과 이어지는 예제이기 때문에, 예제가 이해가 안된다면 위의 글을 참고하면 된다.

 

 

 

Commit 개체란?

Tree 개체를 통해 Git의 staging area에 올라와 있는 파일들을 Tree 개체와 Blob 개체로 이루어진 스냅샷을 만들어 버전관리를 하는 방법에 대해서 알아보았다. 하지만 예제를 작성하면서 해당 스냅샷을 불러오기 위해서 SHA-1 해시값을 기억해야 하는 번거로움을 느꼈을 것이다.

 

또한, 해당 스냅샷을 누가(브랜치), 언제, 왜 저장했는지에 대한 정보도 없다. 이러한 정보를 저장하기 위해 필요한 것이 커밋 개체이다. 즉, staging area에서 커밋(스냅샷)을 할 때, 커밋 정보에 대한 모든 데이터를 저장하는 개체인 것이다.

 

 

 

Commit 개체 생성

commit 개체는 commit-tree 명령어를 통해 생성할 수 있다. 커밋 개체에 대한 설명(커밋 메세지)과 Tree 개체의 SHA-1 값 초반 6글자를 넘기면 된다. ( 이전에 생성한 tree 개체를 사용하겠다. )

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ echo 'first commit' | git commit-tree 8d56ef
b4098f62d5c5322f4e8d428b98fb769db1f1b358

 

커밋 개체에 해당하는 해시 값이 나오고 이를 git cat-file 명령어를 통해 어떠한 형태로 개체가 구성되어 있는지 살펴보자.

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ git cat-file -p b4098f
tree 8d56ef0d1c9626a311c252277765bfb4955de370
author user.name <user.email> 1700657192 +0900
committer user.name <user.email> 1700657192 +0900

first commit

 

위의 커밋 개체를 살펴보면, commit 해준 스냇샵의 최상단 Tree를 보여준 뒤, 해당 Git 사용자와 커밋한 사람의 정보와 시간 정보를 띄운다. 그리고 한 라인을 띄운 뒤, 커밋할 때 지정해준 커밋 메세지를 보여준다.

 

 

 

Commit 개체로 git history 생성해보기

이제 여기서 file2.txt의 내용을 "file2 is changed"로 변경 후 스냅샷을 생성하여 보겠다.

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ echo 'file2 is changed' | git hash-object -w file2.txt  <= 잘못된 코드...
01e6138faef088714355b81759a88101ce07a1a3

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ git update-index --add file2.txt

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ git write-tree
8d56ef0d1c9626a311c252277765bfb4955de370

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ git cat-file -p 8d56ef
040000 tree 9517b3c33e92dbc329ebcf5cd68e830c551dc90b    dir
100644 blob 2777791d6de7aac03f38b1b8403ad0fae82e28ac    file1.txt
100644 blob 01e6138faef088714355b81759a88101ce07a1a3    file2.txt

 

file2.txt 가 잘 변경이 안 되었다... 위의 잘못된 코드는 file2.txt를 변경하는 것이 아닌 file2.txt 의 내용을 가지고 해시 키를 생성하는 코드이다... file2.txt 를 변경하기 위해서는 아래와 같이 해시키를 생성 후 넣어주거나 직접 변경하면 된다... ( 죄송합니다... )

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ echo 'file2 is changed' | git hash-object -w --stdin
e0cb268cab5f2ff0cb0171a474113bdcb02eb15d

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ git cat-file -p e0cb268cab5f2ff0cb0171a474113bdcb02eb15d > file2.txt

 

 

이대로 두번째 commit 개체를 생성 후 세번째 commit 개체도 생성해 주겠다.. 이 때, 이전에 생성한 커밋 개체를 가리키도록 생성하여 보겠다.

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ echo 'second commit' | git commit-tree 8d56ef -p b4098f
b79b0ff030dd64bb6151dda005c9b808352e2c72

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ git cat-file -p b79b0f
tree 8d56ef0d1c9626a311c252277765bfb4955de370
parent b4098f62d5c5322f4e8d428b98fb769db1f1b358
author yusanggon <yusang5159@gmail.com> 1700658007 +0900
committer yusanggon <yusang5159@gmail.com> 1700658007 +0900

second commit

 

첫번째 커밋을 가리키는 두번째 커밋이 잘 생성되었다. 두번째 커밋을 살펴보면 첫번째 커밋과는 달리 parent 라인이 생긴 것을 볼 수 있다. parent 라인은 바로 이전의 커밋 개체를 가리킨다!! 두번째 커밋의 실수로, 세번째 커밋은 file3.txt 를 추가 후 커밋 개체를 생성하여 주겠다. ( 세번째 커밋은 두번째 커밋을 가리키기 생성!! )

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ echo "third file" | git hash-object -w --stdin
667bb3858a056cc96e79c0c3b1edfb60135c2359

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ git cat-file -p 667bb3858a056cc96e79c0c3b1edfb60135c2359 > file3.txt

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ git update-index --add file3.txt

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ git write-tree
9956e70585f6a3c1e0bef6be4d4a7eb8efe869e4

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ git cat-file -p 9956e7
040000 tree 9517b3c33e92dbc329ebcf5cd68e830c551dc90b    dir
100644 blob 2777791d6de7aac03f38b1b8403ad0fae82e28ac    file1.txt
100644 blob 01e6138faef088714355b81759a88101ce07a1a3    file2.txt
100644 blob 667bb3858a056cc96e79c0c3b1edfb60135c2359    file3.txt

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ echo "third commit" | git commit-tree 9956e7 -p b79b0f
e93d9224b1c7642749fd2c1fb59a6a1f6558514d

 

놀랍게도 이로써 심플한(살짝의 실수가 있었지만..) Git history가 만들어졌다. Git history란 이름 그대로, 커밋 개체를 저장함으로써 현재 브랜치가 작업하는 깃 프로젝트의 역사를 저장하여 볼 수 있는 것이다!!

 

정말 그런지 git log 명령어를 통해 세번째 커밋 개체를 출력하여 보자.

user@DESKTOP-UCJOAKJ MINGW64 /d/GitStudy (master)
$ git log --stat e93d92
commit e93d9224b1c7642749fd2c1fb59a6a1f6558514d
Author: user.name <user.email>
Date:   Wed Nov 22 22:14:30 2023 +0900

    third commit

 file3.txt | 1 +
 1 file changed, 1 insertion(+)

commit b79b0ff030dd64bb6151dda005c9b808352e2c72
Author: user.name <user.email>
Date:   Wed Nov 22 22:00:07 2023 +0900

    second commit

commit b4098f62d5c5322f4e8d428b98fb769db1f1b358
Author: user.name <user.email>
Date:   Wed Nov 22 21:46:32 2023 +0900

    first commit

 dir/file1.txt | 1 +
 file1.txt     | 1 +
 file2.txt     | 1 +
 3 files changed, 3 insertions(+)

 

첫번째, 커밋에서 파일이 3개가 추가되고, 두번째 커밋은 변경이 없었기 때문에 아무런 변경 사항이 없고, 세번째 커밋에서 file3.txt 를 추가한 것을 확인할 수 있다. 여기까지 따라오면서, 대강 눈치챈 분들도 있겠지만 이것이 git의 add 명령어와 commit 명령어를 실행했을 때 Git 내부에서 일어나는 일이다. ( 각 명령어에 대해서는 추후에 더 자세히 다루겠다. )

 

해당 커밋 개체를 그림으로 나타내면 다음과 같은 구조를 가진다.

 

Git은 이렇게 커밋 시 Git 개체를 이용하여 스냅샷을 저장하여 언제든지 원하는 버전으로 되돌아갈 수 있는 것이다. Git 개체는 Git 버전 관리 시스템의 핵심이니 만큼 생성하는 법은 모르더라도 각 개체가 어떤 역할을 하는지 어떤식으로 구성되는지에 대해서 알아두면 좋다!!

728x90

'기타 > Git' 카테고리의 다른 글

[Git] status --short  (1) 2023.11.26
[Git] add  (1) 2023.11.26
[Git] Git 개체 - Tree  (2) 2023.11.21
[Git] Git 개체 - Blob  (1) 2023.11.21
[Git] init  (0) 2023.11.18