Skip to content

필사 모드: Git 완전 정복: 주니어부터 시니어까지, 실무에서 바로 쓰는 Git 고급 워크플로우

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

들어가며

Git은 모든 개발자의 일상 도구입니다. 하지만 대부분의 개발자가 `git add`, `git commit`, `git push` 정도만 사용하고, Git이 제공하는 강력한 기능의 10%도 활용하지 못합니다. 이 가이드는 주니어 개발자부터 시니어 개발자까지, Git의 내부 구조부터 실무에서 즉시 적용 가능한 고급 워크플로우를 총정리합니다.

코드 리뷰에서 "이 커밋 히스토리 좀 정리해주세요"라는 피드백을 받은 적이 있나요? 머지 충돌이 나면 당황한 적은요? 이 글을 끝까지 읽으면 그런 상황에서 자신 있게 대처할 수 있습니다.

1. Git 내부 구조 이해 — Objects, DAG, 그리고 .git 디렉토리

Git을 진정으로 마스터하려면 내부 동작 원리를 이해해야 합니다. Git은 단순한 버전 관리 도구가 아니라, **content-addressable 파일 시스템** 위에 구축된 정교한 시스템입니다.

1.1 Git의 4가지 객체 (Objects)

Git 내부에는 4가지 핵심 객체가 존재합니다.

**Blob (Binary Large Object):** 파일의 내용을 저장합니다. 파일 이름이나 경로는 포함하지 않고, 순수한 파일 내용만 담습니다.

파일 내용의 해시값 확인

echo "Hello, Git!" | git hash-object --stdin

결과: 예시 af5626b4a114abcb82d63db7c8082c3c4756e51b

실제 저장된 객체 타입 확인

git cat-file -t af5626b

결과: blob

내용 확인

git cat-file -p af5626b

결과: Hello, Git!

**Tree:** 디렉토리 구조를 나타냅니다. Blob과 다른 Tree를 참조하여 파일 시스템의 스냅샷을 구성합니다.

최신 커밋의 트리 확인

git cat-file -p HEAD^{tree}

100644 blob a906cb2a4a904a15... README.md

040000 tree 99f1a6d12cb4b6f1... src

100644 blob 47c6340d6459e058... package.json

**Commit:** 특정 시점의 스냅샷입니다. Tree 객체를 가리키며, 작성자, 커밋 메시지, 부모 커밋 정보를 포함합니다.

커밋 내부 구조 확인

git cat-file -p HEAD

tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0

parent 8bd3ad5e1234567890abcdef1234567890abcdef

author John Doe <john@example.com> 1711100000 +0900

committer John Doe <john@example.com> 1711100000 +0900

#

feat: add user authentication

**Tag:** 특정 커밋에 이름을 붙이는 객체입니다. 릴리스 버전 관리에 사용됩니다.

어노테이티드 태그 생성

git tag -a v1.0.0 -m "Release version 1.0.0"

태그 객체 확인

git cat-file -p v1.0.0

1.2 SHA-1 해싱과 콘텐츠 주소 지정

Git은 모든 객체를 SHA-1 해시로 식별합니다. 동일한 내용은 항상 동일한 해시를 생성하므로, 중복 저장이 자연스럽게 방지됩니다.

동일한 내용 = 동일한 해시

echo "same content" | git hash-object --stdin

echo "same content" | git hash-object --stdin

두 결과가 완전히 동일합니다

이것이 의미하는 바는 중요합니다. 100개의 브랜치에서 같은 파일을 가지고 있더라도, Git은 그 파일을 단 한 번만 저장합니다.

1.3 DAG (Directed Acyclic Graph) — 커밋 그래프

Git의 커밋 히스토리는 DAG(방향 비순환 그래프) 구조입니다. 각 커밋은 부모 커밋을 가리키며, 순환이 없습니다.

A---B---C---D (main)

\

E---F---G (feature)

\

H---I (hotfix)

이 구조를 이해하면 merge, rebase, cherry-pick이 실제로 무엇을 하는지 직관적으로 알 수 있습니다.

그래프 형태로 로그 보기

git log --oneline --graph --all --decorate

더 깔끔한 출력

git log --oneline --graph --all --format="%h %s (%ar)"

1.4 .git 디렉토리 해부

.git/

HEAD # 현재 브랜치를 가리키는 포인터

config # 저장소별 설정

refs/

heads/ # 로컬 브랜치들 (각 파일 = 커밋 해시)

tags/ # 태그들

remotes/ # 원격 브랜치 추적

objects/ # 모든 Git 객체 (blob, tree, commit, tag)

pack/ # 압축된 객체 팩 파일

hooks/ # Git 훅 스크립트

index # 스테이징 영역 (바이너리)

HEAD가 가리키는 곳 확인

cat .git/HEAD

ref: refs/heads/main

main 브랜치가 가리키는 커밋

cat .git/refs/heads/main

a1b2c3d4e5f6...

객체 저장소 크기 확인

git count-objects -vH

2. 브랜칭 전략 비교 — 팀에 맞는 워크플로우 선택하기

2.1 Git Flow

2010년 Vincent Driessen이 제안한 전통적인 브랜칭 모델입니다.

main ─────────────────────────────── (프로덕션)

└── develop ────────────────────── (개발 통합)

│ │

│ feature/login ────────── (기능 개발)

└── release/1.0 ──────────── (릴리스 준비)

└── hotfix/bug-123 ──── (긴급 수정)

**장점:** 명확한 릴리스 관리, 프로덕션 안정성 보장

**단점:** 브랜치가 많아 복잡, 머지 충돌 빈번, CI/CD와 어울리지 않음

Git Flow 초기화 (git-flow 확장)

git flow init

기능 개발 시작

git flow feature start user-auth

기능 개발 완료

git flow feature finish user-auth

2.2 GitHub Flow

GitHub에서 사용하는 단순한 브랜칭 모델입니다.

main ────────────────────────────────

│ │

└── feature ───┘ (PR + 머지)

**규칙:** main은 항상 배포 가능 상태. 기능 브랜치에서 작업 후 PR을 통해 머지.

1. 브랜치 생성

git checkout -b feature/add-search

2. 작업 및 커밋

git add .

git commit -m "feat: add search functionality"

3. 푸시

git push -u origin feature/add-search

4. PR 생성 (GitHub CLI)

gh pr create --title "Add search functionality" --body "..."

5. 리뷰 후 머지

gh pr merge --squash

2.3 Trunk-Based Development (트렁크 기반 개발)

Google, Meta 등 대규모 팀에서 사용하는 방식입니다. 모든 개발자가 main(trunk)에 직접 또는 매우 짧은 수명의 브랜치를 통해 자주 통합합니다.

main ──A──B──C──D──E──F──G──H──I──

\─/ \─/

(1-2일) (1-2일)

**핵심 원칙:**

- 브랜치 수명은 최대 1~2일

- 하루에 여러 번 main에 통합

- Feature Flag로 미완성 기능 관리

- 강력한 CI/CD 파이프라인 필수

2.4 전략 비교표

| 항목 | Git Flow | GitHub Flow | Trunk-Based |

| ------------ | ----------------- | ------------ | -------------- |

| 복잡도 | 높음 | 낮음 | 중간 |

| 브랜치 수명 | 길다 (주~월) | 중간 (일~주) | 짧다 (시간~일) |

| 릴리스 주기 | 정기 릴리스 | 수시 배포 | 지속 배포 |

| 팀 규모 | 10명 이상 | 2~15명 | 제한 없음 |

| CI/CD 의존도 | 낮음 | 중간 | 높음 |

| 추천 상황 | 모바일 앱, 패키지 | SaaS, 웹앱 | 대규모 조직 |

2.5 브랜치 명명 규칙

기능 개발

feature/JIRA-123-add-login

feature/user-profile-page

버그 수정

bugfix/JIRA-456-fix-null-pointer

fix/login-redirect-loop

핫픽스

hotfix/security-patch-xss

hotfix/v1.2.1

릴리스

release/1.0.0

release/2026-q1

실험/개인

experiment/new-search-algo

chore/update-dependencies

3. 리베이스 마스터 클래스

3.1 Rebase vs Merge — 언제 무엇을 쓸까

**Merge:** 두 브랜치의 히스토리를 보존하면서 합칩니다.

git checkout main

git merge feature/login

머지 커밋이 생성됨

A---B---C---D---M (main, 머지 커밋 M)

\ /

E---F---G (feature)

**Rebase:** 커밋을 다른 베이스 위에 재적용합니다.

git checkout feature/login

git rebase main

feature의 커밋이 main 위에 재적용됨

A---B---C---D (main)

\

E'---F'---G' (feature, 재적용됨)

3.2 Interactive Rebase (대화형 리베이스) 완전 가이드

최근 5개 커밋을 대화형으로 편집

git rebase -i HEAD~5

에디터가 열리면 다음과 같은 화면이 나타납니다.

pick a1b2c3d feat: add user model

pick d4e5f6g fix: typo in user model

pick h7i8j9k feat: add user controller

pick l0m1n2o WIP: debugging

pick p3q4r5s feat: add user routes

**사용 가능한 명령어:**

| 명령 | 약자 | 설명 |

| ------ | ---- | ------------------------------ |

| pick | p | 커밋을 그대로 사용 |

| reword | r | 커밋 메시지만 변경 |

| edit | e | 커밋을 수정 (파일 변경 가능) |

| squash | s | 이전 커밋과 합치고 메시지 편집 |

| fixup | f | 이전 커밋과 합치고 메시지 버림 |

| drop | d | 커밋 삭제 |

**실전 예시 — 지저분한 히스토리 정리:**

pick a1b2c3d feat: add user model

fixup d4e5f6g fix: typo in user model

pick h7i8j9k feat: add user controller

drop l0m1n2o WIP: debugging

pick p3q4r5s feat: add user routes

결과: 5개 커밋이 깔끔한 3개 커밋으로 정리됩니다.

3.3 Autosquash 워크플로우

`fixup!` 접두사를 사용하면 자동으로 정리됩니다.

원래 커밋

git commit -m "feat: add user model"

나중에 수정이 필요할 때

git commit --fixup HEAD

또는 특정 커밋 지정

git commit --fixup a1b2c3d

자동으로 정리

git rebase -i --autosquash main

3.4 리베이스의 황금 규칙

**절대 공유된 브랜치(main, develop)를 리베이스하지 마세요.** 리베이스는 커밋 해시를 변경하므로, 다른 사람들의 로컬 저장소와 충돌이 발생합니다.

안전한 리베이스 (개인 feature 브랜치)

git checkout feature/my-task

git rebase main

위험한 리베이스 (절대 하지 마세요)

git checkout main

git rebase feature/something # 금지!

4. 실무 시나리오 20개 — 문제 발생 시 해결법

시나리오 1: 커밋 메시지를 잘못 작성했을 때

방금 한 커밋의 메시지 수정 (아직 푸시 안 함)

git commit --amend -m "feat: add user authentication"

에디터에서 메시지 수정

git commit --amend

시나리오 2: 잘못된 브랜치에 커밋했을 때

상황: main에 커밋해야 할 것을 feature 브랜치에 했다

방법 1: cherry-pick

git checkout main

git cherry-pick abc1234

git checkout feature/wrong-branch

git reset --hard HEAD~1

방법 2: stash 활용

git reset --soft HEAD~1

git stash

git checkout correct-branch

git stash pop

git commit -m "correct commit message"

시나리오 3: 푸시 후 되돌리기 — revert vs reset

안전한 방법: revert (새 커밋으로 되돌림, 히스토리 보존)

git revert abc1234

git push

위험한 방법: reset + force push (히스토리 변경)

git reset --hard HEAD~1

git push --force-with-lease

force-with-lease는 다른 사람의 커밋을 덮어쓰지 않도록 보호

**revert vs reset 비교:**

| 항목 | revert | reset |

| ----------- | -------------------- | ----------------- |

| 히스토리 | 보존 (새 커밋 추가) | 변경 (커밋 삭제) |

| 안전성 | 안전 | 위험 |

| 공유 브랜치 | 사용 가능 | 사용 금지 |

| 되돌리기 | revert의 revert 가능 | reflog으로만 복구 |

시나리오 4: 머지 충돌 해결 전략

충돌 발생 시

git merge feature/login

CONFLICT (content): Merge conflict in src/auth.js

충돌 파일 확인

git status

충돌 마커 구조

<<<<<<< HEAD

현재 브랜치의 코드

=======

머지하려는 브랜치의 코드

>>>>>>> feature/login

수동 해결 후

git add src/auth.js

git commit -m "resolve merge conflict in auth module"

**머지 충돌 최소화 전략:**

1. main을 자주 가져와서 동기화

git fetch origin

git rebase origin/main

2. 작은 단위로 자주 커밋하고 머지

3. 팀 내 파일 소유권 명확히 하기 (CODEOWNERS)

4. 머지 도구 설정

git config --global merge.tool vimdiff

git mergetool

시나리오 5: 특정 커밋으로 버그 추적 — git bisect

bisect 시작

git bisect start

현재(버그 있음)를 bad로 표시

git bisect bad

버그 없던 커밋을 good으로 표시

git bisect good v1.0.0

Git이 중간 커밋을 체크아웃 — 테스트 후 판단

git bisect good # 또는 git bisect bad

반복하면 버그를 유발한 정확한 커밋을 찾음

결과: abc1234 is the first bad commit

bisect 종료

git bisect reset

**자동 bisect (테스트 스크립트 활용):**

테스트 스크립트가 실패하면 bad, 성공하면 good

git bisect start HEAD v1.0.0

git bisect run npm test

자동으로 버그 커밋을 찾아줍니다!

시나리오 6: 대용량 파일을 실수로 커밋했을 때

방법 1: git-filter-repo (추천)

pip install git-filter-repo

git filter-repo --path large-file.zip --invert-paths

방법 2: BFG Repo-Cleaner

java -jar bfg.jar --delete-files large-file.zip

git reflog expire --expire=now --all

git gc --prune=now --aggressive

예방: .gitignore 설정

echo "*.zip" >> .gitignore

echo "*.tar.gz" >> .gitignore

echo "node_modules/" >> .gitignore

시나리오 7: 파일의 일부만 스테이징 — git add -p

파일의 변경사항을 hunk 단위로 선택적 스테이징

git add -p src/utils.js

각 hunk에 대해:

y - 이 hunk 스테이징

n - 이 hunk 건너뛰기

s - 더 작은 hunk로 분할

e - 수동으로 편집

q - 종료

시나리오 8: 작업 중 긴급 핫픽스 — stash + worktree

방법 1: stash

git stash push -m "WIP: feature work"

git checkout main

git checkout -b hotfix/critical-bug

핫픽스 작업...

git checkout feature/my-work

git stash pop

방법 2: worktree (더 나은 방법!)

git worktree add ../hotfix-workspace main

cd ../hotfix-workspace

git checkout -b hotfix/critical-bug

핫픽스 작업...

cd ../main-workspace

git worktree remove ../hotfix-workspace

시나리오 9: 여러 커밋을 하나로 합치기

방법 1: interactive rebase

git rebase -i HEAD~4

첫 번째를 pick, 나머지를 squash로 변경

방법 2: soft reset

git reset --soft HEAD~4

git commit -m "feat: complete user authentication"

방법 3: merge --squash

git checkout main

git merge --squash feature/user-auth

git commit -m "feat: add user authentication system"

시나리오 10: 서브모듈 관리

서브모듈 추가

git submodule add https://github.com/org/shared-lib.git libs/shared

클론 시 서브모듈 포함

git clone --recurse-submodules https://github.com/org/project.git

서브모듈 업데이트

git submodule update --remote --merge

모든 서브모듈에 명령 실행

git submodule foreach 'git checkout main && git pull'

시나리오 11: 삭제된 브랜치 복구

reflog에서 삭제된 브랜치의 마지막 커밋 찾기

git reflog

abc1234 HEAD@{5}: checkout: moving from deleted-branch to main

브랜치 복구

git checkout -b recovered-branch abc1234

시나리오 12: 특정 파일만 다른 브랜치에서 가져오기

main 브랜치의 특정 파일을 현재 브랜치로 가져오기

git checkout main -- src/config.js

특정 커밋의 파일 가져오기

git checkout abc1234 -- src/config.js

시나리오 13: 커밋 날짜 변경

마지막 커밋의 날짜를 현재 시간으로 변경

GIT_COMMITTER_DATE="$(date)" git commit --amend --date="$(date)"

특정 날짜로 변경 (리베이스 중)

GIT_COMMITTER_DATE="2026-03-22T10:00:00" git commit --amend --date="2026-03-22T10:00:00"

시나리오 14: Git blame으로 코드 추적

파일의 각 줄을 누가 마지막으로 수정했는지 확인

git blame src/auth.js

특정 줄 범위만 확인

git blame -L 10,20 src/auth.js

공백 변경 무시

git blame -w src/auth.js

코드 이동도 추적

git blame -M src/auth.js

git blame -C src/auth.js

시나리오 15: git log 고급 활용

특정 파일의 변경 이력

git log --follow -p -- src/auth.js

특정 문자열이 추가/삭제된 커밋 찾기 (pickaxe)

git log -S "API_KEY" --oneline

특정 저자의 커밋만

git log --author="John" --oneline --since="2026-01-01"

통계 정보 포함

git log --stat --oneline -10

커밋 간 diff

git log -p --oneline -3

시나리오 16: 원격 저장소 관리

여러 원격 저장소 추가

git remote add upstream https://github.com/original/repo.git

git remote add deploy git@deploy-server:app.git

upstream 동기화 (포크 프로젝트)

git fetch upstream

git rebase upstream/main

원격 브랜치 정리

git remote prune origin

git fetch --prune

시나리오 17: Git 태그로 릴리스 관리

어노테이티드 태그 생성

git tag -a v2.0.0 -m "Release 2.0.0: new payment system"

특정 커밋에 태그

git tag -a v1.5.0 abc1234 -m "Hotfix release"

태그 푸시

git push origin v2.0.0

git push origin --tags

태그 삭제

git tag -d v2.0.0-beta

git push origin --delete v2.0.0-beta

시나리오 18: Git hooks로 자동화

.husky/pre-commit

#!/bin/sh

npx lint-staged

.husky/commit-msg

#!/bin/sh

npx commitlint --edit "$1"

.husky/pre-push

#!/bin/sh

npm test

시나리오 19: 패치 파일 생성 및 적용

패치 생성

git diff > my-changes.patch

git format-patch -3 # 최근 3개 커밋을 패치 파일로

패치 적용

git apply my-changes.patch

git am *.patch # format-patch로 생성된 패치 적용

시나리오 20: git reflog — 최후의 보루

reflog 확인 (HEAD의 이동 기록)

git reflog

실수로 reset --hard 한 경우 복구

git reflog

abc1234 HEAD@{2}: commit: important work

git reset --hard abc1234

실수로 삭제한 stash 복구

git fsck --unreachable | grep commit

git stash apply abc1234

5. Conventional Commits + Semantic Versioning

5.1 Conventional Commits 형식

type(scope): description

[optional body]

[optional footer(s)]

**타입 목록:**

| 타입 | 설명 | 예시 |

| -------- | ----------------------- | --------------------------------- |

| feat | 새로운 기능 | feat: add login page |

| fix | 버그 수정 | fix: resolve null pointer in auth |

| docs | 문서 변경 | docs: update API documentation |

| style | 코드 스타일 (포맷팅 등) | style: fix indentation |

| refactor | 리팩토링 | refactor: extract auth middleware |

| perf | 성능 개선 | perf: optimize database queries |

| test | 테스트 추가/수정 | test: add unit tests for auth |

| build | 빌드 시스템 변경 | build: update webpack config |

| ci | CI 설정 변경 | ci: add GitHub Actions workflow |

| chore | 기타 잡무 | chore: update dependencies |

**Breaking Change 표기:**

feat(api)!: change authentication endpoint

BREAKING CHANGE: /auth/login is now /api/v2/auth/login

5.2 Commitlint + Husky 설정

패키지 설치

npm install -D @commitlint/cli @commitlint/config-conventional husky

commitlint 설정

echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js

Husky 초기화

npx husky init

echo 'npx commitlint --edit "$1"' > .husky/commit-msg

5.3 자동 Changelog 생성

conventional-changelog 설치

npm install -D conventional-changelog-cli

CHANGELOG.md 생성

npx conventional-changelog -p angular -i CHANGELOG.md -s

package.json에 스크립트 추가

{

"scripts": {

"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",

"release": "standard-version"

}

}

5.4 Semantic Release — 완전 자동화

npm install -D semantic-release

{

"release": {

"branches": ["main"],

"plugins": [

"@semantic-release/commit-analyzer",

"@semantic-release/release-notes-generator",

"@semantic-release/changelog",

"@semantic-release/npm",

"@semantic-release/github",

"@semantic-release/git"

]

}

}

커밋 타입에 따라 자동으로 버전이 결정됩니다:

- `fix:` -> PATCH (1.0.0 -> 1.0.1)

- `feat:` -> MINOR (1.0.0 -> 1.1.0)

- `BREAKING CHANGE` -> MAJOR (1.0.0 -> 2.0.0)

6. GitHub Actions CI/CD

6.1 기본 워크플로우

name: CI Pipeline

on:

push:

branches: [main]

pull_request:

branches: [main]

jobs:

test:

runs-on: ubuntu-latest

strategy:

matrix:

node-version: [18, 20, 22]

steps:

- uses: actions/checkout@v4

- name: Use Node.js

uses: actions/setup-node@v4

with:

node-version: ${{ matrix.node-version }}

cache: 'npm'

- run: npm ci

- run: npm run lint

- run: npm test

- run: npm run build

6.2 PR 자동 검사 워크플로우

name: PR Checks

on:

pull_request:

types: [opened, synchronize, reopened]

jobs:

lint-and-test:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v4

- name: Setup Node

uses: actions/setup-node@v4

with:

node-version: 20

cache: 'npm'

- run: npm ci

- name: Lint

run: npm run lint

- name: Type Check

run: npx tsc --noEmit

- name: Unit Tests

run: npm test -- --coverage

- name: Build

run: npm run build

- name: Upload coverage

uses: codecov/codecov-action@v4

with:

file: ./coverage/lcov.info

6.3 자동 라벨링

name: Auto Label

on:

pull_request:

types: [opened, edited]

jobs:

label:

runs-on: ubuntu-latest

steps:

- uses: actions/labeler@v5

with:

repo-token: ${{ secrets.GITHUB_TOKEN }}

.github/labeler.yml

frontend:

- changed-files:

- any-glob-to-any-file: 'src/components/**'

backend:

- changed-files:

- any-glob-to-any-file: 'src/api/**'

documentation:

- changed-files:

- any-glob-to-any-file: 'docs/**'

tests:

- changed-files:

- any-glob-to-any-file: '**/*.test.*'

6.4 Dependabot 설정

.github/dependabot.yml

version: 2

updates:

- package-ecosystem: 'npm'

directory: '/'

schedule:

interval: 'weekly'

day: 'monday'

open-pull-requests-limit: 10

labels:

- 'dependencies'

groups:

dev-dependencies:

dependency-type: 'development'

production-dependencies:

dependency-type: 'production'

- package-ecosystem: 'github-actions'

directory: '/'

schedule:

interval: 'weekly'

6.5 배포 워크플로우

name: Deploy

on:

push:

tags:

- 'v*'

jobs:

deploy:

runs-on: ubuntu-latest

environment: production

steps:

- uses: actions/checkout@v4

- name: Setup Node

uses: actions/setup-node@v4

with:

node-version: 20

- run: npm ci

- run: npm run build

- name: Deploy to Production

run: |

echo "Deploying version $GITHUB_REF_NAME"

실제 배포 명령어

7. Monorepo 전략

7.1 Monorepo vs Multirepo

| 항목 | Monorepo | Multirepo |

| ----------- | ----------------------- | ---------------- |

| 코드 공유 | 쉬움 | 패키지 발행 필요 |

| 의존성 관리 | 통합 관리 | 개별 관리 |

| CI/CD | 복잡 (선택적 빌드) | 단순 (저장소별) |

| 코드 리뷰 | 전체 맥락 파악 가능 | 저장소별로 분산 |

| 권한 관리 | 복잡 | 저장소별 설정 |

| 대표 사례 | Google, Meta, Microsoft | Netflix, Spotify |

7.2 도구 비교 — Nx vs Turborepo vs Lerna

Nx 초기화

npx create-nx-workspace@latest my-workspace

Turborepo 초기화

npx create-turbo@latest

프로젝트 구조 예시

my-monorepo/

apps/

web/ # Next.js 웹앱

mobile/ # React Native 앱

api/ # Express API 서버

packages/

ui/ # 공유 UI 컴포넌트

utils/ # 공유 유틸리티

config/ # 공유 설정

turbo.json

package.json

7.3 CODEOWNERS 설정

.github/CODEOWNERS

전체 프로젝트 기본 리뷰어

* @team-lead

프론트엔드

/apps/web/ @frontend-team

/packages/ui/ @frontend-team

백엔드

/apps/api/ @backend-team

/packages/utils/ @backend-team

DevOps

/.github/ @devops-team

/docker/ @devops-team

*.yml @devops-team

7.4 선택적 빌드와 테스트

{

"pipeline": {

"build": {

"dependsOn": ["^build"],

"outputs": ["dist/**"]

},

"test": {

"dependsOn": ["build"]

},

"lint": {}

}

}

변경된 패키지만 빌드

npx turbo run build --filter=...[HEAD^1]

특정 앱만 빌드

npx turbo run build --filter=web

의존성 포함 빌드

npx turbo run build --filter=web...

8. Git 성능 최적화

8.1 Shallow Clone (얕은 클론)

최근 1개 커밋만 클론 (CI/CD에서 유용)

git clone --depth 1 https://github.com/org/repo.git

나중에 전체 히스토리가 필요하면

git fetch --unshallow

8.2 Partial Clone (부분 클론)

Blob 없이 클론 (필요할 때 다운로드)

git clone --filter=blob:none https://github.com/org/repo.git

Tree도 제외 (가장 빠른 클론)

git clone --filter=tree:0 https://github.com/org/repo.git

8.3 Sparse Checkout (희소 체크아웃)

sparse checkout 활성화

git sparse-checkout init --cone

특정 디렉토리만 체크아웃

git sparse-checkout set apps/web packages/ui

디렉토리 추가

git sparse-checkout add apps/api

설정 확인

git sparse-checkout list

8.4 Git LFS (Large File Storage)

Git LFS 설치 및 초기화

git lfs install

대용량 파일 추적

git lfs track "*.psd"

git lfs track "*.zip"

git lfs track "assets/videos/*"

.gitattributes 확인

cat .gitattributes

*.psd filter=lfs diff=lfs merge=lfs -text

LFS 상태 확인

git lfs ls-files

git lfs status

8.5 Git Maintenance (자동 유지보수)

자동 유지보수 활성화

git maintenance start

수동으로 가비지 컬렉션

git gc --aggressive

객체 압축 상태 확인

git count-objects -vH

불필요한 참조 정리

git remote prune origin

git reflog expire --expire=30.days

8.6 Scalar — 대규모 저장소 관리 (Microsoft)

Scalar 설치 (Git 2.38+에 포함)

scalar register

또는 새로 클론

scalar clone https://github.com/org/massive-repo.git

Scalar가 자동으로 설정하는 것들:

- Partial clone

- Sparse checkout

- Background maintenance

- Filesystem monitor

- Commit graph

9. AI + Git (2025~2026)

9.1 AI 커밋 메시지 생성

Claude Code에서 자동 커밋 메시지 생성

claude commit

GitHub Copilot CLI

gh copilot suggest "write a commit message for these changes"

aicommits 도구

npm install -g aicommits

aicommits

9.2 AI 코드 리뷰

GitHub Copilot for Pull Requests는 PR을 자동으로 분석하여 리뷰 코멘트를 생성합니다. 코드의 잠재적 버그, 성능 이슈, 보안 취약점을 찾아줍니다.

GitHub Copilot 자동 리뷰 활성화 (저장소 설정에서)

Settings > Code review > Copilot code review > Enable

9.3 Claude Code와 Git 워크플로우

Claude Code는 Git 작업을 직접 도와줍니다.

변경사항 리뷰 요청

claude "review my staged changes"

커밋 메시지 작성

claude "write a conventional commit message for my changes"

PR 설명 생성

claude "write a PR description for the current branch"

머지 충돌 해결

claude "help me resolve the merge conflicts in src/auth.js"

9.4 자동 PR 설명 생성

name: Auto PR Description

on:

pull_request:

types: [opened]

jobs:

describe:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v4

with:

fetch-depth: 0

- name: Generate PR description

uses: anthropics/claude-code-action@v1

with:

prompt: |

Analyze the diff of this PR and generate a clear description

including what changed, why, and any risks.

실력 점검 퀴즈

퀴즈 1: Git 객체

**A: Tree 객체에 저장됩니다.**

Blob은 파일의 순수 내용만 저장하며, 파일 이름과 경로 정보는 Tree 객체가 관리합니다. 이 설계 덕분에 파일 이름이 바뀌어도 내용이 같으면 같은 Blob을 재사용할 수 있습니다.

Tree 객체에서 파일 이름 확인

git cat-file -p HEAD^{tree}

100644 blob a906cb... README.md <-- 파일 이름은 Tree에!

퀴즈 2: Rebase 안전성

**A: B가 안전합니다.**

리베이스의 황금 규칙은 "공유된 브랜치를 리베이스하지 마라"입니다. main은 공유 브랜치이므로 main 위에서 리베이스하면 안 됩니다. 반면 feature는 개인 브랜치이므로 main의 최신 커밋 위에 feature의 커밋을 재적용하는 것은 안전합니다.

퀴즈 3: Reset 모드

**A:**

- `--soft`: HEAD만 이동. 스테이징 영역과 작업 디렉토리는 그대로. 커밋만 취소하고 싶을 때.

- `--mixed` (기본값): HEAD 이동 + 스테이징 영역 초기화. 작업 디렉토리는 그대로. 커밋과 스테이징을 취소할 때.

- `--hard`: HEAD 이동 + 스테이징 영역 + 작업 디렉토리 모두 초기화. 모든 변경사항 버릴 때. (위험!)

예시: 최근 3개 커밋을 취소하되 코드는 유지

git reset --soft HEAD~3

이제 변경사항이 스테이징된 상태로 남아있음

퀴즈 4: Cherry-pick 충돌

**A:** merge 충돌과 동일한 방식으로 해결합니다.

git cherry-pick abc1234

CONFLICT 발생

1. 충돌 파일 수정

2. 스테이징

git add resolved-file.js

3. cherry-pick 계속

git cherry-pick --continue

또는 cherry-pick 취소

git cherry-pick --abort

퀴즈 5: Monorepo에서의 선택적 CI

**A: 의존성에 따라 다릅니다.**

프론트엔드가 백엔드 패키지에 의존하지 않는다면, 백엔드 테스트를 돌릴 필요가 없습니다. 이것이 Nx나 Turborepo 같은 도구가 제공하는 "영향 분석(affected analysis)"의 핵심입니다.

Nx: 변경에 영향받는 프로젝트만 테스트

npx nx affected --target=test

Turborepo: 변경된 패키지와 의존 패키지만 빌드

npx turbo run build --filter=...[HEAD^1]

하지만 공유 패키지(utils, config 등)가 변경되었다면, 그 패키지에 의존하는 모든 프로젝트의 테스트를 돌려야 합니다.

참고 자료

공식 문서

1. [Git 공식 문서](https://git-scm.com/doc) — 가장 정확한 레퍼런스

2. [GitHub Docs](https://docs.github.com) — GitHub 기능 가이드

3. [Pro Git Book (한국어)](https://git-scm.com/book/ko/v2) — 무료 온라인 서적

브랜칭 전략

4. [Trunk Based Development](https://trunkbaseddevelopment.com/) — TBD 공식 사이트

5. [GitHub Flow Guide](https://docs.github.com/en/get-started/using-github/github-flow)

6. [A successful Git branching model](https://nvie.com/posts/a-successful-git-branching-model/) — Git Flow 원문

CI/CD

7. [GitHub Actions 공식 문서](https://docs.github.com/en/actions)

8. [Semantic Release](https://semantic-release.gitbook.io/) — 자동 버전 관리

9. [Conventional Commits](https://www.conventionalcommits.org/) — 커밋 규약

Monorepo

10. [Nx 공식 문서](https://nx.dev/)

11. [Turborepo 공식 문서](https://turbo.build/repo)

12. [Monorepo Tools](https://monorepo.tools/) — 도구 비교

성능

13. [Git LFS](https://git-lfs.com/) — 대용량 파일 관리

14. [Scalar](https://github.com/microsoft/scalar) — 대규모 저장소

15. [git-filter-repo](https://github.com/newren/git-filter-repo) — 히스토리 정리

심화

16. [Oh Shit, Git!?!](https://ohshitgit.com/) — Git 실수 복구 가이드

17. [Learn Git Branching](https://learngitbranching.js.org/) — 시각적 Git 학습

18. [Git Internals (PDF)](https://github.com/pluralsight/git-internals-pdf) — Git 내부 구조

마무리

Git은 단순한 도구가 아니라 개발 문화를 형성하는 핵심 인프라입니다. 깔끔한 커밋 히스토리는 팀의 협업 능력을 반영하고, 효과적인 브랜칭 전략은 배포 안정성을 결정합니다.

이 글에서 다룬 내용을 한 번에 모두 익힐 필요는 없습니다. 먼저 일상적으로 사용하는 명령어의 동작 원리를 이해하고, 점차 고급 기법을 적용해 보세요. 특히 interactive rebase와 bisect는 한번 익히면 생산성이 크게 올라가는 도구입니다.

기억하세요: **좋은 커밋 히스토리는 미래의 자신과 동료에게 보내는 편지입니다.** 오늘부터 Conventional Commits를 시작해 보는 것은 어떨까요?

현재 단락 (1/543)

Git은 모든 개발자의 일상 도구입니다. 하지만 대부분의 개발자가 `git add`, `git commit`, `git push` 정도만 사용하고, Git이 제공하는 강력한 기능의...

작성 글자: 0원문 글자: 19,397작성 단락: 0/543