02. 커밋 생성하기

준필·2023년 12월 21일
0

git

목록 보기
3/3
post-thumbnail

git을 사용하는 경우는 크게 두 가지입니다.

  1. 로컬 저장소(ex: 내 컴퓨터 디스크)에 있는 버전 관리가 되고 있지 않은 프로젝트에 git을 적용하는 경우
  2. 깃허브와 같은 원격 저장소에 있는 프로젝트를 내 로컬 저장소로 가지고 오는 경우

먼저 첫 번째 경우 어떻게 하는지 확인해봅시다.

지금부터는 리눅스 명령어들을 사용하게 됩니다. 모르는 명령어가 있을 경우 "man <명령어이름>"을 검색하면 여러 내용들을 찾을 수 있습니다.

우선 start-git이라는 디렉토리를 새로 생성했습니다. 디렉토리의 경로는 자유롭게 정하면 됩니다.

$ mkdir start-git
$ cd start-git
$ pwd
/start-git

디렉토리는 윈도우에서의 폴더와 비슷한 개념입니다.

$ touch hello.txt && ls
hello.txt

그리고 touch명령어를 사용해 hello.txt라는 파일을 생성했습니다.

첫 커밋

git init 명령어를 사용해 현재 디렉토리를 git을 이용해 버전 관리를 할 수 있도록 만들어줍니다.

$ git init
Initialized empty Git repository in /start-git/.git/

비어있는 git repository가 생성됐다고 알려줍니다.

git status 명령어를 사용하면 git repository의 상태를 알려줍니다.

$ git status
On branch main

No commits yet

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

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

현재 main 브랜치에 있고 커밋이 하나도 없다는 걸 알 수 있습니다. 당장 브랜치가 뭔지 몰라도 괜찮습니다.

우선 우리는 첫 커밋을 만들겠습니다. 여기서 커밋이란 ep01에서 언급했던 숙제_최종.hwp숙제_진짜최종.hwp와 같은 버전이라고 생각하면 됩니다. 내가 커밋 하나를 생성하면 한 가지의 버전이 추가되는 겁니다.

위의 메시지를 보면 Untrakced files, 즉 깃이 추적하지 않는 파일에 hello.txt가 들어있는 걸 확인할 수 있습니다. 우리는 이 파일을 추적해 버전 관리를 하고 싶으니까 git이 알려주는 대로 git add를 사용해 git이 추적할 수 있도록 해주겠습니다.

$ git add hello.txt && git status
On branch main

No commits yet

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

메시지를 살펴보면 현재 브랜치는 main이고 커밋도 하나도 없다는 걸 알 수 있습니다. 대신 hello.txt 파일이 커밋할 변경사항으로 추가됐습니다.

현재 hello.txt파일은 비어있는 파일입니다. cat 명령어로 파일을 확인할 수 있습니다.

$ cat hello.txt

그럼 이제 git commit을 이용해 새로운 커밋을 생성하겠습니다.

$ git commit -m "첫 번째 커밋"
[main (root-commit) a0c9147] 첫 번째 커밋
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 hello.txt

-m 옵션은 커밋 메시지를 간편하게 작성할 수 있도록 해줍니다. 이 옵션을 넣으면 뒤에 쌍 따옴표 안에 있는 문자열이 커밋 메시지가 됩니다.

git 명령어가 적당히 궁금하면 git <명령어> -h를, 심각하게 궁금하면 git <명령어> --help 를 터미널에 쳐보세요.

$ git status
On branch main
nothing to commit, working tree clean

커밋 후에 git status를 통해 현재 커밋할 게 없다는 걸 확인할 수 있습니다.

이제 main 브랜치가 어떤 커밋들을 가지고 있는지 확인해보겠습니다. git log 명령어는 브랜치의 기록을 확인하는 명령어입니다. 뒤에 브랜치 이름을 넣을 수도 있고, 넣지 않는다면 현재 브랜치의 기록을 보여줍니다.

$ git log
commit a0c9147ee12442437943043e6c2c048df48e96a6
Author: Junepil Lee <hanu9257@gmail.com>
Date:   Thu Dec 21 08:45:32 2023 +0000

    첫 번째 커밋

우리가 커밋한 내용을 순차적으로 볼 수 있습니다. 앞서 우리가 설정했던 작성자의 이름, 이메일과 커밋 시에 입력했던 첫 번째 커밋이라는 메시지 또한 잘 입력됐습니다. 이렇게 우리는 프로젝트의 첫 커밋을 생성했습니다. 앞으로 나오는 모든 커밋은 프로젝트의 버전이라고 이해하면 됩니다.

커밋을 더 만들자

이번에는 echo를 사용해서 hello.txt 파일에 내용을 추가해보겠습니다.

$ echo wolrd > hello.txt
$ cat hello.txt
wolrd

추가된 내용은 전과 같이cat 을 통해 확인할 수 있습니다. 이제 다시 git이 현재 프로젝트의 상태를 어떻게 인지하고 있는지 확인해보겠습니다.

$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   hello.txt

no changes added to commit (use "git add" and/or "git commit -a")

staged 상태가 아닌 변경사항에 hello.txt가 있는 걸 확인할 수 있습니다. 그리고 아래를 보니 hello.txt는 변경됐다고 알려주고 있고, 커밋하기 위해 추가된 변경사항이 없다고 합니다.

우리는 이 상태를 살펴보겠습니다. 평소에 문서나 다른 파일들을 작업하다가 ctrl + s를 눌러서 저장해본 적이 있나요? 있다면 그때 혹시 내가 원하는 단락이나 부분만을 특정해서 저장할 수 있었나요? 그렇지 않았습니다.

하지만 어떤 프로젝트에 파일이 10개가 있을 때, 파일 1개에 변경 사항이 생겼다고 파일 10개를 전부 새로 저장한다면 이는 저장 공간의 낭비로 이어집니다. 그래서 git은 똑똑하게 변경된 부분만 저장할 수 있게 해줍니다. 심지어 한 파일 안에서도 마찬가지입니다.

바로 여기서 staging area가 등장합니다. working directory 즉 현재 변경한 내용들 중에 다음에 만들 커밋에 넣고 싶은 내용들을 staging area에 보관했다가, 이 내용들을 가지고 커밋을 생성하는 겁니다.

$ git add *
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   hello.txt

이번에는 git add *를 사용해서 변경 사항을 staging area에 추가했습니다. git add는 기본적으로 파일 이름을 뒤에 붙여서 staging area에 추가하지만 이렇게 *를 붙이면 git status를 사용했을 때 나오는 모든 변경 사항들을 staging area에 추가합니다. 또한 git add ./foo/*같이 경로 내의 모든 변경된 파일도 추가할 수 있습니다.

똑같은 방식으로 goodbye.txt를 만들고 staging area에 추가했습니다. 커밋될 변경 사항들에 hello.txt가 변경됐고 hell.txt가 새로 생겼다는 내용을 볼 수 있어요.

$ echo bye > goodbye.txt
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   hello.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        goodbye.txt
$ git add * && git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   goodbye.txt
        modified:   hello.txt

그리고 이전에 했던 것과 같이 커밋을 만들었습니다.

$ git commit -m "hello.txt  내용 추가, goodbye.txt 생성"
[main 10aa7d4] hello.txt내용 추가, goodbye.txt 생성
 2 files changed, 2 insertions(+)
 create mode 100644 goodbye.txt

이제 다시 maingit log를 사용해 확인해보면

$ git log
commit 10aa7d430fc0e9b860ea325e8ebbf92bd8f9bcbf
Author: Junepil Lee <hanu9257@gmail.com>
Date:   Thu Dec 21 09:02:06 2023 +0000

    hello.txt내용 추가, goodbye.txt 생성

commit a0c9147ee12442437943043e6c2c048df48e96a6
Author: Junepil Lee <hanu9257@gmail.com>
Date:   Thu Dec 21 08:45:32 2023 +0000

    첫 번째 커밋

main에 두 개의 커밋이 있는 걸 볼 수 있습니다.

브랜치

커밋의 이름

브랜치를 설명하기에 앞서 커밋마다 존재하는 의미를 알 수 없는 영어와 숫자로 이루어진 문자열은 체크섬이라고 불립니다. 커밋을 만들 때 메시지를 작성하긴 했지만 git은 다른 방법으로 각각의 커밋을 구분하는데 이때 사용되는 게 바로 각 커밋을 지칭하는 영어와 숫자 조합입니다.

예를 들어 우리의 첫 번째 커밋은 앞의 6자리를 이용해 a0c914이라고 부를 수 있고, 같은 방법으로 두 번째 커밋은 10aa7d라고 부를 수 있습니다. 일반적으로 이렇게 앞의 6자리를 이용해서 커밋을 지칭합니다.

git은 똑똑하게 앞자리도 커밋끼리 겹치지 않게 체크섬을 만들어주기 때문에 커밋을 표현할 때 6자리로도 충분합니다. 어떤 방식으로 이 체크섬을 만드는지 궁금하다면 SHA에 대해 찾아보길 추천합니다. 체크섬은 커밋의 내용이 같더라도 다를 수 있습니다.

브랜치의 필요성

브랜치는 커밋들의 관심사를 구분하기 위해 사용됩니다.

앞서 커밋은 하나의 버전이라고 했었습니다. 브랜치는 이 커밋들이 연결되어 구성됩니다. 만약 연결 리스트를 배웠다면 이해하기 쉽습니다. 왜나하면 커밋은 생성될 때 부모 커밋을 가지고 있기 때문입니다. 지금 우리의 main 브랜치에는 커밋이 두 개가 연결되어 있는 상태이고, 10aa7da0c914를 부모 커밋으로 가지고 있습니다. 이 때문에 생성 순서와는 반대되는 포인터로 연결되어 있는 게 바로 브랜치입니다.

브랜치는 연결 리스트를 사용해 공통된 관심사에 속해 있는 커밋들을 모아놓은 것입니다. 덕분에 나중에 한 관심사에 대한 변경 사항들을 볼 때 이 관심사에 해당하는 브랜치만 보면 됩니다. 자동차를 프로그램으로 만들 때 바퀴를 만드는 영역, 창문을 만드는 영역을 따로 나눠서 창문과 바퀴 브랜치를 분리하면 작업도 각각 할 수 있고 관리도 더 쉬울 겁니다.

지금은 main이라는 의미가 모호한 브랜치 하나만을 사용하고 있어 와 닿지 않겠지만 나중에 여러 개의 브랜치를 만들다 보면 왜 브랜치가 필요한지 감이 잡힐 겁니다.

profile
공부할 게 너무 많잖아?

0개의 댓글