Rain Lag

브랜치 없는 아침: 매일 코딩을 ‘후회 커밋’ 없이 시작하는 작은 Git 의식

매일 아침 반복할 수 있는 간단한 Git 루틴만으로 브랜치를 깔끔하게 유지하고, 히스토리를 읽기 좋게 만들며, 미래의 나를 후회 커밋에서 해방시키는 방법.

브랜치 없는 아침: 매일 코딩을 ‘후회 커밋’ 없이 시작하는 작은 Git 의식

Git 히스토리가 나무가 아니라 덤불처럼 보인다면, 당신만 그런 게 아니다.

아침에 책상을 앉고, 에디터를 열고, 최신 변경사항을 pull 하고, 몇 시간 동안 코딩을 하다가 문득 깨닫는다:

  • 잘못된 브랜치에 커밋했다.
  • 시작 전에 pull 하는 걸 잊어서 지금 브랜치가 뒤처졌다.
  • 히스토리에 의미 없는 merge 커밋과 대충 적은 WIP 메시지가 잔뜩 쌓였다.

이런 것들이 바로 후회 커밋(regret commits) 이다. 미래의 나도, 내 팀원들도, 리뷰어도 차라리 못 봤으면 싶은 커밋들.

이걸 고치려고 새로운 Git GUI, 거창한 브랜칭 전략, 복잡한 프로세스가 필요한 건 아니다. 필요한 건 아주 작지만 매일 반복 가능한 의식이다: 바로 브랜치 없는 아침(branchless morning).

이 글에서는 매일 몇 초면 실행할 수 있는 간단한 Git 루틴을 만드는 방법을 설명한다. 이 루틴을 쓰면 항상 깨끗하고 최신 상태의 브랜치에서 시작해서, 나중에 봐도 자랑스러운 히스토리로 하루를 마무리할 수 있다.


“브랜치 없는 아침”이란 무엇인가?

브랜치 없는 아침은 매일 코딩을 시작할 때 실행하는 아주 작은 의식이다:

  1. 지금 내가 어떤 브랜치에 있는지 확인한다.
  2. merge 가 아니라 rebase 로 원격과 동기화한다.
  3. 간단한 명령 하나로 모든 주요 레포지토리를 자동으로 업데이트한다.
  4. 머지 전에 주기적으로 커밋 히스토리를 정리한다.

목표는 브랜치를 없애는 게 아니다(브랜치는 좋다). 대신에 이런 걸 방지하는 게 목적이다:

  • 잘못된 브랜치에서 실수로 작업하는 상황을 피하기.
  • 주로 작업하는 브랜치를 선형(linear), 깔끔하고 읽기 쉽게 유지하기.
  • 여러 프로젝트 사이를 오갈 때마다 드는 정신적 부담 줄이기.

제대로만 하면 이 과정은 1분도 안 걸리는데, 나중에 겪을 수많은 Git 고통을 막아준다.


1단계: 항상 내가 어디에 있는지부터 확인하기

후회 커밋을 만드는 가장 빠른 방법은 엉뚱한 브랜치에 커밋하는 것이다.

코드 한 줄이라도 치기 전에 Git에 이렇게 물어보자:

git branch

출력은 대략 이렇게 나올 수 있다:

feature/login-page * main hotfix/issue-123

* 표시가 있는 브랜치가 현재 브랜치다. 이 예에서는 main에 올라가 있는 상태다.

습관으로 굳혀야 한다:

  • 코딩 전에 확인하기. 하루를 시작하기 전에 git branch.
  • 커밋 전에 확인하기. git status 또는 git branch 로 대상 브랜치를 다시 확인.

만약 원하는 브랜치가 아니라면 이렇게 바꾼다:

git checkout feature/login-page # 또는 최신 버전에서는 git switch feature/login-page

이것만 습관이 돼도 “헉, 이걸 main 에 바로 커밋했네” 같은 순간이 놀랄 만큼 줄어든다.


2단계: 평범한 git pull 대신 git pull --rebase 쓰기

올바른 브랜치에 있는 걸 확인했으면, 이제 그 브랜치를 원격과 최신 상태로 맞춰야 한다.

많은 사람들이 그냥 이렇게 쓴다:

git pull

이것도 작동은 하지만, 종종 이런 불필요한 merge 커밋을 만든다:

Merge branch 'main' of github.com:org/repo

사실은 로컬 커밋을 업데이트된 원격 브랜치 위에 그대로 다시 쌓기만 하면 될 때도 말이다.

히스토리를 깨끗하고 선형으로 유지하려면 이렇게 하자:

git pull --rebase

--rebase 인가?

  • 선형 히스토리: 내 커밋이 최신 원격 변경사항 위에 차곡차곡 쌓인다.
  • merge 커밋 감소: 의미 없이 로그를 어지럽히는 “Merge branch 'main'” 커밋이 줄어든다.
  • 읽기 쉬움: git log 가 매듭이 아니라 이야기처럼 보인다.

이 동작을 특정 레포지토리의 기본값으로 만들 수 있다:

git config pull.rebase true

전역 설정도 가능하다:

git config --global pull.rebase true

이렇게 하면 평소에 쓰는 git pull 이 자동으로 git pull --rebase 처럼 동작한다.

매일 아침, 작업 브랜치에서 이렇게 실행하자:

git checkout main # 또는 평소 작업하는 브랜치 git pull --rebase

이렇게 하면 최신 상태에서 코딩을 시작하면서도, 히스토리는 깔끔하게 유지할 수 있다.


3단계: 모든 프로젝트를 위한 아침용 단일 명령 만들기

여러 레포지토리에서 일한다면(대부분 그렇다), 각 레포마다 같은 의식을 반복하는 건 꽤 번거롭다.

이럴 때 유용한 게 바로 이런 간단한 커스텀 명령이다. 예를 들어:

gmg -folder .

gmg 를 “good morning git” 정도의 작은 스크립트라고 생각해보자. 하루를 시작할 때 프로젝트들이 모여 있는 디렉터리에서 한 번만 실행하는 것이다. 예를 들어:

~/projects ├── api-service ├── web-frontend └── mobile-app

~/projects 에서 이렇게 실행한다:

gmg -folder .

그러면 이 스크립트가:

  • 폴더 안에 있는 각 Git 레포지토리를 찾고,
  • 각 레포에서 주로 사용하는 메인 작업 브랜치(예: main 또는 develop)로 전환한 뒤,
  • git pull --rebase 를 실행하고,
  • 선택적으로, 커밋되지 않은 변경사항이 있다면 상태나 경고를 보여준다.

꼭 이름을 gmg 로 할 필요는 없지만, 핵심 아이디어는 이렇다:

명령 하나로, 모든 주요 레포를 한 번에 깨끗하고 최신 상태로 만든다.

하루를 시작할 때 레포마다 돌아다니면서 일일이 pull 할 필요가 없어진다.


4단계: 컨텍스트를 바꿀 때 쓰는 프로젝트별 의식

하루를 보내다 보면 다른 레포나 다른 feature 브랜치로 점프해야 할 때가 있다. 이때 유용한 게 바로 이런 프로젝트 전용 명령이다:

gmg -repo

이 명령은 개별 레포지토리 안에서 실행해서, 동일한 ‘브랜치 없는’ 규칙을 적용한다:

  • 현재 브랜치를 확인하고,
  • 평소엔 develop 나 feature 브랜치에서 일하는데 지금 main 에 있다면 알림을 줄 수도 있고,
  • 추적 중인 브랜치에 대해 git pull --rebase 를 실행하고,
  • 마무리로 git status 를 보여줘서 지금 상황을 한눈에 알 수 있게 한다.

이건 간단한 쉘 스크립트나 alias 로 쉽게 만들 수 있다.

아주 단순한 Bash 의사코드 예시는 다음과 같다:

#!/usr/bin/env bash # gmg -repo branch=$(git rev-parse --abbrev-ref HEAD) echo "Current branch: $branch" git fetch git pull --rebase git status -sb

세부 구현은 각자 스타일에 따라 바꾸면 되지만, 중요한 건 동일한 행동 패턴이다:

  • 레포에 들어올 때마다 짧은 자동 정리를 한 번 돌리고,
  • 명령이 충분히 짧고 간단해서 진짜로 매번 쓰게 만드는 것.

5단계: 머지 전에 히스토리 정리하기

브랜치 없는 아침은 시작을 깔끔하게 만들어 준다. 끝을 깔끔하게 만들려면, 머지 전에 히스토리를 다듬는 과정이 필요하다.

우리 대부분은 하루 동안 이런 식으로 대충 커밋한다:

  • WIP fix tests
  • oops
  • attempt 3

개발 중에는 전혀 문제 없지만, 이런 걸 그대로 main 에 머지하고 싶지는 않을 것이다.

PR 을 올리거나 머지하기 전에, Git 이 제공하는 히스토리 정리 도구들을 활용하자.

인터랙티브 리베이스(Interactive Rebase)

인터랙티브 리베이스를 사용하면 최근 커밋들을 다시 쓸 수 있다:

git rebase -i HEAD~5

그러면 최근 5개의 커밋이 에디터에 뜬다. 여기서 다음과 같은 작업이 가능하다:

  • 커밋 메시지를 reword 해서 다시 쓰기
  • 여러 커밋을 하나로 squash 하기
  • 작은 후속 수정 커밋을 이전 커밋에 fixup 으로 합치기

예시 스니펫:

pick 1234abc Add login form fixup 5678def Fix typo in login button squash 9abc012 Adjust login form styling

결과: 의미 없는 커밋 3개 대신, 의미 있는 메시지 하나를 가진 깔끔한 단일 커밋이 된다.

Squash 와 Fixup 활용하기

어떤 커밋이 “앞에 있던 특정 커밋에 붙어야 한다”는 걸 이미 알고 있다면, 이렇게 쓸 수 있다:

git commit --fixup <commit-hash>

그리고 나중에 이렇게 실행한다:

git rebase -i --autosquash HEAD~5

그러면 Git 이 자동으로 관련된 fixup 커밋들을 묶어서 적절히 squash 해준다.

최종 결과

PR 을 열 때쯤이면, 내 브랜치는:

  • 의도적인, 의미 있는 커밋들로 이루어져 있고,
  • 리뷰어가 흐름을 따라가기 쉬운 이야기를 담고 있으며,
  • main 에 머지해도 복잡한 merge 와 revert 커밋 없이 깨끗하게 들어간다.

이건 후회 커밋의 정반대다. 몇 달 후 다시 봐도 기분 좋은 히스토리다.


모두 합치기: 하루를 여는 브랜치 없는 루틴

실제 하루의 브랜치 없는 아침은 대략 이렇게 보일 수 있다.

하루를 시작할 때:

  1. 프로젝트 디렉터리로 이동:
    cd ~/projects
  2. 아침용 명령 실행:
    gmg -folder .
  3. 오늘 작업할 레포로 들어가서 브랜치 확인:
    cd web-frontend git branch
  4. 필요하다면 feature 브랜치로 전환하거나 새 브랜치를 만든다.

하루 중에 프로젝트를 바꿀 때:

  1. 새 레포로 cd.
  2. 다음 명령 실행:
    gmg -repo
  3. 코딩하기 전에 내가 올바른 브랜치에 있는지 다시 확인.

PR 을 열거나 머지하기 전에:

  1. 인터랙티브 리베이스로 커밋 정리:
    git rebase -i HEAD~N # 오늘 작업 분량에 맞게 N 선택
  2. 정리된 브랜치를 push (워크플로에 따라 괜찮다면 force-push 사용):
    git push --force-with-lease

이 루틴은 길어야 몇 분이면 충분하지만, 다음과 같은 상황을 크게 줄여준다:

  • 실수로 main 에 바로 커밋하는 일.
  • 히스토리에 보기 싫은 merge 버블이 생기는 일.
  • 공유 브랜치에 민망한 WIP 커밋들이 그대로 남는 일.

마무리: 작은 의식이 큰 차이를 만든다

Git 문제는 보통 한 번의 대형 사고에서 나오지 않는다. 수많은 작은, 급한 결정들이 쌓여서 생긴다:

  • “일단 여기다 그냥 커밋해두자.”
  • “pull 은 나중에 하지 뭐.”
  • “히스토리 정리는 나중에 시간 날 때 하지.”

브랜치 없는 아침은 이 패턴을 뒤집는 작은 규율이다:

  • 매일 아침, 지금 내가 어디에 있는지(어떤 브랜치인지) 먼저 확인한다.
  • 항상 rebase 로 pull 해서 히스토리를 곧게 유지한다.
  • gmg -folder . 같은 간단한 명령으로 아침 동기화를 자동화한다.
  • gmg -repo 같은 도구로 프로젝트별로도 같은 의식을 적용한다.
  • 커밋 히스토리를 정기적으로 다듬어서 머지와 리뷰를 깔끔하게 만든다.

후회 커밋을 피하려고 Git 의 고급 기능을 전부 마스터할 필요는 없다. 매일 반복할 수 있는 작은 루틴 하나면 충분하다.

하루의 첫 번째 명령을 ‘브랜치 없는’ 명령으로 만들어보자. 그러면 미래의 나(그리고 내 팀원들)는 우연이 아닌 의도적인 히스토리를 읽게 될 것이다.

브랜치 없는 아침: 매일 코딩을 ‘후회 커밋’ 없이 시작하는 작은 Git 의식 | Rain Lag