💡 Key Takeaways
- The 3 AM Production Crisis That Changed How I Think About Git
- The Foundation: Commands You'll Use Every Single Day
- Branching: Your Parallel Universe Toolkit
- Time Travel: Viewing and Navigating History
Git에 대한 내 생각을 바꾼 3 AM의 생산 위기
우리의 전체 배포 파이프라인이 3 AM에 고장 났던 밤을 나는 절대 잊지 못할 것이다. 나는 핀테크 스타트업의 수석 DevOps 엔지니어로, 경력 5년 차였으며, 누군가 메인에 강제 푸시를 해서 4개의 다른 팀의 3일간의 작업을 삭제했다는 이유로 페이지가 왔다. 초초해진 손으로 터미널을 바라보며 매초가 중요하다는 것을 알았다—규제 기한, 화가 난 이해관계자들, 그리고 나의 수리를 기다리는 지친 개발자 팀이 있었다.
💡 주요 내용
- Git에 대한 내 생각을 바꾼 3 AM의 생산 위기
- 기초: 매일 사용하는 명령어
- 가지치기: 나의 평행 우주 도구 키트
- 시간 여행: 역사 보기 및 탐색하기
그때 나는 중요한 무언가를 깨달았다: 나는 Git을 5년 동안 사용했지만, 진정으로 알던 명령어는 약 20개뿐이었다. 나머지는 잡음이었다. Git 문서에는 160개 이상의 명령어가 나열되어 있지만, 그 위기 순간에 나는 몇 천 번이나 사용했던 동일한 도구 몇 개를 찾았다. 그리고 당신은 알다시피? 그것들은 충분했다. 그날 밤 우리를 구해주었다.
그 이후로 나는 세 개의 회사에서 200명 이상의 개발자와 함께 일했고, 수없이 많은 코드 리뷰를 진행했으며, 셀 수 없이 많은 저장소를 구조했다. 나는 지난 2년 동안 실제 Git 사용을 쉘 기록 분석을 통해 추적했고, 그 데이터는 놀라웠다: 내 Git 상호작용의 94%는 단 20개의 명령어뿐이었다. 나머지 6%는 분기마다 한 번씩 사용할 수 있는 수십 개의 생소한 작업 사이에 분배되었다.
이 기사는 당신이 북마크하고 결코 읽지 않을 또 다른 포괄적인 Git 참고서가 아니다. 이는 당신의 일상 작업의 99%를 처리할 수 있는 전투 테스트와 생산 검증이 된 명령어 목록이다. 나는 각 명령어를 사용하는 방법, 실제로 중요하지 않은 플래그들, 그리고 수백 번의 병합 충돌과 배포 비상 상황 속에서도 나를 제정신으로 유지해준 사고 모델들을 정확하게 보여줄 것이다.
기초: 매일 사용하는 명령어
가장 기본적인 것부터 시작하자—내 손가락이 무의식적으로 입력하는 명령어. 이 다섯 개의 명령어는 모든 Git 워크플로의 중추를 형성한다. 다른 것을 마스터하지 않더라도, 이 명령어들을 마스터하라.
내 팀의 2년간의 쉘 기록을 분석한 결과, 직관에 반하는 것을 발견했다: Git 명령어를 덜 아는 개발자들이 종종 더 생산적이었다. 그들은 기본적인 20개를 마스터하였고, 생각 없이 실행할 수 있었으며, 반면 매뉴얼 전체를 암기한 사람들은 중요한 순간에 비슷한 옵션 사이에서 귀중한 시간을 허비했다.
git status는 나의 끊임없는 동반자이다. 나는 하루에 아마 50번은 이 명령어를 실행하며, 과장하지 않는다. 커밋 전, 풀 이후, 또는 일어나는 일에 혼란스러울 때마다—git status가 첫 번째 행동이다. 이 명령어는 어떤 파일이 스테이징 되었고, 어떤 파일이 수정되었지만 스테이징 되지 않았으며, 어떤 파일이 추적되지 않는지를 보여준다. 출력은 색상이 코딩되어 있어 매우 읽기 쉽다. 나는 주니어 개발자들이 git status를 실행하지 않았더라면 즉시 명백했을 문제로 몇 시간 동안 고군분투하는 모습을 보았다.
내 워크플로는 이렇다: 나는 너무 자주 git status를 입력해서 쉘 구성에서 "gs"로 별칭을 부여했다. 내가 맥락을 전환하거나 회의에서 돌아올 때마다, git status는 내가 무엇을 작업하고 있었는지를 기억하는 방법이다. 현재 상태에 대한 책갈피와 같다.
git add는 커밋을 위해 변경 사항을 스테이징하는 방법이다. 가장 일반적인 패턴은 git add .으로, 이는 현재 디렉토리의 모든 것을 스테이징하지만, 나는 실제로 이를 맹목적으로 사용하는 것을 권장하지 않는다. 대신, 나는 커밋의 약 60%를 위해 git add -p (패치 모드)를 사용한다. 이는 각 변경 사항을 상호작용적으로 검토하고 원하는 덩어리만 스테이징할 수 있게 해준다. 느려지는 건 사실이지만, 나는 더 이상 커밋하지 않았을 debug 코드, API 키 및 부끄러운 console.log 문을 몇 번이나 저지르지 않게 되었다.
빠른 작업을 위해 git add filename은 특정 파일을 스테이징한다. 나는 내가 커밋하는 것이 확실할 때 이 방법을 사용한다. 여기서의 핵심 통찰은 스테이징이 커밋과 별개라는 것이다—파일을 점진적으로 스테이징하고, git status로 검토한 다음, 준비가 되었을 때 커밋할 수 있다.
git commit은 스테이징된 변경 사항의 스냅샷을 생성한다. 나는 작은, 명백한 변경 사항에 대해 git commit -m "message"를 사용하지만, 그 어떤 중요한 사항에 대해서는 그냥 git commit을 입력하여 내 편집기를 열도록 한다. 이는 내가 적절한 커밋 메시지를 제목과 본문을 포함하여 작성하게 만든다. 좋은 커밋 메시지는 미래의 나를 위한 문서이다. 나는 변경 사항이 왜 행해졌는지를 이해하기 위해 git 기록을 살펴보는 데 무수한 시간을 보냈으며, 상세한 커밋 메시지는 금과 같은 가치를 지닌다.
내 커밋 메시지 템플릿: 첫 번째 줄은 간결한 요약(50자 이하), 그 다음 빈 줄, 그리고 무엇이 변경되었고 왜 변경되었는지에 대한 상세한 설명. 여기서 "왜"가 중요하다—diff는 무엇이 변경되었는지를 보여주지만, 그 이유는 오직 당신만이 설명할 수 있다.
git push는 당신의 커밋을 원격 저장소로 보낸다. 대부분의 경우, git push가 전부이다. 만약 새로운 브랜치를 처음으로 푸시하는 경우, 스위칭을 설정하기 위해 git push -u origin branch-name이 필요하다. -u 플래그(단축어는 --set-upstream)는 이 브랜치에서의 향후 푸시와 풀 시 원격 및 브랜치 이름을 지정할 필요가 없음을 의미한다.
알아야 할 중요한 플래그 하나: git push --force-with-lease. 절대적으로 원격 기록을 덮어쓰고 싶은 경우가 아니고서는 git push --force를 사용하지 마라. --force-with-lease 변형은 안전하다. 왜냐하면 누군가가 당신이 로컬에 가지고 있지 않은 커밋을 푸시한 경우 실패하기 때문이다. 나는 --force가 전체 팀의 작업을 말아먹는 것을 보았다. 그런 사람이 되지 마라.
git pull은 원격에서 변경 사항을 가져와 현재 브랜치에 병합한다. 나는 매일 아침 작업을 시작하기 전에 매번 푸시 전에 이 명령어를 실행한다. 기본 동작은 대부분의 경우에 괜찮지만, 나는 불필요한 병합 커밋을 피하여 역사를 더 깔끔하게 유지하기 위해 git pull --rebase를 선호한다. 이것을 git config --global pull.rebase true로 기본값으로 설정했다.
가지치기: 나의 평행 우주 도구 키트
브랜치는 Git의 진정한 힘이 있는 곳이다. 브랜치는 주 코드베이스에 영향을 주지 않고 기능, 실험 및 수정 작업을 고립 상태에서 수행할 수 있게 해준다. 나는 아마 매주 10-15개의 브랜치를 생성하며, 이러한 명령어들이 그 워크플로를 매끄럽게 만든다.
| 명령어 카테고리 | 일일 사용 빈도 | 위기 복구 가치 |
|---|---|---|
| 기본 작업 (add, commit, push, pull) | 하루에 50-80번 | 낮음 - 하지만 모든 것의 기반 |
| 브랜치 관리 (checkout, branch, merge) | 하루에 15-25번 | 중간 - 워크플로에 필수적 |
| 기록 및 검사 (log, diff, status) | 하루에 20-30번 | 높음 - 디버깅에 중요 |
| 작업 되돌리기 (reset, revert, reflog) | 하루에 2-5번 | 중요 - 3 AM에 경력을 구한다 |
| 고급 복구 (cherry-pick, rebase, stash) | 하루에 3-8번 | 매우 높음 - 정밀 수술 도구 |
git branch는 모든 로컬 브랜치를 나열한다. 현재 브랜치는 별표로 표시된다. 나는 git branch -a를 사용하여 원격 브랜치도 확인하고, git branch -d branch-name으로 내가 완료한 브랜치를 삭제한다. -d 플래그는 안전하다—병합되지 않은 변경 사항이 있는 브랜치는 삭제할 수 없게 해준다. 만약 정말로 브랜치를 삭제하고 싶다면(실패한 실험일 수 있다면) git branch -D branch-name을 사용하라.
나는 오래된 브랜치를 끊임없이 정리한다. 50개의 오래된 브랜치가 있는 저장소는 혼란스럽고, 찾고 있는 것을 찾기 어렵게 만든다. 매주 금요일, 나는 git branch --merged를 실행하여 어떤 브랜치가 메인에 병합되었는지를 확인한 다음, 삭제한다. 이는 책상을 정리하는 것과 같다—그냥 기분이 좋다.
git checkout은 사이를 전환하는 데 사용된다.