본문 바로가기
Development/Git

Git 설치하고 사용하기

by 드로니뚜벅이 2022. 4. 11.

Git 설치하기

현재 시스템에 깃(Git)이 설치되어 있는지 확인하려면 버전정보를 확인해 보시면 됩니다. 저는 이미 설치가 되어 있어서 아래처럼 버전정보가 표시 됩니다.

$ git --version
git version 2.25.1

 

Git 설치 (Ubuntu) : 기본 설치

$ sudo apt install git
$ git --version
git version 2.25.1
$

Git 설치 (Ubuntu) : 최신 버전으로 설치하고자 하실 경우

$ sudo add-apt-repository ppa:git-core/ppa -y
$ sudo apt update
$ sudo apt install git -y
$ git --version
git version v2.39.1
$

Git을 설치하고 나면 예쁘지는 않지만 gitk이라는 GUI 툴도 설치가 됩니다. 무료로 사용할 수 있는 훌륭한 GUI 툴이 많기 때문에 굳이 사용할 일이 없긴 하겠지만 별도로 설치하지 않고 간단히 확인하는 용도로 유용할 때가 있습니다.

 

Git 저장소 설정하기

Git을 설치하고 나면 관련 환경설정 정보가 "~/.gitconfig" 파일에 저장됩니다. 환경설정 내용을 터미널에서 확인하려면 다음 명령어를 실행해 봅니다.

$ git config --list # show all the settings in gitconfig

 

사용자 정보 설정

깃은 저장소에 내용을 누가 수정을 했는지 확인을 위해서 "git config"를 통해서 사용자의 이름과 이메일 주소를 반드시 설정해야 합니다. 그렇지 않으면 깃에 커밋된 내용에 대해서 누가, 언제, 어떤 내용을 수정(추가,삭제,변경) 했는지 추적하기가 힘들어집니다.

편집기와 비교툴은 설정하지 않아도 기본 값으로 설정됩니다.

$ git config --global user.name "your name" # set user.name
$ git config --global user.email "your-email-account" # set user.email
$ git config user.name # check user.name
$ git config user.email # check user.email

편집기 및 병합 툴 설정 (옵션)

Git은 시스템 편집기를 기본으로 사용하고 있으며 대부분 Vi 에디터입니다. 해당 항목은 설정하지 않으셔도 기본 값으로 설정되오니 변경이 필요하신 경우만 설정하셔도 됩니다.

$ git config --global core.editor vim
$ git config --global merge.tool vimdiff

편집기를 Visual Studio Code를 사용하시려면 아래와 같이 설정합니다.

$ git config --global core.editor "code --wait"

 

Git Aliases

$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status

 

커밋 내용 템플릿 설정 (옵션)

"git commit" 명령어를 수행할 때 자동으로 설정한 템플릿을 사용하기 위해 미리 설정하도록 하겠습니다.

(기본값을 사용하고자 하신다면 스킵하셔도 됩니다.)

$ cd ~
$ vim git-commit-template.txt
## 원하는 템플릿 구성
[Subject]

[Description]

[Issue]

위에 작성한 템플릿으로 설정합니다.

$ git config --global commit.template ~/git-commit-template.txt

Git 명령어를 alias로 정의해서 사용할 수 있는데 생략하겠습니다. 개인적으로 명령어를 그대로 사용하는 것을 선호하는 편입니다.

커밋 해시코드 줄여서 보기 (옵션)

간혹 커밋 커밋 ID를 확인해야 되는 경우가 있는데 줄여서 보면 유용한 경우가 있습니다.  설정하지 않으셔도 됩니다.

Git에서 커밋 ID는 40자리 길이의 SHA-1 해시로, 가장 짧은 4자리 버전(기본적으로 7자리)까지 축약할 수 있습니다.

$ git config --global log.abbrevcommit yes
$ git config --global core.abbrev 8

$ git log --pretty=oneline
ed054a38 add project based .gitignore
30a3fa4c add ez version
0a6e9015 add logic for shifting days
af4ab954 add n days ago
...

 

기타 설정 (옵션)

$ git config --global core.autocrlf input # for linux, mac
$ git config --global core.autocrlf true # for windows
$ git config --global color.ui auto     // 출력 메시지 색상 지정
$ git config --global init.defaultBranch main //  기본 브랜치명 설정
$ git config --get init.defaultBranch
main
$

 

설정된 내용 확인하기

$ git config --list

 

저장소 생성하기

위에서 설명한 내용으로 설치와 설정을 마치셨으면 이제 작업할 저장소를 생성할 수 있습니다.

저장소 만드는 방법으로는 처음부터 작업폴더를 생성해서 저장소로 등록하는 방법과 다른 곳에 있는 저장소를 가져와서 작업폴더를 구성하는 방법이 있습니다.

현재 작업폴더를 저장소로 만드는 방법

저장소로 생성할 작업 폴더를 생성하고 아래처럼 "git init"를 사용하면 현재 폴더(zoo/)를 Git 저장소로 생성하게 됩니다. 작업 폴더에 ".git" 폴더가 생성된 것을 확인하실 수 있습니다. 작업 폴더(zoo)를 미리 생성하지 않고 "git init <작업디렉토리>" 와 같이 명령어를 실행할 수도 있습니다.

$ pwd
/home/dooly/repos/zoo
$ git init --initial-branch=main // default branch name: master
$ ls -al
.
..
.git

이 명령어 실행 후에는 마스터(master) 브랜치가 자동으로 생성되며 이 곳에서 작업이 진행됩니다.

로컬 저장소의 작업 내용을 원격 저장소에 Push해서 사용하려면 원격 저장소를 등록하는게 필요합니다.

원격저장소는 https와 ssh가 있습니다.

git remote add origin [추가할 원격 git 저장소 주소]
git remote add origin https://github.com/<본인 계정>/our-project.git
git remote add origin git@github.com:<본인 계정>/our-project.git
$ git remote add origin https://github.com/s-yes/zoo.git
$ git remote -v
origin
$

 

 

.gitignore 파일 생성

README.md 파일 생성

 

이미 생성된 저장소를 작업폴더로 가져오기

저장소는 현재 작업하는 노트북이나 PC와 같은 로컬 저장소일 수도 있고 네트워크를 통해 접속해야 하는 원격 저장소일 수도 있습니다.

로컬 저장소일 경우

git clone <local_repos_path>
$ pwd
/home/dooly/repos/monkey
$ git clone /home/dooly/repos/zoo

원격 저장소일 경우

git clone <remote_repos_path>

 

원격저장소에서 로컬저장소로 가져오기

git remote

$ git remote 원격 저장소의 이름 목록을 표시
$ git remote -v 원격 저장소에 대한 자세한 목록 표시
$ git remote show <리모트 저장소 이름>
원격 저장소 살펴보기
$ git remote add [name] [url] 원격 저장소를 추가
$ git remote rm [name] 원격 저장소를 제거

 

git clone

$ git clone [url]

기존 원격 저장소를 로컬에 다운로드하기 위해 사용하는 명령어입니다.

 

git pull

$ git pull

원격 브랜치의 변경 사항을 캡처하기 위해 사용하는 명령어입니다.

 

git fetch

 

git branch

Git 브랜치는 우 가볍습니. 간에 브랜치를 새로 만들고 브랜치 사이를 이동할 수 있습니다. 다른 버전 관리 시스과는 달 Git 브랜치를 만들어 작하고 나중에 Merge 하는 방법 장합니. 심지어 하루에 수번씩해도 괜찮습니. Git 브랜치에 능숙해지면 개발 방식 전히 바고 다른 도를 사용할 수 없게 됩니다.

Git 브랜치는 커 사이를 가게 이동할 수 있는 어 포인터 은 것입니다. 적으로 Git "git init" 명령어를 실행할 때 별도의 다른 브랜치명을 부여하지 않으면 master 브랜치를 만듭니다.
처음 커하면 이 master 브랜치가 생성된 커을 가리키고 이후 커을 만들면 master 브랜치는 자동으로 가
마지 을 가리킵니.

브랜치 명령어와 관련된 옵션은 아래와 같습니다.

git branch                  // 브랜치 목록 보기, * 표시가 현재 브랜치임
git branch -v               // 커밋 메시지도 함께 표시
git branch --merged         // 병합된 브랜치만 표시 (<-> --no-merged)
git branch <Branch Name>    // 브랜치명으로 브랜치 생성
git branch -b <Branch Name> // 브랜치 만들고 바로 체크아웃(checkout)
git branch -d <Branch Name> // 브랜치명에 해당하는 브랜치 삭제
git branch -D <Branch Name> // 강제로 브랜치 삭제
git branch -m <A> <B>       // 브랜치명을 A에서 B로 변경

브랜치를 삭제할(-d) 경우에는 삭제할 브랜치가 현재 브랜치이거나 병합(merge)이 되지 않은 커밋이 있는 경우에는 삭제되지 않고 에러메시지가 출력됩니다.

 

git checkout

작업 공간을 내가 원하는 특정 위치(커밋, 브랜치)로 이동시키고자 하는 경우 사용하는 명령어입니다. 즉, checkout 명령어는 HEAD가 특정 커밋이나 브랜치를 가리키게 됩니다. 단, 태그명으로 체크아웃은 할 수 없습니다.

git checkout <브랜치명>    // 특정 브랜치로 워킹 디렉토리 변경
git checkout <커밋ID>     // 특정 커밋으로 워킹 디렉토리 변경
git checkout -- <파일경로> // 특정 파일을 해당 브랜치 또는 커밋 상태로 변경

 

git merge

브랜치를 병합하는 명령어입니다. 이 명령어에 병합할 커밋 이름을 넣어 실행하면, 지정한 커밋 내용이 'HEAD'가 가리키고 있는 브랜치에 넣어집니다. 'HEAD'는 현재 사용중인 브랜치에 위치하게 됩니다.

$ git merge <브랜치명>

예를 들어, master 브랜치에 work1 브랜치를 병합하려면 아래와 같이 실행합니다.

$ git checkout master
$ git merge work1

병합을 시도할 경우, 브랜치 간의 충돌이 발생할 수 있습니다. 출력 메시지를 확인해서 해당 내용을 수정해서 커밋한 후 계속 진행하시면 됩니다.

 

로컬저장소에서 원격저장소로 올리기

(1) git add

$ git add <file>    # <file>에 기술한 파일(들)을 추가
$ git add .         # 현재 작업 폴더에서 수정된 모든 파일을 추가
$ git add -i        # 대화형으로 진행

파일이나 디렉토리를 인덱스에 추가하는 데 사용하는 명령어입니다. git add 명령어를 실행하면 실제 저장소에 저장하지는 않지만 Git 은 해당 파일을 추적할 수 있는 상태가 됩니다. (Untracked -> Staged)

추가 시 파일이나 디렉토리를 직접 입력하거나 "*.py"처럼 와일드 카드로 여러 대상을 지정할 수도 있습니다.

 

(2) git commit

Staging Area에 추가된 파일이나 디렉토리 내용을 저장소에 쓰기 위해 사용되는 명령어입니다.

$ git commit                   // (1) 메시지를 입력할 수 있는 편집창이 뜹니다
$ git commit -m "Add message"  // (2) Staging Area -> (Local)Repos.
$ git commit -am "Add Message" // (3) Working Directory -> (Local)Repos.
$ git commit --amend           // (4) 이전 커밋 메시지 수정

첫번째(1) 명령어는 메시지(-m) 옵션이 없기 때문에 메시지를 입력할 수 있는 편집기가 뜹니다. 보통 별도로 입력하지 않은 경우 Vim 에디터가 표시됩니다. 해당 내용은 위에서 설명한 "편집기 설정" 항목을 참고해 주세요.

두번째(2) 명령어는 "git add" 명령어로 Staging Area에 저장된 내용을 저장소에 커밋합니다. 편집기를 사용하지 않고 바로 메시지를 입력할 수 있어 쉽게 사용할 수 있는 방법입니다.

세번째(3) 명령어는 또한 "-a" 옵션을 지정하여 작업 디렉토리에 변경된 파일를 검색하고 인덱스에 추가하는 작업도 동시에 실시합니다. ("-am"은 "-a -m"처럼 사용해도 동일하게 적용됩니다)

네번째(4) 명령어는 바로 이전 커밋에 대해서 Index(Staging Area)의 변화가 없는 경우에는 커밋 메세지만 수정하고, Index가 변화한 경우는 내용을 반영되서 커밋됩니다.

 

(3) git push

로컬저장소에 있는 파일을 원격저장소에 저장하는 명령어입니다.

$ git push -u origin master   # -u <원격저장소명> <로컬저장소명>
$ git push --tags

"-u" 옵션을 사용하면 로컬저장소와 원격저장소가 연결상태로 되어 이후에는 "git push" 명령만으로도 동일한 기능을 수행할 수 있습니다.

"--tags"옵션은 로컬저장소의 모든 태그를 원격저장소에 저장합니다.

 

저장소 정보 확인하기

git status

$ git status
$ git status -s // -s : --short

저장소의 상태를 확인하기 위해 사용하는 명령어입니다.

현재 브랜치의 이름과 추가 변경된 파일 및 디렉토리 목록을 표시합니다.

 

git log

저송소에 있는 커밋(Commit) 이력을 조회할 경우 사용하는 명령어입니다.

Options: git [option]

Option Description
-p 각 커밋에 적용된 패치 출력
--stat 각 커밋에서 수정된 파일의 통계정보 출력
--shortstat --stat 명령의 결과 중에서 변경된(수정,추가,삭제) 라인만 출력
--name-only 커밋 정보 중에서 수정된 파일 목록 출력
--name-status 수정된 파일 목록뿐만 아니라 파일 변경 내용 출력
--abbrev-commit 40자 짜리 SHA-1 체크섬이 아닌 처음 몇 자리만 출력
--relative-date 정확한 시간이 아닌 "2 weeks ago" 와 같은 상대적인 형식으로 출력
--graph 브랜치와 병합 히스토리 정보를 포함하여 아스키 그래프로 출력
--pretty 지정한 형식(oneline, short, full, fuller, format)으로 출력
--since
기간, 저자, 커미터, 특정 텍스트 포함여부 등을 사용해서 조회 범위 조정
$ git log                  // 모든 커밋 로그 표시
$ git log test.txt       // 특정 파일의 변경 커밋 조회
$ git log -n 5             // 최근 5개 커밋로그 표시
$ git log --pretty=oneline // 각 커밋을 한 줄로 표시
$ git log --pretty=oneline --abbrev-commit // 커밋 줄임 해시코드로 표시
$ git log --pretty=format:"%h - %an, %ar : %s"
$ git log --pretty=format:"%h %s" --graph
$ git log --oneline        // 위 명령어와 동일하게 표시
$ git log --oneline --decorate // 위 명령어를 예쁘게 (그런데 같아 보임)
$ git log -p               // 마지막 커밋의 변경사항(버전간의 차이점)까지 표시
$ git log -p -1            // 마지막 커밋의 변경사항까지 표시(-n: n개 까지)
$ git log --stat           // 변경이력 통계 정보
$ git log --since=2.weeks

git log --pretty=format 형식

Option Description
%H 커밋 해시
%h 짧은 길이 커밋 해시
%T 트리 해시
%t 짧은 트리 해시
%P 부모 해시
%p 짧은 길이 부모 해시
%an 저자 이름
%ae 저자 메일
%ad 저자 시각
%ar 저자 상대적 시각
%cn 커미터 이름
%ce 커미터 메일
%cd 커미터 시각
%cr 커미터 상대적 시각
%s 요약

git log --since 조회 관련 옵션

Option Description
-(n) 최근 n개의 커밋만 조회
--since, --after 명시한 날짜 이후 커밋만 조회
--until, --before 명시한 날짜 이전의 커밋만 조회
--author 입력한 저자의 커밋만 조회
--committer 입력한 커미터의 커밋만 조회
--grep 커밋 메시지 안의 텍스트 조회
-S 커밋 변경 내용 안의 텍스트 조회

옵션이 너무 길어 타이핑하기 힘드시면 위에서 설명드린 설정(config) 명령어의 alias를 사용하면 손이 편해집니다.

$ vi ~/.gitconfig
[alias]
	g = log --graph --all --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(bold white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --abbrev-commit --date=relative

 

git show

 

git diff

파일이 변경된(어떤 라인을 삭제하고 추가/수정했는지) 내용을 확인하기 위한 명령어입니다. 비교 대상은

1) 작업 파일과 스테이지 파일 비교

    $ git diff

    $ git diff <파일명>

2) 작업 파일과 저장소(로컬) 파일 비교

    $ git diff HEAD

    $ git diff HEAD <파일명>

3) 스테이지 파일과 저장소(로컬) 파일 비교

    $ git diff --cached // --staged 와 동일한 옵션

    $ git diff --cached <파일명>

4) 로컬 저장소와 원격 저장소 파일 비교: git diff <local-branch> origin/<remote-branch>

    $ git diff master origin/master

 

git grep

 

git rm

Untracked 파일 삭제

Git에서 파일을 제거하려면 "git rm" 명령오로 Tracked 상태의 파일을 삭제한 후에(정확하게는 Staging Area에서 삭제하는 것) 커밋해야 합니다. 이 명령어는 작업 공간에 있는 파일도 삭제하기 때문에 실제로 파일도 지워집니다.

Git 명령을 사용하지 않고 단순히 워킹 디렉터리에서 파일을 삭제하고 git status 명령으로 상태를 확인하면 Git은 현재 “Changes not staged for commit” (즉, Unstaged 상태)라고 표시해 줍니다. 하지만, Untracked 상태의 파일을 "rm" 명령어로 삭제할 경우에는 Git에는 아무런 영향이 없습니다.

$ rm PROJECTS.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
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:    PROJECTS.md

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

작업디렉토리와 Git 저장소 파일 삭제

그리고 git rm 명령을 실행하면 삭제한 파일은 Staged 상태가 된다. 커밋하면 파일은 삭제되고 Git은 이 파일을 더는 추적하지 않는다.

$ git rm PROJECTS.md
rm 'PROJECTS.md'
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    PROJECTS.md
$ git commit -m "deleted PROJECTS.md"

Staging Area에서만 제거하고 작업 공간에 있는 파일은 지우지 않고 남겨둘 수 있습니다. 다시 말해서 하드디스크에 있는 파일은 그대로 두고 Git만 추적하지 않게 합니다. "--cached" 옵션을 사용하여 명령을 실행합니다.

작업 디렉토리에서는 삭제하지 않고 Git 에서는 삭제

$ git rm --cached README
$ git commit -m "깃에는 삭제되지만 로컬에서는 삭제되지 않음"

디렉토리를 삭제할 경우에는 "-r" 옵션을 사용합니다. (e.g: git rm -r DIR1)

 

git mv

저장소의 파일 이름을 바꾸는 명령어입니다. 내부적으로는 변경전의 파일을 삭제하고 변경후의 파일을 다시 커밋한다고 보면 될 것 같습니다. 물론 바로 커밋하지는 않고 스테이징 영역에 올라갑니다.

$ git mv Afile Bfile       // Afile을 Bfile로 파일명을 변경합니다.
...
$ mv Afile Bfile           // 위 명령어는 세단계로 동작하게 됩니다.
$ git rm Afile
$ git add Bfile

 

git reset

버전을 삭제하는 명령어입니다.

$ git reset --soft <커밋ID>  // 저장소만 이전 버전으로 되돌아감
$ git reset --hard <커밋ID>  // 작업 디렉토리까지 이전 버전으로 되돌아감

 

git revert

버전을 삭제하지 않으면서 되돌리는 명령어입니다. 즉, 버전의 커밋을 취소한 내용을 새로운 버전으로 만드는 명령어입니다.

$ git revert <새로운버전>

 

태그 (tag)

개발 프로젝트에서는 대부분 배포를 할 때 태그를 사용합니다. 전문 용어로 형상관리를 위한 베이스라인으로 정의하기도 합니다.

태그는 특정 커밋에 대한 링크 즉 상수 포인터입니다.

복잡한 40자리 커밋 ID(해시코드)  대신에 태그를 붙여 놓으면  간결하고 식별하기 쉬울뿐만 아니라 관리하기도 쉬워집니다. 즉, 하루에도 수많은 커밋이 발생하는데 그 중에서 마일스톤이나 배포와 중요한 시점에서 태그를 달아두면 아주 유용하게 찾을 수 있습니다.

태그가 특정 커밋 ID를 한번 지정하게 되면 다른 커밋 ID로 변경할 수 없습니다. 꼭 바꾸고 싶다면 태그를 삭제하고 다시 생성해야 합니다.

 

태그 조회하기 : git tag

"git tag" 명령어를 실행하면 로컬 저장소의 모든 태그를 확인할 수 있습니다.

$ git tag
v0.1
v0.9
v1.0-rc1

검색 패턴을 사용하여 태그를 확인할 수도 있습니다.

$ git tag -l "v2.2*"
v2.2
v2.2-rc1
v2.2-rc2
v2.2-rc3

 

"git tag <태그명>" 명령어는 현재 커밋을 가리키는 태그를 생성합니다. 이러한 태그를 생성하는 방법으로는 Annotated tag와 Lightweight tag가 있습니다.

 

Lightweight Tag

파일에 커밋 체크섬만을 저장할 뿐 다른 정보는 저장하지 않습니다.

마지막 커밋한 내용에 저장되며 버전 정보만을 추가할 뿐 다른 옵션을 사용할 수 없습니다.

특정 커밋을 가리키는 포인터와 같으며 단순히 버전 정보와 같은 태그만을 남길 수 있습니다.

$ git tag v1.0-final

이전 히스토리를 검색해서 이전 커밋에 대해 태그를 붙일 수도 있습니다.

$ git log --pretty=oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
4682c3261057305bdd616e23b64b0857d832627b added a todo file
166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme

$ git tag v1.2 9fceb0

 

Annotated Tag

Annotated 태그는 "-a" 옵션을 사용하여 태그를 만든 사람, 이메일, 날짜, 메시지를 저장합니다.

git tag -a {tag-name} -m {tag-message} {commit-hash}
$ git tag -a v3.0-b1 -m "v3.0 beta version"

"-m" 옵션은 메시지를 저장할 때 사용합니다. 이 옵션을 사용하지 않으면 "편집기 설정"에서 지정한 에디터가 자동으로 실행됩니다.

참고로, 태그 메시지는 커밋 메시지와 따로 저장됩니다.

 

태그를 확인하려면 "git show" 명령어로 확인할 수 있습니다.

$ git show v3.0-b1

 

원격 저장소에 태그 올리기

$ git push <원격저장소명> <태그명>

"git push" 명령어는 원격 저장소에 태그를 올리지 않기 때문에 별도로 처리해야 합니다.

로컬 저장소의 모든 태그를 올리려면 "--tags" 옵션을 사용하면 됩니다.

$ git push origin v3.0-b1
$ git push origin --tags

 

태그명으로 체크아웃하기

태그는 브랜치(branch)와 달리 커밋을 바꿀 수 없기 때문에 체크아웃해서 사용할 수 없습니다. 태그가 가리키는 특정 커밋을 만들어 작업을 하기 위해서는 새로운 브랜치를 생성해야 합니다.

git checkout -b <New Branch> <Tag Name>

 

태그 삭제하기

"-d" 옵션을 사용하여 필요없거나 잘못 만든 태그를 삭제할 수 있습니다.

// 로컬 저장소 태그 삭제
$ git tag -d v3.0-b1

// 원격 저장소 태그 삭제
$ git push origin :v3.0-b1

 

서브모듈

프로젝트를 수행하다 보면 다른 프로젝트를 함께 사용해야 하는 경우가 종종 있다. 함께 사용할 다른 프로젝트는 외부에서 개발한 라이브러리라던가 내부 여러 프로젝트에서 공통으로 사용할 라이브러리일 수 있다. 이런 상황에서 자주 생기는 이슈는 두 프로젝트를 서로 별개로 다루면서도 그 중 하나를 다른 하나 안에서 사용할 수 있어야 한다는 것이다.

Git 저장소 안에 다른 Git 저장소를 디렉토리로 분리해 넣는 것이 서브모듈이다. 다른 독립된 Git 저장소를 Clone 해서 내 Git 저장소 안에 포함할 수 있으며 각 저장소의 커밋은 독립적으로 관리한다.

서브모듈을 추가하는 명령으로 git submodule add 뒤에 추가할 저장소의 URL을 붙여준다. 이 URL은 절대경로도 되고 상대경로도 된다.

 

Bundle

데이터를 한 파일에 몰아넣는 것이다. 이 방법은 다양한 경우 유용하게 사용할 수 있다. 예를 들어 네트워크가 불통인데 변경사항을 동료에게 보낼 때, 출장을 나갔는데 보안상의 이유로 로컬 네트워크에 접속하지 못할 때, 통신 인터페이스 장비가 고장났을 때, 갑자기 공용 서버에 접근하지 못할 때, 누군가에게 수정사항을 이메일로 보내야 하는데 40개 씩이나 되는 커밋을 format-patch 로 보내고 싶지 않을 때를 예로 들 수 있다.

바로 이럴 때 git bundle 이 한 줄기 빛이 되어준다. bundle 명령은 보통 git push 명령으로 올려 보낼 모든 것을 감싸서 한 바이너리 파일로 만든다. 이 파일을 이메일로 보내거나 USB로 다른 사람에게 보내서 다른 저장소에 풀어서(Unbundle) 사용한다.

 

Replace

히스토리(혹은 데이터베이스)에 일단 저장한 Git의 개체는 기본적으로 변경할 수 없다. 하지만 변경된 것처럼 보이게 하는 재밌는 기능이 숨어 있다.

Git의 replace 명령은 "어떤 개체를 읽을 때 항상 다른 개체로 보이게" 한다. 히스토리에서 어떤 커밋이 다른 커밋처럼 보이도록 할 때 이 명령이 유용하다(`git filter-branch`를 사용하여 전체 히스토리를 다시 작성할 필요가 없는 것이다).

예를 들어 현재 프로젝트의 히스토리가 아주 방대한 상태다. 히스토리를 둘로 나누어서 새로 시작하는 개발자에게는 히스토리를 아주 간단한 몇 개의 커밋으로 만들어서 제공하고, 프로젝트 히스토리를 분석할 사람에게는 전체 히스토리를 제공하는 상황을 생각해보자. replace 명령으로 간단해진 히스토리를 전체 히스토리의 마지막 부분에 연결해서 사용할 수 있다. 이렇게 히스토리를 변경하는 데도 커밋을 새로 쓰지 않는 매우 훌륭한 기능이다(Rebase를 생각해보자. 한 부모를 변경하면 이후의 커밋은 모두 재작성된다).

 

Credential 저장소

SSH 프로토콜을 사용하여 리모트 저장소에 접근할 때 Passphase 없이 생성한 SSH Key를 사용하면 사용자이름과 암호를 입력하지 않고도 안전하게 데이터를 주고받을 수 있다. 반면 HTTP 프로토콜을 사용하는 경우는 매번 사용자이름과 암호를 입력해야 한다.

다행히도 Git은 이렇게 매번 인증정보(Credential)를 입력하는 경우 인증정보를 저장해두고 자동으로 입력해주는 시스템을 제공한다. Git Credential 기능이 제공하는 옵션은 아래와 같다.

  • 일단 기본적으로 아무런 설정도 하지 않으면 어떤 암호도 저장하지 않는다. 이 경우 인증이 필요한 때 매번 사용자이름과 암호를 입력해야 한다.
  • “cache” 모드로 설정하면 일정 시간 동안 메모리에 사용자이름과 암호 같은 인증정보를 기억한다. 이 정보를 Disk에 저장하지는 않으며 메모리에서도 15분 까지만 유지한다.
  • “store” 모드로 설정하면 인증정보를 Disk의 텍스트 파일로 저장하며 계속 유지한다. 계속 유지한다는 말은 리모트의 인증정보를 변경하지 않는 한 다시 인증정보를 입력하지 않아도 접근할 수 있다는 말이다. “store” 모드를 사용할 때 주의할 점은 인증정보가 사용자 홈 디렉토리 아래에 일반 텍스트 파일로 저장된다는 점이다.

 

참고 사이트