Haribo ML, AI, MATH, Algorithm

[git 시리즈 4] 부스러기 긁어먹기

2025-12-27
Haribo
 

현업에서 쓰이는 모든 핵심 명령어와 옵션, 조작 싹다 대가리에 때려박기.

0. 환경 설정 (Configuration)

이거 설정은 그냥 누가 썼다, 누가 했다 이런 용도기에 진짜 자기 이름을 써주는게 맞다. 여태껏 user.name 에다가 내 아이디 박아넣고있었음 엌ㅋㅋ.

핵심 옵션:

  • --global: 현재 사용자의 모든 저장소에 적용. (기본값으로 사용)
  • --local: 현재 작업 중인 저장소에만 적용. (회사/개인 계정 분리 시 사용)
  • --list: 현재 적용된 모든 설정값 출력.
# 1. 정체성 확립 (GitHub 잔디 심기의 필수 조건)
git config --global user.name "Minsu Ha" # 협업할 때는 실명 or 특정가능하도록 써주기
git config --global user.email "gkalstn000@gmail.com"

# 2. 줄바꿈 문자 통일 (CRLF vs LF 이슈 방지)
# Windows는 CRLF(\r\n), Mac/Linux는 LF(\n)를 씀.
# 협업 시 Windows 사용자가 CRLF로 올리면, Mac 사용자의 git diff는 모든 줄이 바뀐 것으로 인식함.
git config --global core.autocrlf input  # Mac/Linux (Commit할 때만 LF로 변환)
# git config --global core.autocrlf true # Windows (Checkout할 때 CRLF, Commit할 때 LF)

# 3. 기본 에디터 설정 (rebase -i 할 때 열리는 창)
git config --global core.editor "vim" # 또는 "code --wait" (VSCode)

# 4. Pull 전략 설정 (충돌 방지)
# pull 할 때 불필요한 Merge Commit 생성을 막고, 항상 Rebase를 시도하도록 설정.
git config --global pull.rebase true

1. 데이터의 이동: The 3-Tree Architecture

영역 (Area) 상태 (status) 설명
Working Directory Modified (빨강) 방금 막 수정한 파일. 아직 Git이 관리 안 함.
Index (Staging Area) Staged (초록) git add로 “이거 커밋할 거야”라고 장바구니에 담은 상태.
HEAD (Repository) Committed git commit으로 영구 저장된 상태. (.git 폴더에 영구저장)

1.1 git add

Working Directory의 변경 사항을 Staging Area로 옮김.

핵심 옵션

  • .: 현재 폴더의 모든 변경 사항(삭제 포함)을 스테이징.
  • -p (Patch Mode): 강력 추천. 파일 전체가 아니라, 변경된 코드 덩어리(Hunk) 단위로 하나씩 보여주며 y/n을 물어봄.
    • 임시파일, 로그 찍은거 등 빼고 로직만 올리고 싶을 때 사용.
  • -u (Update): 새로 생성된 파일(Untracked)은 무시하고, 수정/삭제된 파일만 반영.

1.2 git commit (Snapshot)

Staging Area의 내용을 Repository에 영구 저장

핵심 옵션

  • 옵션 없이: vim으로 이동.
  • -m “msg”: 에디터 없이 인라인으로 메시지 작성.
  • -a (All): git add 단계를 생략하고 Tracked 파일의 변경 사항을 바로 커밋. (비추천: 원치 않는 파일까지 들어갈 위험 있음)
  • --amend: 직전 커밋 수정. (방금 커밋했는데 오타 났거나 파일을 빠뜨렸을 때, 새 커밋을 만들지 않고 덮어씌움)
  • --no-edit: 메시지는 수정하지 않고 내용만 덮어쓰기.
  • --fixup <commit_hash>: 나중에 rebase 할 때 해당 커밋과 합칠 것이라고 마킹. (뒤에서 자세히 설명)

2. Revision Selection (리비전: 과거를 가리키는 문법)

Q: 리비전이 머임?
A: Git에서 특정 커밋(스냅샷)을 지칭하는 모든 방법

기본

  • Full SHA-1: dae86e1950b1277e545cee180551750029cfe735 (40자리 해시)
  • Short SHA-1: dae86e1 (앞 7자리만 써도 유일하면 식별 가능)
  • Ref: main, feature/login, HEAD (포인터 이름)

상대 참조 (Relative Reference)

  • HEAD: 현재 내가 보고 있는 커밋.
  • ^ (Caret): 수평적 부모. (Merge Commit에서 유래)
    • HEAD^: 첫 번째 부모 (Mainline).
    • HEAD^2: 두 번째 부모 (Merge된 Feature 브랜치).
  • ~ (Tilde): 수직적 조상. (역사 거슬러 올라가기)
    • HEAD~1: 바로 전 커밋.
    • HEAD~5: 5단계 전 커밋.

3. 동기화 (Synchronization): Fetch, Pull, Push

3.1 git fetch (정찰)

원격 저장소(Remote)의 최신 데이터를 가져오지만, 내 코드(Working Dir)에는 반영안함.

  • 용도: 남들이 뭐 했는지 확인만 하고 싶을 때.
  • --prune (-p): 원격에서 삭제된 브랜치를 내 목록에서도 정리. (강추)
  • --all: 등록된 모든 원격 저장소에서 가져옴.

3.2 git pull (돌격)

  • fetch + merge (또는 설정에 따라 rebase)를 한방에 수행.
  • --rebase (-r): merge 대신 rebase를 수행하여, 내 커밋들을 최신 원격 커밋 뒤에 붙임. (히스토리가 일자가 됨)

3.3 git push (전송)

  • -u (--set-upstream): 현재 브랜치를 원격 브랜치와 연결. (최초 1회 필수)
  • --force (-f): 절대 금지. 원격 역사를 내 로컬 역사로 덮어버림. 팀원 코드 삭제됨.
  • --force-with-lease: 안전한 강제 푸시. 원격 저장소에 내가 모르는 변경 사항이 있으면 푸시를 거부함. (Rebase 후 필수 사용)
  • --tags: 커밋뿐만 아니라 태그까지 함께 전송.

4. 브랜치와 이동 (Branching & Navigation)

4.1 git branch

  • -a: 로컬과 원격의 모든 브랜치 조회.
  • -d: 머지된 브랜치 안전 삭제.
  • -D: 강제 삭제. (머지 안 된 실험용 브랜치 날릴 때)
  • -m <old> <new>: 브랜치 이름 변경.

4.2 git checkout vs git switch

  • git checkout : 특정 시점으로 시간 여행 (Detached HEAD 상태).
    • 더 디테일한 이동
  • git switch : 브랜치 이동 전용.
    • -c: 브랜치 생성과 동시에 이동.

5. Inspection (검사 및 탐색)

5.1 git status

-s: 짧게 요약해서 보여줌. (M: Modified, ??: Untracked 등)

5.2 git log

  • --oneline: 커밋 해시와 제목만 한 줄로 출력.
  • --graph: 브랜치 분기/병합을 아스키 아트 그래프로 시각화.
  • --p: 각 커밋의 변경 내용(diff)까지 출력.
  • --stat: 변경된 파일명과 줄 수 통계 출력.
  • --author="Minsu Ha": 특정 작성자의 커밋만 필터링.
  • --grep="login": 메시지에 특정 단어가 포함된 커밋 검색.

5.3 git diff

  • git diff: Working Directory와 Staging Area의 차이. (Add 하기 전 확인)
  • git diff --staged: Staging Area와 Repository의 차이. (Commit 하기 전 확인)
  • git diff HEAD~1: 현재와 직전 커밋의 차이.

5.4 git blame <file> (범인 찾기)

파일의 각 줄을 누가, 언제, 왜 수정했는지 보여줌. 코드에 버그가 있을 때 작성자를 찾아가기 위해 사용.

5.5 git bisect (이진 탐색 디버깅)

수많은 커밋 중에서 버그가 발생한 시점을 수학적으로(Binary Search) 찾아냄.

  • git bisect start: 시작.
  • git bisect bad: “지금은 버그가 있음.”
  • git bisect good <commit>: “이때는 버그가 없었음.”
    • -> Git이 중간 지점으로 이동하며 계속 good/bad를 물어봄.

6. Patch Generation (패치 생성 및 이식)

네트워크 없이 코드를 전달하거나, 다른 저장소로 코드를 이식할 때

6.1 git format-patch (생성)

커밋을 이메일 형식의 파일로 추출

  • -1 HEAD: 최신 커밋 1개를 패치로 생성.
  • master..feature: master에는 없는데 feature에만 있는 모든 커밋을 패치로 생성.
  • 결과물: 0001-feat-login.patch 같은 파일이 생김.

6.2 git am (적용)

패치 파일을 읽어서 내 브랜치에 커밋으로 반영. (Apply Mailbox)

  • git am <file.patch>: 패치 적용. 충돌 시 해결 후 --continue.

6.3 git cherry-pick

다른 브랜치의 커밋을 “복사”해서 내 브랜치에 붙여넣기

  • git cherry-pick <commit_hash>: 1개 가져오기.
  • git cherry-pick A..B: A 다음부터 B까지의 범위를 가져오기.
  • -n (--no-commit): 커밋은 안 하고 Staging 상태로만 가져오기.

7. 생존 기술 (Recovery)

7.1 git stash (임시 저장)

  • list: 저장된 스택 목록 확인.
  • show -p: 가장 최근 스택의 변경 내용 확인.
  • drop: 스택에서 삭제.
  • clear: 스택 전체 비우기.

7.2 git reflog (최후의 보루)

Git은 우리가 지운 커밋도 일정 기간(기본 30일) 보관함. (HEAD가 가리켰던 모든 지점을 기록)

  • git reflog: 이동 기록 조회. (예: HEAD@{1}: reset: moving to HEAD~1)
  • 복구법: 실수로 reset --hard를 했다면, reflog에서 사고 치기 전의 해시를 찾아 git reset --hard <hash> 하면 복구됨.

7.3 git fsck (File System Check)

  • --lost-found: 연결 고리가 끊겨서(Dangling) reflog에도 안 보이는 객체들을 찾는다.
    • 진짜 최악의 상황에서 사용. 근데 이정도면 다시 짜는게..;

Similar Posts

Comments