Git과 Github는 혼동하기 쉽다.
Git은 내 로컬저장소(내 컴퓨터)의 소스코드를 형상관리하기위한 툴.
Github는 원격환경에 소스코드를 저장할 수 있는 원격저장소를 제공하는 서비스(구글 저장소처럼).
Git을 사용하는 첫번째 목적은 '버전관리'이다.
웹상에서 프로그램을 다운받으면 숫자로 된 버전이 명시되어있음. 버전별로 소스의 어느 부분이 변경되었는지, 신규기능은 어느파일에 구성이 되어있는지 파악하기 위해서는 모든 히스토리가 고스란히 남아있어야 한다. git은 commit이라는 액션 단위로 변동사항에 대한 스냅샷을 가지고 있기 때문에 히스토리 관리에 용이함.
두번째 목적은 '작업 단위의 세분화'이다.
특정 기능을 완성하고 그 반영사항을 commit하게 되면 반영 전후로 서비스 동작에 어떤 영향을 미쳤는지를 확인할 수 있다. 에러가 발생했을 경우 그것을 원상복구 시키는 것도 쉽다.
세번째 목적은 '협업에의 유용성'이다.
git은 branch라는 개념을 도입해서 서로 다른 개발자가 분할된 branch에서 작업을 수행하다가 이를 합쳤을 때 충돌하는 지점을 탐지해준다.
github와 같은 원격 저장소는 로컬git 저장소의 소스를 웹상에서 활용할 수 있도록 저장하는 역할을 함. 같은 역할을 하는 서비스에는 gitlab, bitbucket 등이 있다.
즉, github은 git으로 된 프로젝트 저장 공간을 제공하고, git을 편하게 사용하기 위한 여러가지 부가기능을 제공하는 서비스이다.
sourcetree는 git을 쉽게 사용할 수 있게 하는 도구. 워드 파일을 편집할 때 MS office를 사용하는 것처럼.
commit은 파일을 저장하는 것과 유사. 프로그램의 변경 사항을 반영하는 것. 그러나 일반적인 저장과의 차이점이라고 한다면 저장 때마다 변동 이전의 상태가 모두 유실되지 않고 유지된다는 것. commit을 하면 누가, 언제, 어느 파일의, 어느 부분을 변경했는지 히스토리가 저장소에 반영이 되고, 이때 어떻게 이 작업을 하게 되었는지에 대한 commit 메시지를 작성하도록 되어 있다.
git으로 관리되는 프로젝트를 git에서는 repo(repository 리포지토리)라고 부른다.
내 컴퓨터에 저장되어 있는 리포지토리를 로컬 repo라고 하고, github처럼 다른 곳에서 접속할 수 있는 공간에 저장되어 있는 것을 원격 repo라고 한다.
구글 드라이브 같은 클라우드 서비스로 예를 든다면, 클라우드에 있는 폴더를 내 컴퓨터에 있는 폴더와 연결해서 동기화해두면 내 컴퓨터 폴더의 내용이 자동으로 클라우드 폴더와 똑같아진다.
git도 클라우드 서비스로 두군데의 내용을 동기화한 것처럼 원격 repo와 로컬 repo를 연결시켜서 내용을 반영시킬 수 있다. 로컬 repo가 원격 repo를 연결하는 것을 추적(tracking/branch tracking)이라고 한다.
단, 클라우드 서비스와 다르게 작업내역 즉, commit을 자동으로 반영하지 않는다. 내가 원하는대로 어디 commit까지만 반영할지를 수동으로 설정할 수 있게 한다.
로컬 repo의 commit들을 원격 repo에 반영하는 것을 'push'라고 한다. 원격 repo의 commit들을 로컬 repo에 반영하는 것을 pull이라고 한다. 원격 repo를 내 컴퓨터에서도 사용할 수 있도록 가져올 수도 있는데 일종의 초기 다운로드라고 생각하면 된다. 이를 clone이라고 한다.
git은 이름과 이메일을 등록한 후에 정상적으로 사용이 가능하다. 다음 명령어를 실행한다.
git config --global user.name "KYEONGMIN CHO"
git config --global user.email"ggingmin@likelion.net"
내가 작업하고 있는 프로젝트 디렉토리를 git이 관리하는 영역으로 만들어주기 위해서는 초기화를 해주어야 한다.
git init
.gitignore 파일은 말 그대로 git으로 하여금 특정 파일을 무시하여 commit 대상에서 제외시키는 역할을 한다. 보통 저장소의 최상위 디렉토리에 위치하고 있다.
.gitignore에서 관리하는 파일은 보통 OS상에서 자동으로 생성하는 파일이나, 보안상 공개되어서는 안되는 파일, 공동 작업에 있어서 불필요한 것들로 이루어져 있다.
git status
git init을 실행한 영역에서 상기의 명령어를 실행하면 아무 파일도 존재하지 않기 때문에 "커밋할 사항이 없음"이라는 메시지가 출력된다.
동일한 디렉토리 내에 특정 파일을 만들고 다시 명령을 실행하면 새로운 파일이 "추적하지 않는 파일"이라는 메시지가 뜬다. 추적하지 않는다는 것은 staging area에 아직 소스코드가 올라가지 않았다는 의미이다.
작성한 소스를 추적하기 위해서는 하기의 명령어를 실행해야 한다.
git add <file name>
// 특정 파일을 추적하고 싶을 때
git add -A
// 프로젝트 전체를 추적하고 싶을 때
추적하고 있는(staging되어 있는) 파일 중 commit 대상에서 제외가 필요한 것은 다음의 명령어로 해제가 가능하다. 추적이 해제가 되면 git add 명령어를 실행하기 이전으로 되돌아 간다.
git rm --cached <file name>
추적했던 파일을 로컬 저장소에 반영하기 위한 명령어는 다음과 같다.
git commit -m "<message>"
// <message>에 반드시 commit 메시지를 적어주어야 한다.
// -m 옵션을 사용하면 commit 명령과 동시에 메시지를 입력할 수 있다.
git -a -m "<message>"
// -a 옵션을 추가하면 이미 추적 중인 파일에서 변동 사항이 있을 때 굳이 다시 add를 거치지 않고 commit을 할 수 있다.
// 즉, add를 생략하게 해주는 옵션이다.
// 주의할 점은 이미 staging area에 올라간 파일에 대해서 생략이 가능한 것이지, 한번도 add가 되지 않았던 파일에 대해서는 해당사항이 없다.
작성한 소스를 누가, 언제 commit 했는지 확인이 필요한 경우 로그를 조회할 수 있다. 로그 창에서 나오기 위해서는 ":"을 누르고 "q"를 누르면 된다.
git log
최종 commit 버전의 소스와 작업이 이루어지고 있는 순간의 소스를 비교해야 할 때가 있다. 만약 commit 이후 소스가 변경되었다면 다음과 같은 내역을 확인할 수 있다. 변동사항이 확인되면 새로 commit을 하거나 commit된 버전에 맞게 소스를 수정해야 한다.
git diff
A, B, C라는 세가지 기능을 구현한다고 가정해보자. 만약 main 브랜치에서 모든 진행을 하게 된다면 협업은 물론이거니와 1인 작업이어도 효율적으로 작업을 하기가 어려워진다. 소스 commit도 어지럽게 엉키고 버그가 발생해도 찾기가 굉장히 어렵게 된다.
그러므로 A라는 기능을 위한 브랜치, B라는 기능을 위한 브랜치 등을 따로 설정한다. 이들 브랜치에서는 병렬적으로 작업이 가능하며, 나중에 소스 작성이 완료된 이후 main브랜치로 병합하게 된다.
1) "dev1"라는 브랜치를 새로 생성함과 동시에 그긋으로 브랜치를 이동하는 명령은 다음과 같다.
git checkout -b dev1
브랜치 별로 작업이 완료되면 소스를 하나로 병합해주어야 한다. main 브랜치로 돌아간 상태에서 dev1의 작업내용을 합치기 위해 다음의 명령어를 실행한다. dev1에서 작성했던 소스가 나오면 정상이다.
git merge dev1
위의 과정이 로컬 저장소에서 소스를 다루는 내용이었다면 이제 이렇게 작업이 완료된 소스를 github의 원격 저장소에 올리는 과정을 다뤄본다. 먼저 github 저장소 주소를 등록해야 한다.
사전에 github 저장소를 새로 만들어주고 명령을 실행해준다.
git remote add origin https://github.com/ggingmin/test.git
// git remote add [원격 저장소명] [원격 저장소 주소]
git push -u origin main
// git push -u [원격 저장소명] [브랜치명]
// -u 옵션을 사용하면 추후 동일한 원격 저장소와 브랜치에 push할 때 git push만 실행할 수 있다.
로컬에 원격 저장소 프로젝트를 가져오는 방법은 두가지가 있다. 많은 사람들은 둘은 혼동한다.
git fetch
원격 저장소의 내용을 로컬 저장소로 받아오기는 한다. 하지만 로컬 저장소는 내 컴퓨터에 저장이 되어 있을 뿐이지 우리가 실제로 작업하고 있는 working directory가 아니다 즉, fetch만으로는 직접 작업을 하거나 수정을 할 수가 없다.
git pull
원격 저장소의 소스를 받아올 뿐만 아니라 working directory 병합까지 수행한다. 순서대로 정리하면 원격 저장소에서 받은 내용이 로컬 저장소에, 로컬 저장소의 내용이 다시 working directory까지 도달하는 것이다.