git

Installation

1
sudo apt-get install git-all

Terminology

Branch 란 commit 의 나열을 의미한다. 서로 다른 branch 란 서로 다른 작업 내역의 합이고 이러한 작업내역을 서로 합치고 변경하면서 여러 형태의 code base 가 존재할 수 있다.

Commit 이란 code base 의 변화내역을 의미한다. 즉, git 에서 현재 code base 의 최종상태는 과거의 commit 들의 합을 의미하고, 특정 commit 을 변경하는 행위는 과거의 특정 시점의 작업 내용을 변경함을 의미한다. git 에서 이러한 commit 은 매우 핵심적인 역할을 한다.

HEAD 현재 내가 있는 commit 을 의미한다. 내가 현재 있는 곳은 사용자에게 매우 직관적이기에 git 에서는 특정 commit 의 고유한 identity 인 commit hash 대신에 HEAD 를 기준으로 commit hash 를 표현하는 경우가 많다. 가령 HEAD~3 이란 현재 내가 있는 commit 으로부터 앞에서 3번째 커밋의 hash 를 가리킨다.

Setup

Global setup

git 의 사용자 정보 및 사용자별 다른 연결 정보등과 같은 공통의 설정들은 <home>/.gitconfig 파일에 설정할 수 있다.

이는 git config --global user.name = <USER_NAME> 등과 같은 명령어를 통해서도 가능하지만 파일에 직접 설정을 작성할 수 있다.

~/.gitconfig

1
2
3
4
5
6
7
8
9
10
11
12
13
[user]
name = <사용자 이름>
email = <사용자 이메일>
username = <USER_NAME>

[credential]
helper = cache # 비밀번호를 캐싱하여 계속 입력하지 않아도 되도록 한다.

# 특정 repository 에 대한 credential 을 설정한다.
# 예를 들어 만약 코드 커밋을 사용한다면 다음과 같이 code commit repository 세팅을 다음과 같이 할 수 있다.
[credential "<CODE_COMMIT_REPOSITORY>"]
helper = !aws codecommit credential-helper $@
UseHttpPath = true

위 설정은 간단히 아래의 커맨드로도 가능하다.

1
2
3
4
git config --global user.name <USER_NAME>
git config --global user.email <USER_EMAIL>
git config credential.helper cache
git config --list # 설정한 내용 확인

Repository level setup

위처럼 git 의 system 전역 세팅이 아닌 특정 git repository 마다 다른 세팅을 하고자 한다면 다음과 같은 레포지토리 마다 설정을 해줄 수 있다.

특정 repository 의 .git 디렉토리의 config 파일에 git 세팅을 할 수 있다.

SSH setup

Git repository 에 인증체계는 https 방식과 ssh 방식이 있는데, https 방식은 유저네임과 패스워드로 레포지토리 인증을 하는 것이고, ssh 방식에서는 사용자 pc 의 ssh 공개키를 github repository 에 등록하여 인증을 하는 방식이다.

먼저 ssh 인증 방식은 다음과 같다.

먼저, ssh를 활용하여 연결하기 위해서 컴퓨터의 ssh key를 생성하고, 생성된 공개키는 git에 등록한다.
공개키를 사용하려면 일단 공개키를 만들어야 하는데, 공개키를 만드는 방법은 모든 운영체제가 비슷하다.
먼저 키가 있는지부터 확인하자. 사용자의 SSH 키들은 기본적으로 사용자의 ~/.ssh 디렉토리에 저장한다.

리눅스 혹은 ubuntu의 경우 ssh-keygen을 통해 공개키/개인키 쌍을 생성할 수 있다.

1
ssh-keygen

위 명령어를 통해 공개키를 생성하였으면 ~/.ssh 디렉토리에 id_rsa.pub가 생성되었을 것이다.
해당 공개키를 git 홈페이지의 repository의 설정에서 등록해 주면 된다.

참조

Git Add

추가된 파일 포함시키고 커밋하기

1
2
3
4
5
### 모든 파일 추가
git add .

# 특정 파일 추가
git add <FILE_NAME>

branch

브랜치 생성 및 변경

1
2
git branch [브랜치명]
git checkout [브랜치명]

git branch [브랜치명] 명령어로 브랜치를 생성하고
git checkout [브랜치명] 명령어를 통해 브랜치를 변경한다.
여기서 checkout은 단순히 브랜치를 옮기는 것으로 지금까지의 변경내용이 바뀌지 않고 해당 브랜치로 이동하기 때문에
해당 브랜치에 지금의 변경내용이 전부 반영된다.

브랜치 삭제하기

git branch -d [branch Name]

commit

1
2
# 커밋하기
git commit -m "메세지"

checkout

Checkout 명령어는 현재 나의 code base 를 특정 커밋 혹은 브랜치로 옮기는 것이다.

사실 더 정확한 표현은 특정 커밋으로 옮긴다고 하는 것이 맞는 표현일 것 같다.

1
2
3
4
5
6
7
8
9
10
# 특정 브랜치로 code base 이동
# 사실 특정 브랜치 이름은 특정 커밋 해쉬를 의미한다.
# 해당 브랜치의 마지막 commit 으로 이동한다고 보면 된다.
git checkout <BRANCH_NAME>

# 특정 커밋으로 code base 이동
git checkout <COMMIT_HASH>

# 특정 파일만 특정 commit 으로 이동
git checkout <COMMIT_HASH> <FILE_NAME>

원격 브랜치 가져오기

git checkout -t origin/eventsource

###

log

먼저 커밋 내역을 확인할 수 있도록 log를 확인한다.

1
git log

merge

머지하기
git checkout master를 통해 마스터로 이동한다
git merge [commit name]

push

원격 코드베이스에 나의 코드를 밀어넣는다.

업스트림(upstream) 브랜치 설정
로컬 저장소를 init 명령어로 생성했을땐 수동으로 업스트림 브랜치를 설정할 필요가 있다. 업스트림 브랜치란 원격 저장소와 바로 연결된 로컬 저장소를 말하며 push나 pull 명령등에서 원격 저장소 이름을 생략할 수 있게 한다.

1
git push --set-upstream origin master

밀어넣기
git push origin [branch]

강제로 밀어넣기
git push -u origin master

pull

풀받기
git pull [remote 저장소] [브랜치]

rebase

Rebase 란 말 그대로 시작점을 다시 설정하는 것이다.

git 의 코드관리는 복잡해 보이지만 기본적으로 최초의 하나의 뿌리에서 부터 여러 갈래로 갈라져 나간 나무의 형태를 띄고 있다. 여기서 rebase 의 의미는 현재 나의 branch 와 합치고 싶은 다른 branch 의 base 즉 갈라져 나온 최초의 commit 시점을 찾아서 그 이후로 진행한 나의 모든 가지를 통으로 잘라서 다른 branch 의 끝으로 옮겨붙이는 것이다.

실제 나무에서 하나의 가지를 통으로 잘라내어 붙이고 싶은 가지를 선택해 그 가지의 끝에 잘라낸 가지를 옮겨붙이는 것을 생각하면 쉽게 이해할 수 있다.

이러한 rebase 는 상대방의 모든 코드 변화 이후에 나의 코드변화를 빠짐없이 적용할 수 있다는 점에서 매우 유용하다.

가령 친구와 나의 교과서 필기를 하나로 합치고 싶은데 제일 깔끔한 친구의 노트에 내 모든 필기내용을 한반에 옮겨적는 것을 생각해 보면 된다. 이 얼마나 편리한가! 만약 여기서 친구와 내가 같은 페이지에 다른 내용을 기록했다면 여기서 어떤 내용을 최종으로 작성할지 결정하는 작업이 필요하다.

과거 나의 커밋 내용을 수정하기

open source 활동을 하거나 혹은 대규모의 프로젝트를 진행할때 겪는 가장 큰 문제는 내가 작성한 과거의 코드내용, 즉 과거의 커밋 내용을 수정하는 것이다.

대부분의 경우 feature 브랜치에서 많은 내용을 수정하고 중간중간 변경 사항에 대해 commit 으로 기록하기 때문에 과거의 커밋을 바꾸기 위해서는 까마득한 예전의 코드로 돌아가 그 특정 부분을 수정하고 그 뒤의 변경사항을 다시 재적용 시키는 일이 필요하다.

이 경우에는 git rebase 명령을 사용하여 해결할 수 있으며 다음과 같은 절차를 거친다.

  1. git log 를 통해 나의 이전 커밋 내용을 확인한다.
  2. git rebase -i HEAD~n 를 통해 HEAD로 부터 얼마나 뒤 내용을 수정하고 rebase를 진행할지 정해준다. 가령 HEAD 로 부터 3 번째 커밋부터의 커밋들에 수정사항이 있다면 git rebase -i HEAD~3 명령어를 입력한다.
  3. 위 명령어를 입력하면 과거의 커밋들이 나타나고 커밋명 앞에 pick 이라는 키워드가 있다. 여기서 우리가 수정하기를 원하는 커밋의 pick 키워드를 e(edit) 으로 바꿔준다.
  4. 이제 git이 edit 하고자 하는 커밋으로 코드를 돌려주고 원하는 내용을 수정한 뒤에 git commit --amend 를 해주면 해당 커밋을 수정하여 다시 커밋하고 git rebase --continue 명령을 통해 뒤의 커밋들을 쭉 적용시켜 줄 수 있다.

remote

원격 레포지토리 등록하기

원격 저장소와 코드를 주고 받기 위해 가장 먼저 해야 할 일은 원격 저장소가 어디에 있는지를 알려주는 일이다.
다음과 같은 코드를 입력하기 원격저장소 origin의 위치를 등록해 준다.

1
git remote add origin <GIT_REPOSITORY>

revert

이번에는 기존에 한 커밋을 되돌리는 법을 배운다.

뒤로 돌리기

1
git revert HEAD

명령어를 통해 HEAD에 마지막으로 커밋된 내용을 뒤로 돌린다.

이 revert 에서 주의할 점은 해당 커밋의 변경내용을 정확히 반대로 하는 새로운 commit 을 만들어 내는 것이다.

즉, revert 를 하면 revert 하고싶은 commit 을 뒤로 돌리는 새로운 업데이트에 대한 commit 을 만들어 낸다.

stash

로컬 작업 내용 버리기 혹은 저장하기

당신이 어떤 프로젝트에서 한 부분을 담당하고 있다고 하자. 그리고 여기에서 뭔가 작업하던 일이 있고 다른 요청이 들어와서 잠시 브랜치를 변경해야 할 일이 생겼다고 치자. 아직 완료하지 않은 일을 커밋하는 것은 좀 껄끄럽다. 이런 상황에서는 커밋하지 않고 나중에 다시 돌아와서 작업을 다시 하고 싶을 것이다. 이 문제는 git stash라는 명령으로 해결할 수 있다.

1
2
3
4
5
git stash // stash difference
git stash clear // deled stased
git stash list // list up stashed
# stash 한 변경 내용들 불러오기
git stash pop

##

Configuration

Repository wide ssh setup

아래 명령어는 특정 레포지토리의 ssh 인증키를 별도로 세팅하는 코드이다. 이를 통해 여러개의 레포지토리 마다 별도의 ssh 인증키를 사용할 수 있다. 개인 pc 에서 업무용 repository 에 접근하는 경우라면 이러한 세팅은 매우 편리하다.

아래 명령어를 git repository 에서 실행함으로 간편하게 repository level 에서의 인증키를 등록할 수 있고

1
git config --local --add core.sshCommand 'ssh -i ~/your_key'

혹은 아래와 같이 직접 .git/config 파일을 수정할 수 있다.

1
2
[core]
sshCommand = "ssh -i ~/.ssh/<KEY_FILE>"

git home 디렉토리 변경하기

git 아이콘을 우클릭하여 대상 뒤의 –cd-home을 없애고

시작위치에 원하는 위치를 넣어준다.

CLI 에서 비밀번호 저장하기

git config credential.helper store

2FA 인증

git authentication

git 에서 2FA 인증을 하는 경우 personal access token을 발급받아서 해야한다.

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×