Git을 이용하여 소스코드의 버전관리를 해 보자

1. Git의 환경 설정: git config

현재 사용하고 있는 리눅스 환경에서 git을 한 번이라도 사용한 적이 없다면 글로벌 환경 설정을 해주어야 합니다. 만약 환경 설정을 한 적이 있는 사용자라면 이 부분은 건너 뛰어도 됩니다.

먼저, git을 사용할 사용자의 이름과 이메일 주소를 설정해 볼 것입니다. 이들은 나중에 소개할 commit 메시지에 author 라는 항목에 나타나게 됩니다. git config --global 명령을 이용하여 다음과 같이 설정해 줍니다.

$ git config --global user.name "Sukjun Kim"
$ git config --global user.email "dandyrilla@naver.com"

이러한 설정들은 어디에 저장되는 것일까요? Git의 설정을 담고 있는 파일들은 계층에 따라 세 개가 존재합니다. 각 설정은 역순으로 우선시됩니다. 즉, system 설정은 global 설정에 의하여 무시될 수 있고, global 설정은 작업 중인 Git 디렉토리의 설정이 우선시 되어 무시될 수 있습니다.

자, 그럼 설정한 정보들을 확인해 볼까요? 다음과 같이 git config --list 명령을 사용합니다.

$ git config --list
user.name=Sukjun Kim
user.email=dandyrilla@naver.com

또는 설정한 특정 키 값만을 보려면 git config {key}와 같이 입력하면 됩니다.

$ git config user.name
Sukjun Kim

user.name, user.email 말고도 config 명령으로 지정할 수 있는 글로벌 변수들이 매우 많습니다. 이를 보려면 다음과 같이 입력하면 됩니다. config 명령어 외에도 다른 명령어에 대한 도움말을 보고 싶다면 git help {command}와 같이 입력하면 man page를 보여줍니다.

$ git help config

2. Git으로 버전관리 시작하기 (git init)

Git 설정을 마쳤으니 이제 본격적으로 소스코드의 버전관리를 시작해 봅시다. git으로 버전관리를 시작할 디렉토리에 들어가서 git init이라는 명령어를 입력하여 새로운 로컬 저장소를 만듭니다. 이는 현재 위치에 .git 폴더를 만들고 그 안에 git에 의해 관리되는 정보들이 담긴 여러 파일들이 생성되도록 하는 명령입니다.

$ git init
Initialized empty Git repository in /home/Sukjun/project/.git/

앞으로 소스코드를 수정하면서 따로 열어볼 필요는 없겠지만, 어떤 파일들이 생성되었는지 한번 살펴볼까요? tree .git 명령어로 방금 전에 생성한 .git 폴더의 구조와 파일들을 살펴보았습니다. branch의 정보를 저장하고 있는 braches 파일, 현재 폴더의 git 설정을 담고 있는 config 파일 등이 생성된 것이 보입니다.

$ tree .git
.git
|-- branches
|-- config
|-- description
|-- HEAD
|-- hooks
|   |-- applypatch-msg.sample
|   |-- commit-msg.sample
|   |-- post-update.sample
|   |-- pre-applypatch.sample
|   |-- pre-commit.sample
|   |-- prepare-commit-msg.sample
|   |-- pre-rebase.sample
|   `-- update.sample
|-- info
|   `-- exclude
|-- objects
|   |-- info
|   `-- pack
`-- refs
    |-- heads
    `-- tags

이제 소스코드 관리 개념으로 돌아와서, 자주 사용하게 되는 명령어를 하나 소개하겠습니다. git status 명령은 만들어진 git 저장소의 현재 상태를 살펴보는 명령어입니다. git은 관리되어야 할 파일을 따로 추가(git add)해줘야 버전 관리를 시작합니다. 따라서 어떤 파일들이 현재 관리되고 있고 관리되지 않는지, 그리고 관리되는 파일 중에 어떤 파일이 이전 커밋(commit, 커밋의 개념은 뒤에 따로 설명하겠습니다.)을 기준으로 해서 수정되었고 수정되지 않았는지를 이 명령어를 통해 확인할 수 있습니다.

$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       LICENSE
#       scripts/
#       setup.py
nothing added to commit but untracked files present (use "git add" to track)

3. Git으로 관리할 파일 추가(git add) 및 삭제(git rm --cached)하기

관리되고 있지 않은 파일(untracked files)을 관리되는 파일(tracked files)로 바꾸려면 git add 명령어를 이용해 파일을 추가해주면 됩니다. 아래는 LICENSE 파일과 setup.py 파일을 버전관리를 적용할 대상 파일로 삼겠다는 명령입니다.

$ git add LICENSE
$ git add setup.py

이후 다시 git status를 입력하면 달라진 상태를 확인할 수 있을 것입니다. 살펴보면 setup.py가 새로운 파일로 추가되었음을 알 수 있습니다.

$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   LICENSE
#       new file:   setup.py
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       scripts/

만약에 버전관리가 필요 없는 파일을 잘못하여 추가했다면 git rm --cached <file> 명령으로 관리대상에서 다시 제외 시킬 수도 있습니다. LICENSE 파일을 다시 관리대상에서 제외하려면 다음과 같이 입력합니다. --cached 옵션을 주는 이유는 파일은 실제로 삭제되지 않고 관리대상에서만 제외시키기 위함입니다. 만약에 파일도 삭제하고 싶으면 그 대신 -f 옵션을 주면 됩니다.

$ git rm --cached LICENSE
rm 'LICENSE'

4. Git으로 현재 시점 저장하기 (git commit)

자, 그렇다면 이제 git에게 현재 시점의 상태를 기억시키게 해주어야 합니다. 이를 커밋이라고 부르며 나중에 무언가 잘못 수정했을 때 되돌아 올 수 있습니다. 마치 우리가 윈도우 운영체제가 깨졌을 때 특정 시점으로 돌아갈 수 있는 복원 시점을 만드는 것과 비슷하다고 보시면 됩니다.

$ git commit -m "First commit"

5. 원격 저장소 이용하기

5.1. 복제해오고(clone), 가져오고(pull), 올려두기(push)

원격 저장소로부터 파일들을 다운로드 받기 위해서는 복제(clone)를 하면 됩니다. 원격 저장소에 접속하면 아래와 같이 ‘clone or download’라는 초록색 버튼이 보일 텐데요. 이 버튼을 클릭하고 ‘Use HTTPS’를 클릭하여 다운로드 받을 원격 저장소의 주소를 얻어옵니다.

Image

그리고 로컬 환경에서 git clone명령어를 이용해 원격 저장소의 파일들을 다음과 같이 다운로드 받아줍니다.

$ git clone https://github.com/biopython/biopython.git
Cloning into 'biopython'...
remote: Counting objects: 74562, done.
remote: Compressing objects: 100% (52/52), done.
remote: Total 74562 (delta 19), reused 28 (delta 9), pack-reused 74500
Receiving objects: 100% (74562/74562), 43.74 MiB | 4.55 MiB/s, done.
Resolving deltas: 100% (55587/55587), done.
Checking out files: 100% (2098/2098), done.

8. Git 사용하면서 마주친 에러들: Trouble shootings

8.1. Not a git repository

git으로 관리되지 않는 디렉토리에서 git status를 치면 다음과 같이 나타납니다.

$ git status
fatal: Not a git repository (or any parent up to mount point /home/user)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

9. Git 사용법 정리된 문서들