2026년 3월

모노레포 짭 - Orphan Branch

하나의 레포지토리 안에서 orphan branch와 clean-switch alias로 프로젝트를 격리하는 방법

모노레포 딜레마?

지금까지 modal, prettier-format-linear, nextjs-netdef 같은 싱글파일 유틸리티를 만들면서 '이거 파일 몇개 없는데, repo를 따로따로 만들어서 유지해야하나?' 라는 생각이 들었습니다.

가장 먼저 떠오른 생각은 모노레포를 적용해보는 것이었습니다. 관리 용이성 · 코드 공유 · 일관된 개발 환경 · 의존성 관리 · 대규모 리팩터링 등 장점이 많아 보였습니다.

  • app
  • web
  • UI
  • Test
Mono Repo
  • app Repo
  • web Repo
  • UI Repo
  • Test Repo
Poly Repo

하지만 저의 상황에서는 오히려 'over engineering이 아닌가?' 하는 생각이 들었습니다. 여러 언어를 넘나들어야하고, 그러다 보니 일관된 개발환경은 불가능하고, 서로 의존성을 관리할 필요도 없으며, 서로가 의존하지 않으니 대규모 리펙터링도 일어나지 않을 터 였습니다.

뭔가 하나의 레포지토리에 여러 프로젝트를 격리할 수 있는 쉬운 방법이 없나 찾아보다가, 언젠가 들어봤던 Orphan Branch라는 것이 번뜩 떠올랐습니다.

Git Orphan Branch

git을 사용하다보면 init 커밋에서 시작해 branch들이 가지를 뻗어가다가, 하나로 합쳐지는 모양을 반복하며, 하나의 git tree를 형성합니다.

git branch <name>
로 branch를 생성할 때도, head가 가리키는 commit을 가리키는 branch가 생성되어, 최초의 main branch가 만드는 git tree를 벗어날 수 없습니다.

하지만 orphan branch는 기존 브랜치와 완전히 분리된 새로운 트리를 시작할 수 있게 합니다.

git switch --orphan <branch이름>
# Example
git switch --orphan test1
# Switched to a new branch 'test1'
git log
# fatal: your current branch 'test1' does not have any commits yet

orphan branch가 만들어지고,

git log
를 사용하면 아직 아무런 커밋도 하지 않았으므로, 에러가 발생합니다.

커밋을 하고,

git log
를 사용하면 커밋이 추가된 것을 확인할 수 있고,
git switch
로 독립된 코드베이스와 git tree를 넘나들 수 있습니다.

Untracked 파일이 남는 문제

이제 생성된 orphan branch와 기존의 main branch를 넘나들며, 독립된 프로젝트를 운용할 수 있습니다. 하지만 두 branch를 넘나들다보면 이전 branch에서 몇몇 파일들이 남아 Untracked 상태를 가지게 됩니다.

Untracked Diagramignore 된 파일이 untracted로 남는 문제

원인은 .gitignore에 등록된 파일은 switch를 해도 바뀌지 않지만, switch를 하면 .gitignore의 내용이 바뀌기 때문에, 제외된 파일이 untracked로 표시되는 것입니다.

정말 다행히도 git에는 clean 명령어가 있어, 제외된 파일이나 폴더만 제거할 수 있습니다.

git clean -fdx
# 또는
git clean -nfdx

clean + switch = clean-switch

매번 switch할 때마다, clean 명령어를 사용하는 것은 매우 귀찮은 일입니다. git의 command alias 기능을 사용해서 하나의 명령어로 정의해서 사용할 수 있습니다.

# global scope 에서 사용하고 싶을 때
git config --global alias.clean-switch '!f() { git clean -fdX && git switch "$@"; }; f'

# local scope (scope를 명시하여)
git config --local alias.clean-switch '!f() { git clean -fdX && git switch "$@"; }; f'

# local scope (scope를 명시하지 않아도됨)
git config alias.clean-switch '!f() { git clean -fdX && git switch "$@"; }; f'

위 명령어중 하나를 선택하여 적용합니다.

--global
scope로 설정하여, 다른 레포지토리에서도 해당 alias를 사용할 수 있고
--local
scope로 저장하면 이 레포지토리의 범위안에서만 사용할 수 있습니다.
--local
은 생략할 수 있습니다.

Untracked Diagramclean-switch demo

이제 orphan branch로 switch할 때는

git clean-switch <branch>
를 사용하면 clean 명령어가 실행된 후에 switch 됩니다.

한계점

이 방식은 프로젝트를 완전 독립된 환경에서 작동시키면서도, 하나의 레포지토리에서 관리할 수 있게 해줍니다. 하지만 한계점이 없는 것은 아닙니다.

정리

위의 단점에도 불구하고 저는 이 방식을 저의 github profile repo에서 사용하고 있습니다. dependency가 적고, 단편적인 유틸리티 파일을 언어에 관계없이 관리할 수 있다는 점이 큰 장점으로 다가왔기 때문입니다.

의존성 폴더가 제거되긴 하지만, orphan branch 끼리 의존하지 않고, .env 없는 단일파일 유틸리티와 테스트코드로만 이루어진 저의 orphan branch 사용패턴에서는 매우 효과적인 정리방법이었습니다.

실제로 적용한 결과는 아래에서 확인하실 수 있습니다.

Xeonlink/Xeonlink