📚 목차

  1. Git 이란 무엇인가?
  2. Git 기본 워크플로우
  3. Git 설정 (Configuration)
  4. Git 필수 개념 및 유용한 기능
    • Conventional Commits
    • .gitignore
    • Git Branch
    • Troubleshooting (문제 해결)
    • Git 습관 만들기
  5. Git & GitHub 협업
    • GitHub Issues
    • GitHub Projects
    • GitHub Wiki
    • Pull Request (PR)
    • Fork 기반 GitHub Flow 협업 전략

1. Git 이란 무엇인가?

  • 분산형 버전관리 시스템 (Distributed Version Control System, DVCS)

    • Linus Torvalds가 Linux 커널 관리를 위해 개발했습니다. (1주일 만에!)
    • 현재 업계 표준으로 압도적으로 많이 사용됩니다.
  • 주요 특징

    • 단순한 구조와 빠른 속도: 변경사항을 스냅샷으로 저장합니다.
    • 분산형 저장소 지원: 로컬 저장소와 원격 저장소 모두 존재하며, 네트워크 연결 없이도 대부분의 작업이 가능합니다.
    • 비선형적 개발 (수천 개의 브랜치) 가능: 브랜치를 통해 독립적인 작업 흐름을 만들고 관리하기 용이합니다.
  • Git의 장점 (Pros)

    • 소스코드를 주고받을 필요 없이 동시 작업이 가능하여 생산성이 증가합니다.
    • 수정 내용을 commit 단위로 관리하며, 원하는 시점으로 쉽게 돌아갈 수 있습니다 (Checkout).
    • Branch를 통해 새로운 기능을 편안하게 실험하고, 완료되면 Merge하여 반영합니다.
    • 인터넷 연결 없이도 작업할 수 있습니다.
  • CLI vs GUI:

    • CLI (Command Line Interface)를 배우는 것이 중요합니다.
    • Cloud Platform 등에서 관련 작업을 위해서는 CLI가 필수적입니다.
    • CLI에 익숙해지면 GUI 도구 적응이 훨씬 쉬워집니다.
    • Shell 명령에 익숙해지는 데 도움이 됩니다.
  • Git Internals - Objects:

    • Git은 내부적으로 세 가지 주요 오브젝트를 관리합니다.
      • Blob: 파일 하나의 내용을 저장합니다.
      • Tree: Blob이나 다른 Tree의 메타데이터 (디렉토리 구조, 속성, 이름 등)를 저장합니다.
      • Commit: 특정 시점의 스냅샷 (Tree)과 메타데이터 (작성자, 시간, 이전 Commit 정보 등)를 기록합니다.
    • 자세한 내용은 Git Internals - Git Objects를 참고하세요.
  • Git은 System, GitHub는 Service:

    • Git은 버전 관리를 위한 시스템(System) 입니다.
    • GitHub, GitLab, Bitbucket 등은 Git 저장소를 호스팅하고 협업 기능을 제공하는 서비스(Service) 입니다. 이 둘을 혼동하지 않는 것이 중요합니다.

2. Git 기본 워크플로우

Git은 Working Directory, Staging Area, Local Repository, Remote Repository 네 가지 영역을 중심으로 동작합니다.

graph LR
    A[Working Directory] --> B(Staging Area): git add
    B --> C(Local Repository): git commit
    C --> D(Remote Repository): git push
    D --> C: git pull
    C --> A: git switch / git checkout
  • Working Directory: 실제 파일을 작업하는 공간입니다.

  • Staging Area (Index): 다음 커밋에 포함시킬 변경사항들을 준비하는 공간입니다. git add 명령으로 변경사항을 이곳에 올립니다.

  • Local Repository: git commit으로 저장된 커밋들이 쌓이는 공간입니다. 내 컴퓨터에 저장됩니다.

  • Remote Repository: 네트워크 상에 있는 저장소입니다. GitHub, GitLab 등이 제공하는 공간으로, 여러 사람이 협업할 때 사용합니다. git push로 로컬 커밋을 올리고, git pull로 원격 저장소의 변경사항을 가져옵니다.

  • 시작하는 방법:

    1. git clone {username/repo-addr}: 원격 저장소를 내 로컬로 복제합니다.
    2. cd {repo-addr}: 복제된 저장소 디렉토리로 이동합니다.
    3. vi README.md: 파일 수정/추가 등 작업을 수행합니다.
    4. git status: 현재 Working Directory와 Staging Area의 상태를 확인합니다.
    5. git add README.md: 변경된 파일을 Staging Area에 올립니다.
    6. git commit: Staging Area의 변경사항을 Local Repository에 커밋으로 기록합니다. (Conventional Commit 메시지 작성!)
    7. git push origin main: Local Repository의 커밋을 원격 저장소(origin)의 main 브랜치로 올립니다.
  • Github Personal Access Token (PAT):

    • Github을 처음 사용할 때, 비밀번호 대신 Token을 사용해서 계정 접근 권한을 부여해야 합니다.
    • https://github.com/settings/tokens 에서 생성하고 사용합니다.

3. Git 설정 (Configuration)

Git을 사용하기 전에 사용자 정보와 편집기 등을 설정하는 것이 좋습니다.

# 전역 사용자 이름 설정
$ git config --global user.name “{username}"

# 전역 사용자 이메일 설정
$ git config --global user.email “{emailaddr}# 기본 편집기 설정 (vim으로 설정하는 경우가 많습니다)
$ git config --global core.editor “vim”

# pager 설정 (log 등의 긴 출력을 볼 때 사용, 'cat'은 pager 없이 전체 출력)
$ git config --global core.pager “cat”

# 현재 설정 확인
$ git config --list

# 수정이 필요할 경우, ~/.gitconfig 파일을 직접 편집할 수 있습니다.
$ vi ~/.gitconfig

4. Git 필수 개념 및 유용한 기능

Conventional Commits

  • 목적: 커밋 메시지를 구조화하여 가독성을 높이고, 자동화 도구 활용(변경 로그 생성, 버전 관리 등)을 가능하게 합니다.

  • 규칙:

    • 제목은 type(scope): description 형식으로 작성합니다. scope는 선택 사항입니다.
    • description은 현재형/명령형으로 작성하며, 문장이나 절의 형태로 작성합니다. (Add feature vs Adds feature)
    • Breaking Change가 있다면 type 뒤에 !를 붙일 수 있습니다 (feat!:).
  • Prefix (type): (일반적인 예시)

    • feat: 새로운 기능 개발
    • fix: 버그 수정
    • docs: 문서 수정 (README, 주석 등)
    • style: 코드 포매팅, 세미콜론 누락 등 (코드 자체 변경 없음)
    • refactor: 코드 리팩토링 (기능 변경 없음)
    • test: 테스트 관련 코드
    • chore: 빌드 시스템, 라이브러리 설치 등 (프로덕션 코드 변경 없음)
    • build: 빌드 시스템 관련
    • ci: CI 설정 관련
    • perf: 성능 개선
    • revert: 이전 커밋 되돌리기
  • Conventional Commit Template:

    {type}: {description} 작업단위 축약(breaking change가 있다면 type 뒤에 !)
    
    {body} 작업 상세 기술 (선택 사항)
    
    {footer} 부가정보 (예: Issue 번호, Breaking Change 설명)
  • 예시:

    feat: add sign up component
    
    This commit adds the sign up component to the application.
    
    Closes #123
    fix!: resolve issue with login page
    
    This commit fixes an issue with the login page that prevented users from logging in.
    
    BREAKING CHANGE: drop social login support
    Closes #123
  • 참고: https://www.conventionalcommits.org/ko/v1.0.0/

.gitignore

  • 목적: Git이 특정 파일이나 디렉토리를 추적하지 않도록 명시하는 파일입니다. 빌드 파일, 로그, 개인 설정 파일 등을 Git 저장소에 포함시키지 않을 때 사용합니다.

  • 프로젝트 루트에 .gitignore 파일을 생성하여 규칙을 작성합니다.

  • 예시:

    # 주석은 #으로 시작
    # MacOS 설정 파일 무시
    .DS_Store
    
    # Python 캐시 파일 무시
    # *.pyc
    # __pycache__/
    
    # Vim 스왑 파일 무시
    *.swp
    *.swo
    
    # 특정 디렉토리 무시
    temp/
    build/
    
    # 특정 파일 패턴 무시
    *.log
    config/*.env
    
    # 하위 디렉토리의 특정 파일 패턴 무시
    Credentials/**
  • 유용한 .gitignore 템플릿 생성기: https://gitignore.io/

Git Branch

  • 목적: 기존 코드에서 분기점을 만들어 독립적으로 코드를 변경하고 관리하는 모델입니다. 여러 개발자가 동시에 작업하거나 새로운 기능을 안전하게 실험할 때 사용합니다.

  • 기본 명령어:

    • git branch: 로컬 브랜치 목록 확인
    • git branch -r: 원격 브랜치 목록 확인
    • git branch -a: 전체 브랜치 목록 확인
    • git branch {branch name}: 새로운 브랜치 생성
    • git switch {branch name}: 특정 브랜치로 전환
    • git merge {branch name}: 현재 브랜치에 다른 브랜치의 변경사항 병합
  • 브랜치 삭제:

    • git branch -d {branch name}: 병합된 브랜치 삭제
    • git branch -D {branch name}: 병합되지 않은 브랜치 강제 삭제
  • 브랜치 Push:

    • git push origin {branch name}: 특정 브랜치를 원격 저장소에 올립니다.
    • git push -u origin {branch name}: 처음 push 할 때 로컬 브랜치와 원격 브랜치를 연결합니다 (-u 옵션). 이후에는 git push만 사용해도 됩니다.
  • 브랜치 간 변경사항 확인:

    • git diff main stem: main 브랜치와 stem 브랜치 간의 차이를 확인합니다.

Troubleshooting (문제 해결)

개발 과정에서 흔히 발생하는 문제 상황과 해결 방법입니다.

  • 작업 중인 변경사항 잠시 미뤄두기 (Stash):

    • git stash: 현재 Working Directory와 Staging Area의 변경사항을 임시 저장합니다.
    • git stash save “{message}”: 메시지와 함께 stash 합니다.
    • git stash list: Stash 목록을 확인합니다.
    • git stash pop: 가장 최근의 stash를 적용하고 목록에서 삭제합니다.
    • git stash pop {index}: 특정 index의 stash를 적용하고 삭제합니다.
    • git stash apply {index}: 특정 index의 stash를 적용하지만 목록에서 삭제하지 않습니다.
    • git stash drop {index}: 특정 index의 stash를 삭제합니다.
  • Working Directory 변경사항 취소하기 (Undo):

    • git restore {filename}: 특정 파일의 Working Directory 변경사항을 마지막 커밋 시점으로 되돌립니다.
    • git restore .: 현재 디렉토리의 모든 Working Directory 변경사항을 되돌립니다.
  • Staging Area 변경사항 내리기 (Unstaging):

    • git reset HEAD {filename}: 특정 파일을 Staging Area에서 Working Directory로 내립니다. (Git 2.23 이전 버전에서는 git reset HEAD {filename} 또는 git rm --cached {filename})
  • Staging Area 변경사항 내림과 동시에 삭제:

    • git rm -f {filename}: 파일을 Working Directory와 Staging Area에서 삭제하고, 다음 커밋에 삭제를 반영합니다.
  • 직전 Commit Message 수정하기:

    • git commit --amend: 직전 커밋을 수정할 수 있습니다. Staging Area에 add 된 변경사항이 있다면 함께 커밋에 포함시킬 수 있습니다.
  • 이전 Commit Message 수정하기:

    • git rebase -i <commit>: <commit> 이전의 커밋부터 현재 HEAD까지의 커밋 내역을 대화형으로 수정할 수 있습니다. pick, reword, edit, squash, fixup, drop 등의 작업을 할 수 있습니다.
    • Rebase 도중 문제가 발생하면 git rebase --continue 또는 git rebase --abort로 중단합니다.
  • 커밋을 없었던 일로 만들기 (Reset commit):

    • git reset --hard HEAD~{nums of commit}: 현재 브랜치의 HEAD를 {nums of commit} 만큼 이전으로 이동시키고, Working Directory와 Staging Area의 변경사항을 모두 버립니다. 주의: 로컬 변경사항이 유실될 수 있습니다.
    • git push -f origin <branch>: 로컬 브랜치의 변경 이력을 강제로 원격 브랜치에 덮어씌웁니다. 주의: 협업 시 팀원들의 이력과 충돌을 일으킬 수 있습니다.
  • 잘못된 커밋을 되돌리기 (Revert commit):

    • git revert <commit>: 특정 커밋에서 일어난 변경사항을 되돌리는 새로운 커밋을 생성합니다. 기존 커밋 이력을 보존하면서 변경을 취소할 때 사용합니다. Reset 보다 안전하며 협업에 적합합니다.
    • git revert --no-commit HEAD~{nums of commit}..: 여러 커밋을 되돌리되, 하나의 새로운 커밋으로 합칩니다.
    • git revert -m {1 or 2} {merge commit id}: 머지 커밋을 되돌릴 때 사용하며, 어떤 부모 커밋 기준으로 되돌릴지 선택합니다.
  • Merge Conflict 해결:

    • Merge나 Rebase 작업 중 같은 파일의 같은 부분을 다른 내용으로 수정했을 때 발생합니다.
    • Git은 가능한 경우 auto-merge를 시도하지만, 충돌 시에는 수동 해결이 필요합니다.
    • 해결 방법:
      1. 충돌이 발생하면 Git은 해당 파일에 충돌 마커 (<<<<<<<, =======, >>>>>>>)를 표시합니다.
      2. 충돌 파일을 편집기로 열어 원하는 내용만 남기고 충돌 마커를 제거합니다.
      3. 수정된 파일을 git add {filename}으로 Staging Area에 올립니다.
      4. git commit 명령으로 충돌 해결 커밋을 생성합니다. Merge 중이었다면 자동으로 커밋 메시지가 생성됩니다. Rebase 중이었다면 git rebase --continue를 실행합니다.

Git 습관 만들기

  • TIL (Today I Learned) Repository: 매일 배운 것을 Git에 기록하여 커밋/푸시 습관을 만듭니다.
  • GitHub Blog: Hexo 등으로 정적 블로그를 만들어 Markdown 작성 습관을 들이고 배포를 경험합니다.
  • Side Project: 작은 단위의 프로젝트를 꾸준히 진행하며 Git 워크플로우를 반복 연습합니다.

5. Git & GitHub 협업

GitHub는 Git 기반의 다양한 협업 도구를 제공합니다.

GitHub Issues

  • 목적: 프로젝트의 할 일, 버그, 질문 등 다양한 이슈를 추적하고 관리하는 기능입니다.

  • 활용:

    • Issue Template을 만들어 일관성 있는 리포트를 유도합니다. (예: 버그 리포트, 기능 요청 템플릿)
    • Label을 활용하여 이슈의 상태, 종류, 긴급도 등을 표시합니다. (Sane GitHub Labels 참고)
    • Milestone을 설정하여 특정 기간(Sprint) 내에 해결해야 할 이슈들을 묶어 관리하고 진행률을 파악합니다.
    • Pull Request에서 Issue 번호를 언급하여 자동으로 연결/종료되게 합니다. (close #123, fix #456, resolves #789)
  • Issue Template: (.github/ISSUE_TEMPLATE/ 디렉토리 아래 마크다운 파일로 작성)

    ## Description
    
    한 줄 요약: [기능, 버그, 질문 등]
    
    디테일한 설명: (사진, 영상 등 첨부 가능)
    어떤 문제가 있는지, 왜 필요한 기능인지 등 상세히 작성합니다.
    
    ## Tasks
    
    - [ ] TODO 1
    - [ ] TODO 2
    - [ ] TODO 3
    
    ## References (선택 사항)
    
    - [참고 자료 텍스트](참고 자료 링크)

GitHub Projects

  • 목적: 이슈와 Pull Request를 칸반 보드나 테이블 형태로 시각화하여 프로젝트 진행 상황을 관리하는 도구입니다.
  • Repo Issue 기반으로 동작하며, commit, pull request 메시지를 통해 자동으로 상태를 업데이트하도록 설정할 수 있습니다.

GitHub Wiki

  • 목적: 프로젝트 관련 문서를 작성하고 관리하는 공간입니다.
  • README.md 외에 더 자세한 설명이 필요한 내용들을 기록합니다.
  • FAQ, 설계 문서, 회의록 (Daily Scrum, Retrospection), 코드 컨벤션, 기술 부채(Technical Issues) 목록 등을 Wiki에 작성할 수 있습니다.
  • 예시: https://github.com/TeamCooks/TwoSpoon/wiki

Pull Request (PR)

  • 목적: 특정 브랜치에 적용된 변경사항을 다른 브랜치에 병합(Merge)하기 전에 코드 리뷰를 요청하고 논의하는 기능입니다.

  • PR Template을 만들어 일관성 있는 요청 내용을 작성하는 것이 좋습니다.

  • PR Template: (.github/PULL_REQUEST_TEMPLATE.md 파일로 작성)

    ## Summary
    
    한 줄로 요약하는 변경사항 설명
    
    디테일한 설명: (사진, 영상 등 자유롭게 추가 가능)
    구현 내용, 해결된 문제, 영향 범위 등을 상세히 작성합니다.
    
    ## Proposed Changes
    
    - 변경사항 1 (close #{issue_num})
    - 변경사항 2 (fixed #{issue_num})
    - 변경사항 3 (resolves #{issue_num})
    (관련 Issue 번호를 언급하여 자동으로 연결되게 합니다.)
    
    ## To Reviewers
    
    Code review 시 특별히 참고/확인해주었으면 하는 사항

Fork 기반 GitHub Flow 협업 전략

오픈 소스 프로젝트나 외부 기여자가 많은 팀에서 흔히 사용하는 협업 워크플로우입니다.

  1. 팀 Repository 생성: 팀 리더/Admin이 메인 Repository를 생성합니다. (보통 Organization 아래 생성)
  2. Issue 생성: 팀원들이나 리더가 필요한 작업(Task, Bug, Feature)을 Issue로 등록하고 담당자를 지정하며 Label, Milestone 등을 설정합니다.
  3. Repository Fork: 작업할 팀원/기여자는 팀 Repository를 자신의 GitHub 계정으로 Fork 합니다. (Repository 페이지 우측 상단 'Fork' 버튼)
  4. Fork된 Repository Clone: 자신의 계정으로 Fork한 Repository를 로컬 컴퓨터로 Clone 합니다.
    $ git clone https://github.com/{my-username}/{repo-name}.git
    $ cd {repo-name}
  5. Upstream 설정: 원본 팀 Repository를 upstream으로 설정하여 최신 변경사항을 쉽게 받아올 수 있도록 합니다.
    $ git remote add upstream https://github.com/{team-username}/{repo-name}.git
    $ git remote -v # 설정 확인
  6. 최신 상태 유지: 작업 시작 전 또는 주기적으로 원본 Repository의 main 브랜치 변경사항을 가져와 내 로컬 main 브랜치에 반영합니다.
    $ git switch main
    $ git pull upstream main # 원본 최신 변경사항 가져오기
    $ git push origin main # 내 Forked Repo에도 반영 (선택 사항이나 권장)
  7. 작업 브랜치 생성 및 작업: main 브랜치에서 작업할 Issue에 해당하는 새로운 브랜치를 생성하고 이동하여 작업을 수행합니다.
    $ git switch -c feat/add-login # 새로운 브랜치 생성 및 이동
    # 코드 작업...
    $ git add .
    $ git commit -m "feat: add login component"
  8. Fork된 Repository로 Push: 작업 브랜치의 커밋들을 내 Forked Repository로 Push 합니다.
    $ git push origin feat/add-login
  9. Pull Request 생성: GitHub 웹사이트에서 Forked Repository의 작업 브랜치와 원본 팀 Repository의 main 브랜치를 비교하는 Pull Request를 생성합니다. Issue 번호를 언급하여 연결합니다.
  10. Code Review: 팀 리더나 다른 팀원들이 PR 내용을 검토하고 피드백을 제공합니다.
  11. 피드백 반영: PR 피드백에 따라 로컬 작업 브랜치에서 추가 작업을 하고 커밋, 푸시합니다. 변경사항은 자동으로 열려있는 PR에 반영됩니다.
  12. Conflict 해결: 만약 원본 main 브랜치에 변경사항이 생겨 Merge Conflict가 발생하면, 로컬에서 git pull upstream main 명령으로 최신 코드를 가져와 충돌을 해결하고 다시 Push 합니다.
  13. PR Merge: Code Review가 완료되고 Approval을 받으면, 팀 리더/Admin이 PR을 원본 Repository의 main 브랜치에 Merge 합니다.
profile
20세기소년

0개의 댓글