본문 바로가기
DevOps/Linux, Git

[Git] 기본적인 Git 정리

by DUSTIN KANG 2023. 12. 3.

Git?

Git은 리누스 토르발즈가 BitKeeper의 문제점을 해결하고자 만든 VCS(버전관리시스템)이다.

Git을 사용하는 이유는 협업 또는 백업 관리등을 위해 사용한다.

 

Git Settings

  1. Homebrew를 설치 후, `brew install git` 명령어로 Git을 설치한다.
  2. Git과 Github 계정 전역(global) 연결하기
    • `git config -global user.name "깃허브_계정_이름"`
    • `git config -global user.email "깃허브 가입 이메일"`
    • `git config --list` 
    • `git config --global init.defaultbranch main` Master 브랜치에서 Main 브랜치로 이름 변경(의무는 아님)
  3. 프로젝트 디렉토리에 `git init`으로 숨김 파일 .git을 생성한다.
  4. 로컬 저장소와 Github 원격 저장소를 연결한다.
    • Github에 새로운 레포지토리를 생성한다.
    • `git remote add <원격저장소의 이름 지정, origin> <레포지토리의 url>` 원격 저장소 등록
    • `git push -u origin main` 만약 `main`이라는 깃 브랜치 지정이 안되어 있는 경우 `git branch -M main`으로 생성해야한다.
    • token 발급 : [settings] - [Developer Settings] - [Personal access tokens] - [generate new token] - [repo ✅] 
💡 SSH 프로토콜을 통한 깃허브 통신
HTTPS 방식으로 데이터를 가져오는 경우도 있지만 SSH 방식도 있다.
1. `ssh-keygen -t rsa -C "깃허브 가입 이메일"`와 엔터키로 키를 생성한다.
2. `.ssh/id_rsa.pub`이라는 키 파일이 있다는 것을 확인할 수 있다.
3. Github에서 [Settings] - [SSH and GPG keys] - [New SSH Keys]에서 `key` 내용에 `cat` 명령어로 키내용을 복사해 넣고 생성한다.
4. `remote add origin git@<SSH 레포주소>` 명령 후 커밋할 수 있다.
만약, 이전에 HTTPS 방식을 사용했다면 `git remote remove origin`으로 지워야 한다.

 

Git Lifecycle과 상태 관리

레포지토리의 상태를 확인하는 명령어는 `git status`를 통해 확인할 수 있다.

 

 

 

위에 LifeCycle을 보면 Untracked한 데이터들을 `git add` 하며 Stage에 올릴 수 있다.

그리고, 모든 변경 사항에 대한 절차가 끝났을 경우, Unmodified한 상태에서 `git commit`으로 Git에 변경 사항을 저장한다.

커밋에는 세가지 옵션이 존재한다.

  • `git commit -m` :  커밋 메세지를 적용한다.
  • `git commit -a`: `git add`와 같이 진행하는 방법이다.
  • `git commit --amend` : 직전 커밋을 수정해서 지금 수정사항과 추가해 git에 적용된다. 

커밋을 기록하게 되면 `git log`를 통해 저장된 기록을 볼 수 있다. 가장 최신 커밋이 최상단에 위치한다.

 

커밋을 할 때, 커밋 메서지를 작성한다고 했는데 어떻게 하면 커밋 메시지를 잘 작성할 수 있을까?

 

💡 git stash
만약 수정된 파일을 잠깐 임시 저장하려면 어떻게 해야할까? git에는 `stash`라는 수정된 파일을 임시저장해주는 명령어가 있다.
물론, git에 적용된 파일이어야 한다. 브랜치에서 작업하다 다른 브랜치로 바꿀 때 커밋을 안할때 사용한다.
Stack 형식으로 이루어져 있으며 `stash`을 통해 임시저장해두고 `pop`을 통해 최근 저장한 내역을 가져올 수 있다.
또는 `drop`(삭제) `apply`(적용) `list`(리스트확인) `clear`(전부 삭제)등 명령어로 사용할 수 있다.

 

commit message Convention

 

더보기

Commit Message Convention 예시

  • 제목(Header) : `Feat(urls.py):Urls.py 생성`
  • 작업 설명() : `- Implement url.py routing`
  • 꼬리말 : `Ref : #3`
Feat, Feature 새로은 기능을 추가할 때 사용한다.
Fix, bugfix 버그를 수정하거나 typo(오타)를 수정한다.
refactor 리팩토링 작업 시, 사용한다.
desgin CSS, UI 디자인 변경시 사용한다.
docs 문서 수정 및 추가 삭제 시 사용한다.
remove 파일 삭제시 사용한다.
rename 파일이나 디렉토리명을 수정하는 경우
init 프로젝트 초기 설정
chore 필요한 주석을 추가하거나 잡일의 경우
tests 테스트 코드를 작성하거나 테스트를 하는 경우
env 환경 설정 변경시 사용
Fixes 이슈를 수정 중이고 아직 해결되지 않음
Resolves 이슈를 해결한 상태
Ref 참조할 이슈가 있는 경우
Related to 해당 커밋에 관련된 이슈 번호

참고자료

 

결과를 되돌리는 명령어

git show

`git log`로 확인했던 이전 결과를 볼 수 있는 명령어 이다.

  • `HEAD`나 `@`은 현재 시점을 의미한다.
  • `~` `^`는 이전 시점을 의미한다.
  • 원하는 커밋을 확인하려면 hash값을 이용해 확인할 수 있다.
git show @~2
git show HEAD~2

 

git reset

이전에 커밋 상태로 돌아가는 명령어로 다시 원래 상태로 돌아올 수 없기 때문에 `--hard`를 사용하는 일은 없어야 한다.

git resest --soft @~

 

 

git revert

이전에 커밋 상태로 돌아가는 명령어커밋 상태가 기록된다는 것이 특징이다. 그래서 협업할 때는 reset보다 revert를 사용한다.

  • `--no-commit` 옵션을 사용하면 커밋 직전 상태에서 추가 작업을 진행 후 커밋을 할 수 있다.
  • Hash 값을 전달한다.
git revert <hash>

 

 

Git Branch

 

 

 

  • `git branch -m` : 브랜치의 이름을 변경할 때 사용한다.
  • `git branch -d` : 브랜치를 삭제하는 옵션이다. 반드시 원격 저장소에 merge를 해야한다. 커밋 여부 없이 강제로 삭제할려면 `-D`를 사용한다.
  • `git branch -v` : 브랜치의 상세 정보를 확인한다.
  • `git branch --merged` : 현재 브랜치에 이미 머지한 브랜치를 확인한다. `--no-merged`는 반대로 머지하지 않은 브랜치를 살펴본다.
  • `git checkout "브랜치"` : 브랜치를 이동 시킨다.  HEAD의 위치를 변경한다. (`git switch "브랜치"`)
  • `git checkout -b "브랜치"` : 브랜치를 생성하고 이동한다. (`git switch -c "브랜치"`)
  • `git merge "대상브랜치"` : 브랜치를 병합하는 명령어이다.
💡 brew install tig
지금까지 작업했던 커밋들을 시각적으로 볼 수 있다. `tig` 명령어를 통해 확인할 수 있다.

 

충돌(Conflict) 해결하기

언제나 누구든 git 작업을 하다보면 반드시 충돌이 발생한다.

충돌에 대해서는 겁날 필요도 없고 도망갈 필요도 없다.

 

다음은 Main 브랜치에서 파일에 main이라는 문구를 작성하고 커밋했다.

Feature/conflict이라는 브랜치를 생성하여 Conflict이라는 문구를 작성했고 커밋했다.

또, 추가로 Main 브랜치에서 Feature/Conflict#2라는 브랜치를 생성해 문구를 작성하고 커밋했다.

 

이제 Main에서 Feature/Conflict 브랜치과 Merge를 시도했는데 정상적으로 Merge가 이루어졌다.

하지만, Feature/Conflict#2와 Merge에는 충돌이 일어났다. 이러한 상황에서는 다음과 같은 충돌이 일어난다.

 

 

간단하게 고치고 싶으면 commit을 하거나 병합을 취소하고 싶으면 --abort로 병합을 취소하면 된다.

만약 고친다는 가정하에 아래 코드를 수정할 수 있다.

 

 

Git Flow(브랜치 전략)

브랜치 전략에는 Local 중심의 Git FlowRemote 중심의 Github Flow가 있다.

Git Flow

일반적으로 사용되는 Branch로 Main, Develop, Release, Feature, hotfix 등이 있다.

  • Main 브랜치 : 배포용 브랜치로 직접 커밋을 하지 않고 Develop, Release, Hotfix 브랜치에서 merge를 한다.
  • Develop 브랜치 : 개발용 브랜치지만 충돌(Conflict)를 방지하기 위해 Feature에서 작업 후 Develop에 Merge하는 방식으로 진행된다.
  • Release 브랜치 : 선택 사항인 배포용 브랜치로 실제 배포를 준비하기 위한 브랜치이다. 이 단계에서 bugfix나 리팩터링을 진행한다.
  • Hotfix 브랜치 : main 브랜치에서 심각한 버그나 문제가 발생했을 때 hotfix를 만들어 문제를 해결후 main, develop에서 merge 한다.
  • Feature 브랜치 : 실질적으로 코드를 작성하고 하나하나 기능을 구현하는 브랜치로 작업이 완료한 후 develop에 merge 한다.

Github Flow

Remote 중심의 Branch 전략으로 Main(main, develop, release), Feature(feature, Hotfix) 브랜치등이 있다.

 

Remote에 작업한 내용을 수시로 push하여 Remote를 항상 최신 상태로 유지해야 한다.

Git Flow의 Develop, Release 브랜치 처럼 배포 준비를 위한 브랜치가 없기 때문에 Main에 merge 할때 엄격하게 다뤄져야 한다.

 

Git Flow 만들어보기

# develop 브랜치 생성
git branch develop

# feature 브랜치 생성
git checkout 'develop'
git branch feature
git checkout 'feature'

# 코드 작성 및 커밋
touch main.py
git add main.py
git commit -m "add main.py"

# pull request으로 merge 요청

 

 

Push and Pull

Push

`git push origin main`은 로컬 브랜치의 내용을 원격 브랜치로 전달하는 명령어이다.

만약 협업의 경우에는 `git push origin features/who` 처럼 새로 브랜치를 생성하여 Pull request를 진행한다.

 

Pull

원격저장소에서 데이터를 가져오고 대상 브랜치에 자동으로 merge한다.

 

fetch

원격저장소에서 데이터를 가져오지만, merge를 하지않는 명령어다.

원격저장소에 변화가 있는지 확인할 때 사용하는 명령어이다. 만약, 로컬과 원격의 변경 사항이 다르다면 비교를 하고 merge나 pull을 진행할 수 있다.