경일게임아카데미 멀티 디바이스 메타버스 플랫폼 개발자 양성과정 정리 번외1. Git

Jinho Lee·2022년 5월 5일

Git

많은 협업에서 프로젝트의 변경 사항을 관리할 때, 매번 새로운 파일로 저장하거나 공유를 하는 것은 작업의 효율에 큰 문제를 일으키기 마련이다. 이러한 문제를 해결하기 위해 파일의 변화를 기록하여 그 최신 버전을 공유하고 과거 버전으로 돌이킬 수 있게 해주는 시스템이 개발되었는데, 이를 버전 관리 시스템 (Version Control System)이라 한다. 그 중 현재 널리 사용되고 있는 Git을 중점적으로 배웠기에 그 내용을 이 글에서 정리한다.

버전 관리 시스템

  • 버전 관리 (Version Control) : 파일의 변화를 기록하는 것.

  • 버전 관리 시스템 (Version Control System, 이하 VCS) :
    파일의 변화를 기록하여 추후 특정 버전으로 불러올 수 있는 시스템. SVN, PerForce, Git

  • 버전 관리가 어디서 이뤄지는지에 따라 구분할 수 있다.

    • 로컬 : 내 컴퓨터에서만 버전 관리
    • 중앙집중형 : 서버에서만 버전 관리
    • 분산형 : 내 컴퓨터와 서버에서 같이 버전 관리

Git의 특징

  • Git은 분산형 버전 관리 시스템 (Distributed VCS)으로, 모든 변화의 히스토리를 각 개인이 들고 있게 된다.

스냅샷

  • 델타 기반 : 대부분의 VCS는 각 파일의 변화를 시간 순으로 관리.

  • 스냅샷(snapshot) : 특정 시점에 스토리지의 파일 시스템을 포착해 보관하는 기술

  • Git은 데이터를 파일 시스템 스냅샷의 연속, 스트림(흐름)으로 취급한다.

  • Git은 상태를 저장할 때마다 파일이 존재하는 그 순간을 중요하게 여긴다.

세 가지 상태

  • Git은 파일을 아래 세 가지 상태로 관리한다.

  • Committed : 버전 관리를 한 상태

    • 데이터가 로컬 데이터베이스에 안전하게 저장됐다는 것을 의미한다.
  • Modified : 수정이 일어난 상태

    • 수정한 파일을 아직 로컬 데이터베이스에 커밋하지 않은 것을 말한다.
  • Staged : 커밋하겠다고 한 상태

    • 수정한 파일을 곧 커밋할 것이라고 표시한 상태를 의미한다.

    • 커밋(commit) : 확정하다. 파일의 변화를 확정.

  • 각 상태의 작업

    1. 작업 디렉토리에서 파일을 수정 -> Modified

    2. 스테이지 영역에 파일을 추가하여 커밋할 스냅샷을 만든다. -> Staged

    3. 스테이지 영역에 있는 파일들을 커밋해서 Git 디렉토리에 영구적인 스냅샷으로 저장한다. → Committed

명령어

로컬

  1. git init : git 시작, 레포지토리 생성. Initialize repository

  2. git commit : 커밋을 한다.

    • -m “내용” : 바로 커밋 메시지 내용을 입력 가능
  3. git branch 브랜치명 : 브랜치를 새로 만든다.

    • -f 브랜치명 위치 : 브랜치의 위치를 지정, 브랜치를 위치로 강제로 이동.

    • -d 브랜치명 : 브랜치를 삭제

    • -u 추적할-원격-브랜치명 (추적시킬-브랜치명) : 브랜치가 원격 브랜치를 추적하도록 설정. 후술.

  4. git checkout 위치 : HEAD를 위치로 옮긴다.

    • -b 브랜치명 (위치) : 브랜치를 새로 만들고 선택, HEAD를 옮긴다. 위치 또한 지정 가능하다. 원격에서의 사용은 후술

    • HEAD : 현재 작업 중인 커밋의 위치를 의미한다.

  5. git merge 브랜치명 : 브랜치를 현재 HEAD에 합친다. (merge : 병합하다)

  6. git rebase 위치 : 현재 HEAD로부터 위치까지의 위치의 위에 커밋을 접목한다.(덧붙인다) HEAD가 위치의 부모에 있다면, 위치로 이동하여 최신 상태가 된다.

    • -i 위치 (위치) : rebase를 하면서, 커밋의 순서를 바꾸거나 필요없는 커밋을 제외할 수 있다. 포함을 시작하는 위치도 덧붙일 수 있다.
  7. git log : 커밋의 위치(해시, hash)를 모두 표시한다.

  8. 위치^ : 위치의 한 커밋 위를 상대적으로 가리킨다. 상대 참조. ex) HEAD^ - HEAD 한 커밋 위

  9. 위치~수 : 위치의 수만큼의 위를 상대적으로 가리킨다. 상대 참조. ex) HEAD~3 - HEAD 세 커밋 위

  10. 위치^수 : 위치에서 한 커밋 올라갈 때, 부모가 다수 있을 때 부모를 골라 올라갈 수 있다. ex) HEAD^2 - HEAD 두 번째 부모 한 커밋 위

  11. 위치~수^수^ : 상대 참조는 복수의 참조를 한번에 사용할 수 있다.

  12. git reset 위치 : 위치까지 변경내역을 되돌리는 명령어. 애초에 커밋하지 않은 것처럼 예전 커밋으로 브랜치를 옮긴다. * 로컬 (본인의 컴퓨터) 브랜치에서만 사용할 것

  13. git revert 위치 : 위치까지 변경내역을 되돌리고 공유하는 명령어. 리모트 (다른 사람의 컴퓨터) 브랜치에서 사용한다. * 반드시 한 커밋씩 되돌릴 것. 아니면 충돌한다.

  14. git cherry-pick 커밋(위치) 커밋 ... : 현재 위치(HEAD) 아래에 있는 일련의 커밋들에대한 복사본을 만들겠다는 명령어. rebase처럼 HEAD에 커밋을 덧붙인다. git rebase -i처럼 사용할 수 있다.

  15. git tag 태그명 커밋 : 영구적으로 움직이지 않는 태그를 커밋에 다는 명령어. 태그에 checkout해도 태그에 직접 커밋은 할 수 없다. HEAD가 분리될 뿐.

  16. git describe (위치) : 위치에서 가장 가까운 부모 태그까지, 몇 커밋 멀리 있는지와 묘사하고 있는 커밋의 해시(위치)를 표시한다. 위치를 지정하지 않으면 지금 checkout된 곳을 사용한다.(HEAD)

  17. git status : repository 상태 확인

  18. git add 파일명 : git에 파일 추가, 파일명에 .을 입력하면 디렉토리 내 전부를 추가 → staged 상태로 변환, 스테이징 영역 추가

  19. git log : 커밋 기록 표시 - 다양한 옵션으로 커스터마이징 가능

    • --all : 모든 브랜치 표시

    • 너무 길면 q, w, e로 표시 조절 가능

    • e : 아래로 / w : 위로 / q : 나가기

  20. git restore 파일명 : 변화 내용 복구

  21. git config : git 설정, Configure repository

  • 표시 내용 CONFLICT : 충돌이 일어났다는 의미.

    • 병합 충돌 해결 기능 : 툴에 따라 제공되는 기능.
      기존 변화를 남길지 / 신규 변화를 남길지 / 둘 다 남길지 / 그리고 둘을 비교해볼지를 선택해 자동으로 충돌 없이 병합이 가능하다.

원격

  1. git clone : 원격 저장소의 복사본을 로컬에 생성할 때 사용하는 명령어. * 실제로 사용하는 방법은 좀 다르다.

    • 원격 브랜치 origin/main : 원격 저장소의 상태를 반영, 추적하는 특수한 브랜치

    • 브랜치의 이름은 main, 원격 저장소의 이름은 origin.

    • 체크 아웃을 하게 되면 분리된 HEAD 모드로 가게 된다.

  2. git fetch : 원격 저장소에서 업데이트된 내용을 가져오는 명령어.

    • 원격 저장소에는 있지만 로컬에는 없는 커밋들을 다운로드 받고 원격 브랜치가 가리키는 곳을 업데이트한다.

    • 로컬 상태는 전혀 바꾸지 않는다.

    • 작업 전에 반드시 하게 될 작업이 될 것.

  3. git remote 이름 URL : Github 등의 원격 저장소와 연결. 원격 저장소의 이름은 관습적으로 origin을 많이 쓴다.

  4. git remote : 현재 원격 저장소의 이름을 표시한다.

  • 로그를 git adog로 모든 브랜치를 예쁘게 한 줄에 그래프로 표시하기 위한 설정 명령.
    git config --global alias.adog "log --all --decorate --oneline --graph”
    실사용 : git adog
  • 브랜치 명은 다른 커밋의 주소 등과 겹쳐서는 안된다.
  • HEAD로 지정된 브랜치는 강제 이동이 되지 않는다.

원격 추적

  • main브랜치는 o/main브랜치를 추적하도록 설정되어 있다. 이것은 main가 merge와 push할 내재된 목적지가 생겼다는 뜻.
  • pull 작업 중
    • 커밋들은 o/main에 내려받아 지고 그다음 main 브랜치로 merge된다. merge에서 내재된 타겟은 이 연결에서 결정한다.
  • push 작업 중
    • main 브랜치의 작업은 원격의 main브랜치(로컬에서 o/main로 표현되는)로 push 된다. push의 목적지는 main와 o/main의 연결에서 결정된다.
  • o/main을 추적할 다른 브랜치도 지정 가능.
  1. git checkout -b 추적시킬-브랜치명 추적할-원격-브랜치명

    • 브랜치를 새로 만들고, HEAD를 놓고, 브랜치가 원격 브랜치를 추적하도록 설정한다.
  2. git branch -u 추적할-원격-브랜치명 (추적시킬-브랜치명)

    • 브랜치가 원격 브랜치를 추적하도록 설정한다. 현재 작업 중인 브랜치라면 브랜치명을 생략 가능하다.
  3. git push 원격-저장소 위치

    • 위치로 가서 모든 커밋을 수집하고, 원격 저장소에 부족한 커밋을 채워넣는다.
  4. git push 원격-저장소 로컬-위치:원격-위치

    • 로컬 위치로 가서 모든 커밋을 수집하고, 원격 저장소의 원격 위치에 부족한 커밋을 채워넣는다.

    • ":" colon refspec(콜론 참조스펙) : git이 알아낼 수 있는 위치

  5. git fetch 원격-저장소 위치

    • 위의 push와 같이, 원격의 위치로 가서 모든 커밋을 수집하고, 로컬 저장소에 부족한 커밋을 원격 브랜치 밑에 채워넣는다. 다음과 같이 콜론 참조스펙도 사용 가능하다.

    • git fetch 원격-저장소 원격-위치:로컬-위치

    • 딱히 인자가 없다면, 모든 원격 브랜치로 커밋들을 내려받는다.

  6. git pull 원격-저장소 위치

    • pull은 fetch에 merge를 더한 것

    • fetch와 마찬가지로 원격의 위치로 가서 모든 커밋을 수집하고, 로컬 저장소에 부족한 커밋을 원격 브랜치 밑에 채워넣고 merge한다. 콜론 참조스펙도 사용 가능하다.

  • 콜론 참조스펙에서, 앞의 로컬 위치를 (없음)으로 지정 가능
    • push - 로컬, 원격의 브랜치(위치)의 삭제
    • fetch - 로컬에 원격에 넣은 이름의 브랜치 생성

유닉스 (git bash) 기초 명령어

  1. cd : change directory, 디렉토리 변경

  2. mkdir 디렉토리명 : make directory, 디렉토리 생성

  3. ls : list, 디렉토리 안 모두 표시

  4. touch 파일명 : 빈 파일 생성

  5. clear : 지우기

  6. rm -f 파일명 : 파일 삭제

    • rm -rf 폴더명 : 재귀적으로(-r), 강제적으로(-f) 폴더를 삭제한다. 강제적 삭제이므로 매우 조심할 것.
  7. vi 파일명 : vim editor 열기

    • vim editor

      • vim editior 안에서 i : insert mode, 텍스트 작성 모드

      • vim editior 안에서 Esc : 명령어 모드

      • :wq : vim editior에서 나가기

참고

협업

Github Flow

효율적인 협업을 위한 브랜치 관리 전략에는 Git Flow, Github Flow, Gitlab Flow 등이 있다.

  • Github Flow
  1. main 브랜치는 항상 안정적이고 최신의 상태여야 한다. 실수로 main 브랜치에 푸시하지 않도록 주의한다.

  2. 브랜치 이름은 다른 사람이 봐도 어떤 작업인지 한눈에 알 수 있도록 명확히 이름을 짓는다.

  3. 원격에도 자주 푸시해 어떤 작업을 하는지 다른 사람에게 공유한다.

  4. 피드백이나 도움이 필요한 경우 혹은 병합할 준비가 됐다면 Pull Request를 연다. Pull Request는 코드 리뷰를 도와주는 시스템으로 어떤 변화가 있는지 확인할 수 있고, 코드에 대해 토론할 수 있으며, 간단한 충돌도 해결할 수 있다.

  5. 팀원들과 충분한 논의를 거친 후에 main으로 병합할 수 있도록 한다.

  6. (Advanced) main에 푸시 됐거나 병합된 것은 즉각 배포되어야 한다.

    • CI/CD : 지속적 통합/지속적 제공

협업에서 충돌을 줄이기 위한 규칙

Git 실습을 하며, 수없이 많은 충돌이 일어났다. 이를 해결하기 위해 다음과 같은 규칙을 배웠고, 실천했다.

  1. main 브랜치에서 기능 관련 브랜치를 만들고 체크아웃한다.

  2. 기능을 개발할 때마다 커밋하면서 푸시를 한다.

    2-1. 개발 및 커밋하기 전 git fetch를 통해서 원격 저장소를 항상 최신화한다.

    2-2. main에 새로운 기능이 추가되었다면 내 브랜치로 병합한다.

    2-3. 커밋하기 전 항상 내 코드를 스스로 리뷰한다.

  3. 기능 개발이 끝났다면 Pull Request를 연다.

    3-1. Pull Request 도중 충돌이 발생했을 경우 로컬에서 충돌 해결한 다음 푸시한다.

  4. 다른 사람들한테 Pull Request를 열었다고 알려준다.

  5. 해당 팀원의 코드를 리뷰한다.

  6. 리뷰가 끝났다면 병합한다.

  7. 병합이 끝나면 원격 브랜치를 삭제한다.

Github 기능 - Branch Protection Rule

  1. Require a pull request before merging
  2. Require approvals : 전체 팀원 - 1 만큼 설정.
  3. Require review from Code Owners : 팀장(레포지토리 주인)의 리뷰를 반드시 받아야 한다.
  4. Include administrator : 팀장도 리뷰를 받아야 한다.

커밋 메시지 컨벤션

타입[범위]: 제목

[본문]

[꼬릿말]

타입

  • 커밋 타입은 아래와 같다. 범위에는 관련된 기능을 적을 수도 있고, 이슈 ID를 적을 수도 있다.
  1. Feat: 새로운 기능의 추가

  2. Fix: 버그 수정

  3. Docs: 문서 수정

  4. Style: 스타일 관련 기능(코드 포맷팅, 세미콜론 누락, 코드 자체의 변경이 없는 경우)

  5. Refactor: 코드 리펙토링

  6. Chore: 빌드 업무 수정, 패키지 매니저 수정 등 잡다한 일(ex .gitignore 수정 같은 경우)

제목

본문

  • 본문은 구현 방법보다는 변경한 내용과 이유를 설명한다.

  • 한 줄 당 72자 내로 작성하며 양에 구애받지 않고 최대한 상세히 작성한다.

꼬릿말

  • 선택사항

  • 보통 Github Issue 추적을 위해 사용한다.

  • “유형: #이슈 번호” 형식을 사용하며, 여러 개의 이슈 번호를 적을 때는 쉼표로 구분한다.

  • 유형은 Resolves, See also를 사용한다.

Git GUI

참고

0개의 댓글