버전 관리 시스템, Git, GitHub

버전 관리 시스템의 개념과 Git, GitHub에 대해서 배웁니다. 또 오픈소스에 대해서 알아봅니다.
Git, GitHub, 버전 관리 시스템, 버전


버전 관리

버전 관리(Version Control, Revision Control)란 소프트웨어 개발 과정에서 소스코드 및 리소스의 변화와 그 파일들을 기록하는 것을 말합니다. 그 필요성에 대해서 먼저 생각해보겠습니다.

  • 소스코드를 안전하게 백업해두고 싶다.
  • 개발 중 문제점이 발견되어, 과거로 돌이가고 싶다. 혹은 과거의 소스코드를 참고하고 싶다.
  • 두 명 이상이 같은 프로젝트를 진행하고 싶다.

Version ControlVersion Control

Backup은 어렵지 않습니다. 로컬 보조기억장치, 공유 파일 시스템이나 원격 서버 등에 소스코드를 주기적으로 백업 할 수 있겠습니다. 이런 작업을 자동화하는 것도 어려운 문제는 아닙니다.

코드를 과거로 되돌리는 것(Revert)도 과거 백업본을 이용하면 불가능하지 않겠습니다. 물론, 과거 백업본과 현재 소스코드의 차이점을 일일이 비교하면서, 코드를 특정 시점으로 복원하는 작업이 쉽지는 않겠습니다.

마지막으로 파일시스템 기반의 프로젝트의 협업은 상당히 어려울 것 같습니다. 내가 할 일, 네가 할 일을 명확히 분담하고, 최대한 프로젝트를 파일별로 분리하여 개발해도, 작업하다보면 서로 간의 소스코드 변경사항에 충돌(Conflict)이 있기 마련입니다.

협업과 그 기록협업과 그 기록

또 소스코드를 취합(Merge)하려면, 이메일, 외부저장장치를 쓸까요? 혹은 공유 파일 시스템이나 원격 서버의 도움을 받을까요? 최신 소스코드의 공유는 해결되었다 쳐도, 소스코드나 리소스를 취합하려면 단순히 파일을 덮어쓰는 것보단 더 많은 고민이 필요합니다. 안정적인 코드인지? 코드 품질은 나쁘지 않은지? 이 코드는 어떤 이슈를 해결하는지?

소규모 프로젝트라면 단순히 소스코드를 서로 공유하면서 주기적으로 취합하는 것으로 충분할지 몰라도, 10명, 100명, 1000명이 동일한 프로젝트에 기여하기 위해선 버전 관리를 위한 견고한 시스템이 필요합니다.

Git

버전 관리 시스템(VCS; Version Control System) 또는 소스코드 관리 도구(SCM; Source Code Management)는 위와 같은 버전 관리 문제를 해결해주는 소프트웨어를 말합니다. 과거부터 쓰이던 여러가지 프로그램들(SVN, CVS 등)이 있지만, 강제적으로 SVN 등을 써야하는 이유가 아니라면, Git으로 VCS를 시작해나가는 것이 최선이라고 생각합니다.

GitGit

Git

  • 사용법이 복잡함
  • 무료이며 오픈소스, VCS 중 가장 높은 점유율
  • 개개 파일(텍스트 외에 바이너리까지)별 생성 및 파일명 변경, 이동, 내용 추가 및 삭제에 대한 모든 이력을 효율적으로 보관
  • 생성되는 버전(Commit)별로 작성자 및 변경 사항을 기록 할 수 있음
  • 원격 저장소 및 서버를 두면 손쉽게 협업 할 수 있음
  • 소스코드 충돌(Conflict)시 가능한 경우 자동으로 취합(Merge) 할 수 있음
  • 버전을 분기(Branch)하여 충돌을 줄이면서 짜임새있고 장기적인 소프트웨어 개발 계획을 수립 할 수 있음

Github DesktopGithub Desktop

Git 설치

Windows 사용자는 강의 초반에 Git Bash를 설치했다면, 이미 Windows용 Git을 설치한 셈입니다. Git을 설치하지 않은 분이나 Unix 계열 사용자는 Git 홈페이지 에서 CLI 프로그램을 다운 받을 수 있습니다. 또 Git GUI 프로그램에 관심이 있다면 홈페이지를 방문해보세요.

저장소(Repository)

협업을 떠나서 로컬에서 백업, 히스토리를 기록 용도로만 Git을 사용한다고 생각해 보겠습니다. Git을 이용하면 특정 디렉토리를 기준으로 저장소(Repository)를 생성 할 수 있습니다. 저장소는 그 루트 디렉토리(Top Level Directory) 하부에 .git 디렉토리를 생성하고, 루트 디렉토리에 생성되는 모든 파일(.git 디렉토리를 제외하고)에 대한 버전별 스냅샷(Snapshot; 특정 시점의 모든 데이터)을 .git 디렉토리에 저장하게 됩니다.

Git Repository StructureGit Repository Structure

이때 저장소에서는 프로젝트의 이력 및 데이터를 OS 종속적인 파일시스템(디렉토리 구조 등)을 통해서 보관하지 않고 독자적인 형태의 데이터베이스를 구축합니다.

git init

works$ mkdir git-test
git-test$ cd git-test/
git-test$ git init
Initialized empty Git repository in /Users/dehypnosis/works/git-test/.git/

작업 디렉토리 (Working Directory)

당장 저장소 내부에 대해서는 신경을 끄고, 현재 편집중인 소스코드 및 리소스가 존재하는 작업 디렉토리에서 프로젝트의 이력을 저장소에 반영하는 메커니즘을 알아보겠습니다. 작업 디렉토리 내의 모든 파일은 4가지 상태를 갖습니다.

Git File StatusGit File Status

먼저 저장소에서 이력을 추적하지 않는 파일은 Untracked 상태입니다. 물론 최초의 파일들은 모두 Untracked 입니다. 이후 저장소에 추가(git add)되면 추적되는 파일들은 세가지 상태를 오가게 됩니다.

git add/status/commit/log

Working Directory - Staging Area (Index) - Repository (History)Working Directory - Staging Area (Index) - Repository (History)

마지막 버전(스냅샷)에서 내용이 변경된 파일은 Modified 상태가 됩니다. 이때 사용자가 git add를 통해 Staged 상태로 변경 할 수 있습니다. Staged란 새로운 버전에 반영될 준비가 되었다는 의미입니다.

이후 git commit -m '메세지’를 통해서 마지막 버전에 Staged 파일들을 반영해 새로운 버전을 생성하게 됩니다. 이때 새로운 버전이 생성된 이후에 파일들은 다시 Unmodified 상태로 돌아갑니다.

위처럼 Untracked/Modified -> Staged -> Committed의 상태를 거치면서 새로운 버전을 생성 할 수 있습니다.

git-test$ touch a b c
git-test$ ls
a b c
git-test$ git status
On branch master

Initial commit

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

  a
  b
  c

nothing added to commit but untracked files present (use "git add" to track)
git-test$ git add a b
git-test$ git status
On branch master

Initial commit

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

  new file:   a
  new file:   b

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

  c

git-test$ git commit -m 'a b files added'
[master (root-commit) 153cab6] a b files added
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a
 create mode 100644 b
git-test$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

  c

nothing added to commit but untracked files present (use "git add" to track)
git-test$ git log
commit 153cab6ac3dbbd6e0a621af3f3025c1d483b34e0
Author: <dehypnoss@gmail.com>
Date:   Tue Jun 6 18:14:02 2017 +0900

    a b files added

git rm

외부적인 요인으로 파일이 삭제된 경우(rm 등으로)에는 Git은 파일을 Modified 상태로 추적합니다. git rm 명령어도 존재하는데, rm 명령어와 큰 차이는 없고, 파일을 삭제한 뒤 바로 Staged 상태로 변경해줍니다.

git rmgit rm

Tracked 파일을 Untracked 상태로 바꾸려면 git rm --cached를 이용합니다. 이때 파일은 새로운 버전(스냅샷)에서 제거되지만 작업 디렉토리에서 삭제되지는 않습니다.

git-test$ git rm --cached a
rm 'a'
git-test$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  deleted:    a

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

  a
  c

git-test$ rm b
git-test$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  deleted:    a

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

  deleted:    b

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

  a
  c

git-test$ git rm b
rm 'b'
git-test$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  deleted:    a
  deleted:    b

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

  a
  c

git-test$ ls
a c

그 외 명령어

이외에 git reset을 통해서 Staged 상태를 다시 Modified로 복구(파일 내용은 유지)하거나, git checkout을 통해서 Modified 상태를 다시 Unmodified로 복구(파일 내용도 복원)할 수 있습니다. 또는 git revert를 통해서 특정 버전으로 회귀하는 새로운 버전을 발행(commit) 할 수 있습니다.

이외에도 파일을 세세하게 복원하는 방법이나, 프로젝트를 분기(Branch)하는 법, 버전간 변경 사항을 비교하는 법, 저장소에 대한 설정 등 Git은 방대한 기능을 제공합니다. 추가적인 내용들은 필요에 따라서 실전 환경에서 학습하시길 바랍니다. 이후에 아래에서는 협업에 필요한 기초적인 내용과 GitHub에 대해서 다루도록 하겠습니다.

Git에서 제공하는 온라인 교재

Git으로 협업하기

협업을 위해서는 우선 모두가 접근 가능한 원격 Git 저장소 서버가 필요하겠습니다. 그리고 그 서버에 저장소(Bare Repository; Working Directory 없이, .git 디렉토리와 동일)를 생성하고, 클라이언트의 요청을 처리할 Git 서버 프로그램을 실행하면 되겠습니다. 물론 Git에서 원격 저장소 서버 구축을 위한 프로그램 및 가이드를 제공합니다.

GitHubGitHub

당장 원격 저장소 서버를 구축하는 일에 대해서는 신경을 끄고, GitHub 에 대해서 알아보겠습니다. Git Hosting Service는 Git 원격 저장소 서버 임대 및 다양한 협업 도구를 제공하는 서비스입니다. 수 많은 업체들이 있지만, 그 중에서도 GitHub는 오픈소스의 성지라고 불립니다.

  • Git 원격 저장소 생성 및 권한 관리
  • 웹에서 바로 저장소의 소스코드를 리뷰, 생성하거나 편집 가능
  • 웹에서 바로 저장소의 소스코드를 취합(Merge) 가능
  • 저장소 별로 협업을 위한 도구들(게시판 등)을 제공
  • 오픈소스 프로젝트를 검색하고 또 기여 할 수 있음

GitHub Diff toolGitHub Diff tool

GitHub의 핵심적인 서비스는 무료로 원격 저장소를 생성하고 웹 상에서 쉽게 관리 할 수 있다는 점입니다. 이를 통해서 원격 저장소를 위한 서버 구축 비용을 절감 할 수 있습니다. 하지만 이때 Private 저장소는 유료이기 때문에 무료로 저장소를 생성하려면 프로젝트를 모두에게 공개해야 합니다.

GitHub Issues toolGitHub Issues tool

또한 이슈 게시판, 마일스톤 작성 등 강력한 협업 도구를 제공하기 때문에 전세계의 수 많은 개발자들이 오픈소스 프로젝트에 효율적으로 기여 할 수 있습니다. 물론 Private 저장소, 영리 프로젝트에서도 협업 도구는 큰 도움이 됩니다.

GitHub 가입

https://github.com/join 에서 GitHub 계정을 생성합니다.

원격 저장소 생성

새로운 프로젝트를 위해서, 먼저 원격 저장소를 GitHub에서 생성합니다. https://github.com/new 에서 저장소를 생성 할 수 있습니다. 저장소 생성시 README.md 파일을 생성하지 않으면, 최초의 저장소에는 아무런 버전이 존재하지 않습니다.

로컬 저장소 및 최초 버전 생성

먼저 로컬에서 Git 저장소를 생성하고, 최초의 버전을 만들어 보도록 하겠습니다.

works$ mkdir workshop-git
works$ cd workshop-git/
workshop-git$ git init
Initialized empty Git repository in /Users/dehypnosis/works/workshop-git/.git/
workshop-git$ echo "# Workshop GitHub Practice" > README.md;
workshop-git$ git add .
workshop-git$ git status
On branch master

Initial commit

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

  new file:   README.md

workshop-git$ git commit -m 'initial commit'
[master (root-commit) 49738c0] initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
workshop-git$ git log
commit 49738c0070c2aaf46eabecd86e4d055b7ce35888
Author: <dehypnoss@gmail.com>
Date:   Wed Jun 7 12:41:08 2017 +0900

    initial commit

I/O Redirection: echo "# Workshop GitHub Practice" > README.md는 “…” 문자열을 표준출력에 기록하고(echo 명령어), 그 표준 출력을 README.md 라는 파일로 연결합니다. 파일이 존재하지 않을 경우 생성하기 떄문에, “…” 문자열을 내용으로하는 README.md 파일을 생성하는 명령입니다. md는 마크다운(MarkDown)으로 불리는 텍스트 포맷의 확장자 입니다.

최초의 버전(49738c0070c2aaf46eabecd86e4d055b7ce35888)을 생성했습니다. 이제 이 최초의 버전을 원격 저장소에 업로드하겠습니다.

로컬 저장소의 버전을 원격 저장소로 push

먼저 원격 저장소의 URL을 등록하고, 버전을 업로드합니다.

workshop-git$ git remote add origin git@github.com:dehypnosis/benzen-workshop-git.git
workshop-git$ git remote -v
origin  git@github.com:dehypnosis/benzen-workshop-git.git (fetch)
origin  git@github.com:dehypnosis/benzen-workshop-git.git (push)
workshop-git$ git status
On branch master
nothing to commit, working directory clean
workshop-git$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 238 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:dehypnosis/benzen-workshop-git.git
 * [new branch]      master -> master

git push origin master 명령으로 origin이라는 이름으로 등록된 원격 저장소에, master라는 브랜치(뒤에서 설명)로 현재 로컬 저장소의 내용을 업로드 했습니다.

원격 저장소를 로컬에 clone

자 이번에는 반대로, 다른 개발자 B의 입장에서 이미 존재하는 원격 저장소의 리소스를 다운로드해봅니다. 뿌리가(버전 히스토리가) 다른 원격 저장소에서 스냅샷을 다운로드하거나, 업로드 할 수 없습니다. 때문에 git clone 명령어를 통해서 원격 저장소의 리소스를 다운로드 함과 동시에 로컬 저장소를 생성합니다.

works$ git clone git@github.com:dehypnosis/benzen-workshop-git.git workshop-git-clone
Cloning into 'workshop-git-clone'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
Checking connectivity... done.
works$ cd workshop-git-clone/
workshop-git-clone$ ls
README.md
workshop-git-clone$ git log
commit 49738c0070c2aaf46eabecd86e4d055b7ce35888
Author: dehypnosis <dehypnoss@gmail.com>
Date:   Wed Jun 7 12:41:08 2017 +0900

    initial commit
workshop-git-clone$ git remote -v
origin  git@github.com:dehypnosis/benzen-workshop-git.git (fetch)
origin  git@github.com:dehypnosis/benzen-workshop-git.git (push)

새로운 버전을 원격 저장소에 업로드 push

git clone을 통해서 완전히 동일한 로컬 저장소가 로컬에 복제됐습니다. 새로운 파일을 생성하고, 기존 파일을 수정한 뒤 새로운 버전을 생성하고(add & commit), 원격 저장소에 업로드(push)해봅니다.

workshop-git-clone$ touch b1 b2 b3
workshop-git-clone$ echo "B updated README.md" >> README.md
workshop-git-clone$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

  modified:   README.md

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

  b1
  b2
  b3

no changes added to commit (use "git add" and/or "git commit -a")
workshop-git-clone$ git add .
workshop-git-clone$ git commit -m 'b updated'
[master fd3603f] b updated
 4 files changed, 1 insertion(+)
 create mode 100644 b1
 create mode 100644 b2
 create mode 100644 b3
workshop-git-clone$ git push origin master
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 329 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To git@github.com:dehypnosis/benzen-workshop-git.git
   49738c0..fd3603f  master -> master
workshop-git-clone$ git log
commit fd3603f8aa0ca72ae111b14f6fd89dbbb948e28a
Author: dehypnosis <dehypnoss@gmail.com>
Date:   Wed Jun 7 13:00:17 2017 +0900

    b updated

commit 49738c0070c2aaf46eabecd86e4d055b7ce35888
Author: dehypnosis <dehypnoss@gmail.com>
Date:   Wed Jun 7 12:41:08 2017 +0900

    initial commit

I/O Redirection: echo "B updated README.md" >> README.md는 “…” 문자열을 표준출력에 기록하고, 그 표준 출력을 README.md 라는 파일로 연결합니다. 파일이 존재하지 않을 경우 생성하고, 파일이 존재하면 파일의 뒷부분에 그 표준 입력을 추가합니다.

원격 저장소에서 다운로드 pull

이제 다시 개발자 A가 B가 업데이트한 원격저장소의 리소스를 다운로드합니다. git pull 명령어로 원격 저장소의 최신 버전을 다운로드 할 수 있습니다.

workshop-git-clone$ cd ../workshop-git
workshop-git$ ls
README.md
workshop-git$ git pull origin master
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 4 (delta 0), reused 4 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), done.
From github.com:dehypnosis/benzen-workshop-git
 * branch            master     -> FETCH_HEAD
   49738c0..fd3603f  master     -> origin/master
Updating 49738c0..fd3603f
Fast-forward
 README.md | 1 +
 b1        | 0
 b2        | 0
 b3        | 0
 4 files changed, 1 insertion(+)
 create mode 100644 b1
 create mode 100644 b2
 create mode 100644 b3
workshop-git$ git log
commit fd3603f8aa0ca72ae111b14f6fd89dbbb948e28a
Author: dehypnosis <dehypnoss@gmail.com>
Date:   Wed Jun 7 13:00:17 2017 +0900

    b updated

commit 49738c0070c2aaf46eabecd86e4d055b7ce35888
Author: dehypnosis <dehypnoss@gmail.com>
Date:   Wed Jun 7 12:41:08 2017 +0900

    initial commit
workshop-git$ ls
README.md b1        b2        b3

A가 README.md를 수정하고 새로운 버전을 업로드

마지막으로 동료끼리 동시에 같은 파일을 수정해서 충돌이 일어나는 경우에 대해서 알아보겠습니다. A가 먼저 README.md를 수정하고 원격저장소에 업로드 한 뒤, B가 뒤이어 README.md를 수정하고 원격저장소에 업로드 하는 시나리오입니다.

workshop-git$ ls
README.md b1        b2        b3
workshop-git$ echo "A updated readme.." >> README.md
workshop-git$ git add .
workshop-git$ git commit -m 'readme update'
[master efea8e1] readme update
 1 file changed, 1 insertion(+)
workshop-git$ git push origin master
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 334 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:dehypnosis/benzen-workshop-git.git
   fd3603f..efea8e1  master -> master

B가 README.md를 수정하고 새로운 버전을 업로드

workshop-git$ cd ../workshop-git-clone/
workshop-git-clone$ ls
README.md b1        b2        b3
workshop-git-clone$ echo "B updated readme.." >> README.md
workshop-git-clone$ git add .
workshop-git-clone$ git commit -m 'b update'
[master e1c6dae] b update
 1 file changed, 1 insertion(+)
workshop-git-clone$ git push origin master
To git@github.com:dehypnosis/benzen-workshop-git.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'git@github.com:dehypnosis/benzen-workshop-git.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

B가 새로운 버전을 생성하는 데(Commit) 성공했으나, 원격 저장소에 업로드 하려니 에러가 발생했습니다. 버전 히스토리가 맞지 않아 업로드 할 수 없으니, 먼저 원격 저장소의 내용을 다운로드하라고 합니다.

B가 로컬에 새로운 버전을 유지한채, 원격 저장소에서 다운로드

workshop-git-clone$ git pull origin master
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:dehypnosis/benzen-workshop-git
 * branch            master     -> FETCH_HEAD
   fd3603f..efea8e1  master     -> origin/master
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

다운로드에 성공했으나 Automatic merge failed라며 CONFLICT 에러를 보이고 있습니다. 버전 히스토리는 차곡 차곡 쌓일 수 밖에 없기 때문에, 결국 저장소는 순서대로 최초 버전/…/A가 업데이트한 버전/B가 취합(Merge)한 버전의 구성을 따를 수 밖에 없습니다. 취합된 버전을 생성하기 위해서 텍스트 편집기를 통해서 충돌이 일어난 README.md 파일을 수정합니다.

Git conflictGit conflict

Git conflict resolvedGit conflict resolved

Merged 버전 생성 후 업로드

workshop-git-clone$ cat README.md
# Workshop GitHub Practice
B updated README.md
B updated readme.. OKAY B FIRST!
A updated readme..
workshop-git-clone$ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 1 and 1 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

  both modified:   README.md

no changes added to commit (use "git add" and/or "git commit -a")
workshop-git-clone$ git add .
workshop-git-clone$ git commit -m 'merged readme'
[master cb309ea] merged readme
workshop-git-clone$ git push origin master
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 625 bytes | 0 bytes/s, done.
Total 6 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To git@github.com:dehypnosis/benzen-workshop-git.git
   efea8e1..cb309ea  master -> master

협업의 흐름

Git Remote WorkflowGit Remote Workflow

git remote, git push, git clone, git pull 등의 명령어를 이용한 협업의 흐름에 대해서 알아봤습니다. 이외에도 협업시 이슈별로 브랜치(branch)를 생성하고, 충돌을 최소화하며 독립적으로 작업을 진행한 후, merge를 통해서 결과를 합치거나, 또는 원격 저장소의 메인 브랜치(master)에 직접 push 할 권한이 없는 경우 원격 저장소의 관리자에게 pull-request를 보내서(GitHub의 기능) 브랜치간에 작업 내역을 합칠 수 있습니다.

Git은 단순히 사용 할 수 있지만, 한편으로 방대한 기능을 제공합니다. 브랜칭, 서브모듈 등 이외의 다양한 기능들은 실제 프로젝트를 진행하는 데 의미가 있기 때문에, 당장 Git을 처음 쓰는 입장에서 혼자서 공부하는 것은 사상누각이라고 생각합니다. 실제로 Git을 통해 프로젝트를 진행하면서 혹은 GitHub의 오픈소스에 기여하면서 Git이나 GitHub에 익숙해지고, Git의 새로운 기능이 궁금 할 때 쯤, Git에서 제공하는 온라인 교재를 통해서 궁금한 주제에 대해서 공부하면 충분하겠습니다.

.gitignore

DB 설정 파일이나, node_moudules 같은 의존 패키지들 등 저장소의 스냅샷에 포함하고 싶지 않은 파일이 있을 수 있습니다. 물론 add 할 때마다 걸러서 tracking 하지 않으면 되지만, 애초에 tracking 하지 않도록 설정파일을 작성 할 수 있습니다. 아래처럼 루트 디렉토리(혹은 하위 폴더)에 .gitignore 텍스트 파일을 작성합니다.

.gitignore 예시

/**/node_modules/
.DS_Store
assets/dist/
config.json

자세한 .gitignore 작성법

Git 원격 저장소 서버의 프로토콜

Git 저장소 서버는 로컬 파일 시스템이나 공유 파일 시스템(NFS, CIFS, NAS 등) 또는 HTTP나 SSH 프로토콜을 이용한 서버 프로세스로 운영 할 수 있습니다. 또한 Git 자체 프로토콜(git://)을 이용한 서버 프로세스를 운영 할 수도 있습니다.

Git 서버 프로토콜의 자세한 내용

오픈소스 라이센스

오픈소스(Open Source)란 소스코드가 공개되어 누구나 사용/활용 가능한 소프트웨어(또는 하드웨어)를 의미합니다. 프로젝트의 구성 요소 중, 오픈소스로 공개된 모듈이나 라이브러리를 이용하면 개발 비용을 줄이고 품질을 향상시킬 수 있습니다. 지금도 전세계의 개발자들에 의해 수 많은 오픈소스 프로젝트가 진행되고 있으며, 개인이나 기업에 의해서 영리/비영리적으로 활용되고 있습니다.

Open Source ProjectsOpen Source Projects

이때 오픈소스 역시 이용 방법 및 조건의 범위를 명시한 라이센스를 갖습니다. 아직 국내 및 외국에서 오픈소스 라이센스의 법적 구속력에는 한계가 있지만, 라이센스 위반시 도의적 책임을 피할 수는 없습니다. 몇가지 대표적인 라이센스는 아래와 같습니다.

라이센스요약소프트웨어
BSD License; Berkeley Software Distribution License라이센스 명시 필요FreeBSD OS, Nginx 웹 서버, OpenCV 시각처리 라이브러리 등
MIT License라이센스 명시 필요X11 유닉스 계열 GUI 프레임워크, jQuery/Angular.js/Backbone.js JS 라이브러리, BootStrap CSS 프레임워크 등
Apache License소스코드를 수정하여 재배포시 라이센스 명시 필요Android OS, Apache 웹 서버, Hadoop 분산처리 플랫폼, PhoneGap 하이브리드 앱 프레임워크, Tensorflow 머신러닝 라이브러리 등
GNU GPL; GNU General Public LicenseGPL 코드를 이용한 소프트웨어는 무조건 GPL 라이센스를 따라야함, 프로그램을 영리/비영리로 배포시 소스코드 공개 필요 Linux OS 커널, GCC 컴파일러, Git 버전 관리 시스템, Firefox 웹 브라우저 등
GNU LGPL; GNU Lesser General Public LicenseLGPL 코드를 동적(dynamic) 라이브러리로 링크한 프로그램은 소스코드를 공개 불필요, 이외의 경우는 GPL을 따름FFmpeg 영상/음성 처리 라이브러리, Open Office 사무 소프트웨어 등
Beerware License맥주 사주기?
목차
6. 개발과 배포
7. 다른 플랫폼으로
저자

김동욱

개발 경력 약 10년, 전문 분야는 웹 및 각종 응용 소프트웨어 플랫폼입니다. Codeflow를 운영하고 있습니다.

2018년 04월 10일 업데이트

지원되지 않는 웹 브라우저거나 예기치 않은 오류가 발생했습니다.