[Tip] git 사용법 - 코드 관리(SCM) & 버전 관리(VCS)


지난 포스팅

1. 마크다운 문법

2. github 가입 및 다운로드

3. git bash shell 명령어


지난 포스팅까지 git을 사용하기 위한 빌드업을 했습니다. 이제는 본격적으로 git을 사용해보도록 하겠습니다. git을 사용하는 용도는 크게 두 가지 입니다.

  1. 코드 관리(SCM) & 버전 관리(VCS) 도구로서의 git

  2. 협업 도구로서의 git

기본적으로 git 자체는 1번의 기능을 수행하기 위한 것이지만 github와 결합되면서 2번의 기능까지 수행할 수 있게 되었습니다. 눈치 채신 분들이 있겠지만 gitgithub는 다릅니다. 둘의 차이에 대해 간단하게 짚고 넘어가도록 하겠습니다.

git

로컬 저장소 (쉽게 말해 자신의 컴퓨터라고 생각하시면 됩니다.) 에서 작업 폴더의 버전을 관리해주는 시스템입니다. 소스 코드의 변경 사항을 버전의 형태로 모두 저장해주어 수정 사항 확인 및 롤백이 쉽습니다.

여담으로 git을 개발한 사람은 Linus Torvalds라는 사람인데 이름을 보면 아시겠지만 Linux를 개발한 사람입니다. 그래서 git bash의 명령어는 Linux의 명령어를 사용하는 것이고 Linux OS에는 git이 기본적으로 내장되어 있습니다.

github

원격 저장소 (클라우드와 비슷한 개념입니다.) 에서 작업 폴더의 버전을 관리해주는 시스템입니다. 따라서 작업 폴더에 타인의 접근이 가능해지게 되며 협업 및 배포의 기능을 수행할 수 있게 됩니다.

이번 포스팅에서는 로컬 저장소에서 코드 관리 및 버전 관리를 어떻게 하는지에 대해 다룰 것이고 원격 저장소에서 할 수 있는 협업에 관한 내용은 다음 포스팅에서 다루도록 하겠습니다. 먼저 git bash를 실행해봅시다. 홈 디렉토리에서 cd 명령어를 통해 원하는 디렉토리로 이동해도 되지만 이동하고 싶은 폴더를 열고 마우스 오른쪽을 눌러 Git Bash Here를 실행시키면 간단히 이동할 수 있습니다.

메뉴

git bash를 열었다면 우리가 작업할 폴더를 만들어주고 이동해봅니다. 저는 작업 폴더의 이름을 workspace라고 만들고 이동해보겠습니다.

lhmlh@DESKTOP-99JLML6 MINGW64 ~
$ mkdir workspace

lhmlh@DESKTOP-99JLML6 MINGW64 ~
$ cd workspace

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace
$

(1) git init

git init은 현재 폴더를 git 저장소로 만드는 명령어입니다. 위에서 만든 workspacegit 저장소로 만들어보겠습니다.

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace
$ git init
Initialized empty Git repository in C:/Users/lhmlh/workspace/.git/

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)

눈썰미가 좋은 분이라면 어떤 차이가 생겼는지 바로 눈치채실 수 있을 것입니다. 경로 옆에 (master)라는 표시가 붙었습니다. 그리고 해당 폴더를 열어보시면 .git이라는 폴더가 생긴 것을 확인할 수 있습니다. 이제 workspace 폴더는 git에서 버전 관리를 해주는 폴더가 되었습니다. 만약 더이상 해당 폴더를 git에서 관리하고 싶지 않다면 .git 폴더를 지워주시면 됩니다.

(2) git status

git statusgit의 관리 현황을 출력해줍니다. 한 번 입력해봅시다.

$ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

한 줄 씩 읽어보면


On branch master

현재 master라는 branch에 있다. (branch의 개념은 다음 포스팅에서 설명하겠습니다.)

No commits yet

아직 아무것도 commit 된 것이 없다.

nothing to commit (create/copy files and use “git add” to track)

commit 할 것이 없다. 파일을 만들어서 git add 해달라.


출력된 텍스트를 미루어 볼 때 git에서 작업물을 관리하기 위해서는 먼저 파일을 만들고 그것을 add하고 commit을 해야하는 구나라고 생각해볼 수 있습니다. workspacetouch 명령어를 이용해 a.txt 파일을 생성해보고 다시 git status를 입력해보겠습니다.

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ touch a.txt

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git status
On branch master

No commits yet

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

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

뭔가 다른 텍스트가 출력됐습니다.

Untracked files: (use “git add ..." to include in what will be committed) a.txt

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

git에게 추적되지 않은 파일이 발견되었다. commit을 하고 싶다면 git add를 사용해서 추적할 수 있게 해라.’

대략 이런 말인 것 같습니다. 이제 가장 중요한 git addgit commit에 대해 알아봅시다.

(3) git add & git commit

git의 작동 방식을 흔히 사진을 찍는 것에 비유합니다. 각자 폰을 들고 사진기 어플을 실행해봅시다. 사진을 찍기 위해서는 먼저 찍고자 하는 대상을 렌즈에 비춰야합니다. 이것이 git에서 파일을 add하는 것과 같습니다. a.txtadd를 통해 렌즈에 비춰봅시다. git add 파일명 형식으로 입력하시면 됩니다.

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git add a.txt

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git status
On branch master

No commits yet

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

Changes to be committed: (use “git rm –cached ..." to unstage) new file: a.txt

새로운 파일 a.txtgit에게 인식된 것을 확인할 수 있습니다.


사물을 렌즈에 올리기만 하면 사진은 찍히지 않습니다. 셔터를 눌러야 비로소 사진이 찍히고 앨범에 저장이 되는 것이죠. 셔터를 눌러 앨범에 저장하는 것이 git에서는 commit한다고 말합니다. 셔터를 눌러봅시다. git commit -m "해당 버전에 대한 설명" 으로 입력하시면 됩니다. “해당 버전에 대한 설명”을 쓰는 이유는 해당 버전의 기능, 수정내역 등 대해 한 눈에 파악하기 위해서 입니다. 사진으로 비유하면 사진을 저장할 때 사진을 찍은 날짜와 장소 등으로 이름을 붙여줘야 하는 것과 동일합니다.

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git commit -m "add a.txt"
[master (root-commit) 907b729] add a.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a.txt

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git status
On branch master
nothing to commit, working tree clean

축하합니다! git 저장소에 첫 번째 버전을 올리는데 성공했습니다. 여세를 몰아 두 번째 세 번째 버전도 올려보도록 하겠습니다. b.txtc.txt파일을 차례대로 add, commit 해봅시다.

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ touch b.txt

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git add b.txt

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git commit -m "add b.txt"
[master 2a61a16] add b.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 b.txt

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ touch c.txt

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git add c.txt

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git commit -m "add c.txt"
[master d3a48c7] add c.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 c.txt

workspace에는 세 가지 버전이 생겼습니다. 버전 정보를 확인해보도록 하겠습니다.

(4) git log

git log는 현재까지의 버전 정보를 모두 출력하는 명령어 입니다. 좀 더 깔끔한 출력을 위해 두 가지 옵션이 있습니다.

  • git log --oneline : 버전 정보를 한 줄로 출력합니다.
  • git log --숫자 : 특정 개수만 출력합니다.

git log --oneline 명령어를 통해 버전 정보를 출력해봅시다.

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git log --oneline
d3a48c7 (HEAD -> master) add c.txt
2a61a16 add b.txt
907b729 add a.txt

d3a48c7, 2a61a16, 907b729은 각 버전의 일련 번호입니다. 일련 번호와 함께 commit할 때 함께 썼던 설명이 출력됩니다. git은 이런 식으로 작업 폴더의 변경 이력을 모두 저장합니다.


앗! 그런데 갑자기 c.txt 파일에 치명적인 오류가 발생하였습니다. 도저히 수정이 불가능한 오류이기 때문에 c.txt 파일을 만들기 이전의 버전으로 돌아가고 싶습니다. 어떻게 하면 좋을까요?

(5) git checkout

git checkout은 특정 시점의 버전을 체크할 수 있는 명령어 입니다. git checkout 해당 버전의 일련번호를 입력합니다. c.txt를 추가하기 전 버전으로 돌아가 봅시다.

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git checkout 2a61a16
Note: switching to '2a61a16'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 2a61a16 add b.txt

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace ((2a61a16...))
$ ls
a.txt  b.txt

ls 명령어를 입력하니 놀랍게도 c.txt가 사라진 것을 확인할 수 있습니다. 해당 파일을 열고 들어가면 c.txt가 사라진 것을 알 수 있습니다. 하지만 이것은 실제로 과거의 버전으로 돌아간 것이 아니라 과거의 버전을 조회한 것에 불과합니다.

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)

HEAD is now at 2a61a16 add b.txt

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace ((2a61a16...))

위의 코드에서 중요한 텍스트 세 줄만 가져왔습니다. 눈치 채셨겠지만 경로 옆에 붙은 표시가 처음에는 master 였다가 ‘HEAD2a61a16에 있습니다.’ 라는 말 다음에 2a61a16로 바뀌었습니다. git 세상에서 현재의 기준은 항상 master입니다. git checkout은 타임머신과 같아서 과거로 이동할 수는 있지만 엄연히 현재는 master에 존재합니다. 즉 git checkout을 통해 과거를 현실로 만든 것이 아니라 현실은 그대로 두고 과거로 이동했을 뿐이라는 것입니다. 그렇다면 현재를 아예 없던 일로 만들고 과거를 다시 현재로 만들어 버리는 방법은 있을까요? 물론 있습니다.

(6) git reset

git reset은 현재를 아예 없던 일로 만들고 과거를 다시 현재로 만들어 버리는 명령어 입니다. 현재를 없애버리기 위해서는 우선 현재로 다시 돌아가야 합니다. git checkout master를 입력하여 현재로 돌아갑시다.

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace ((2a61a16...))
$ git checkout master
Previous HEAD position was 2a61a16 add b.txt
Switched to branch 'master'

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ ls
a.txt  b.txt  c.txt

git reset을 통해 c.txt가 없었던 버전으로 돌아가 보겠습니다. git reset 돌아가고 싶은 버전의 일련번호 로 입력해주시면 됩니다.

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git log --oneline
d3a48c7 (HEAD -> master) add c.txt
2a61a16 add b.txt
907b729 add a.txt

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git reset 2a61a16

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git log --oneline
2a61a16 (HEAD -> master) add b.txt
907b729 add a.txt

git checkout을 했던 때와 다르게 이번엔 경로 옆에 그대로 master가 유지됐습니다. git log를 통해 변경 이력을 확인해보면 c.txt를 추가했던 이력이 사라졌습니다. 여기서 주의해야할 것은 git에서 reset을 한 것이 작업 폴더에 반영되지는 않는다는 것입니다. 다만 gitcommit되기 이전으로 돌아간 것 뿐입니다.

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ ls
a.txt  b.txt  c.txt

lhmlh@DESKTOP-99JLML6 MINGW64 ~/workspace (master)
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        c.txt

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

ls를 입력하면 c.txt는 그대로 있습니다. 하지만 git status를 입력하면 c.txtgitcommit되지 않았다는 것을 알 수 있습니다.

지금까지 git을 이용하여 로컬 저장소에서 코드 관리 및 버전 관리를 하는 방법에 대해서 알아봤습니다. 다음 포스팅에서는 github를 이용해 협업하는 방법을 다뤄보도록 하겠습니다. 읽어주셔서 감사합니다~


다음 포스팅

github 사용법 - push&pull