전체 검색

글, 태그와 카테고리를 검색하고 바로 이동해요

여울 v0.2.0 공개 베타 — 5주 만에 도구가 된 Git GUI

여러 Git 저장소와 워크트리를 한 화면에서 다루는 여울 v0.2.0을 공개합니다. 첫 공개 빌드까지의 5주 기록과 최신 설치 안내를 함께 정리했어요.

2026. 08. 27. 10:15:328분 읽기프로젝트/Git GUI
#macOS#멀티레포#워크트리#Git#Electron
조회 9

여울의 두 번째 공개 베타인 v0.2.0을 배포합니다. 이번 버전은 하나의 저장소를 잘 보는 데서 더 나아가, 여러 저장소와 워크트리를 한 작업 공간에서 끊김 없이 다루는 데 초점을 맞췄습니다.

여울 v0.2.0 DMG 바로 다운로드 — Apple Silicon과 Intel Mac을 모두 지원하는 Universal 빌드입니다. 링크를 누르면 GitHub 릴리스 페이지를 거치지 않고 바로 다운로드됩니다.

여러 저장소가 하나의 작업 공간으로

프로젝트를 구성하는 저장소가 여러 개라면 이제 각각을 따로 열 필요가 없습니다. 작업 공간 트리에서 저장소와 워크트리를 함께 살펴보고, 선택한 저장소의 변경 파일과 커밋 흐름으로 바로 이동할 수 있습니다.

여울 v0.2.0 멀티 저장소 작업 공간 화면
여러 저장소와 워크트리, 변경 상태를 한 화면에서 확인합니다.

저장소별 변경 개수와 현재 브랜치를 한눈에 확인할 수 있고, 여러 저장소에 흩어진 변경도 같은 흐름에서 스테이지하거나 다시 내릴 수 있습니다.

워크트리를 부가 기능이 아닌 기본 작업 단위로

여울의 중심은 여전히 워크트리입니다. 브랜치와 워크트리 관계를 트리에서 확인하고, 각 워크트리의 변경·히스토리·터미널로 자연스럽게 이어집니다. AI 기능을 앞세우는 도구보다 실제 Git 작업과 워크트리 운용을 편하게 만드는 Git GUI를 목표로 합니다.

여울 v0.2.0 워크트리와 커밋 히스토리 화면
워크트리별 브랜치와 커밋 흐름을 통합 트리에서 살펴볼 수 있습니다.

v0.2.0에서 달라진 점

  • 여러 Git 저장소를 하나의 작업 공간 트리로 통합
  • 저장소별 변경 파일과 커밋 히스토리 조회
  • 저장소를 넘나드는 스테이지·언스테이지 흐름 개선
  • 워크트리와 저장소 상태 배지 정리
  • 좁은 창에서도 헤더와 pull·push 상태가 줄바꿈되지 않도록 반응형 레이아웃 개선
  • 간격·디바이더·타이포그래피와 테마 설정 정돈
  • 외부 파일 변경 감지와 패키지 실행 검증 안정화

설치와 업데이트

  1. 위 DMG 링크에서 설치 파일을 내려받습니다.
  2. DMG를 열고 여울을 응용 프로그램 폴더로 옮깁니다.
  3. 기존 버전을 사용 중이라면 앱을 종료한 뒤 새 버전으로 교체합니다.

앞으로 새 버전은 소스 코드와 분리된 공개 릴리스 저장소에서 확인합니다. 여울이 latest-mac.yml을 통해 새 버전을 찾고 DMG와 SHA-512를 검증한 뒤 설치 파일을 열어줍니다. 소스 저장소는 계속 비공개로 유지됩니다.

공개 베타에서 알아둘 점

현재 Apple Developer ID 서명·공증이 없는 ad-hoc 서명 빌드입니다. 첫 실행에서 macOS가 막으면 Finder에서 여울을 우클릭하고 열기를 선택해야 할 수 있습니다. 중요한 저장소는 원격에 백업한 뒤 사용하는 것을 권장합니다.

v0.2.0 릴리스 안내와 전체 파일 보기

문제나 개선 의견은 여울 릴리스 저장소의 Issues에 남겨주세요.


첫 공개 빌드 0.0.1 기록

지금 이 글도 그 앱으로 커밋했습니다.

5주 전에 "화면엔 AI만 남았는데, 커밋은 어디서 하지"로 시작한 이야기예요. 에디터를 안 쓰게 되면서 IntelliJ의 git 도구 하나 때문에 IDE를 켜는 게 이상해졌고, 그래서 직접 만들기로 했던 그 앱이요.

오늘 그 앱이 제 독(Dock)에 아이콘으로 있습니다. 이름은 Git GUI, 버전 0.0.1. 설치 가능한 .dmg가 나왔고, 저는 이제 매일 이걸로 커밋합니다.

완성이라고는 안 할게요. 다만 "만들고 있는 것"에서 "쓰고 있는 것"으로 넘어갔습니다. 그 선을 넘은 기록이에요.

Git GUI 0.0.1 첫 릴리스

Git GUI 0.0.1 — 5주 만에 손에 쥔 첫 릴리스.

이 앱으로 보내는 하루

기능을 나열하면 읽히지 않으니, 제가 실제로 쓰는 순서대로 적어볼게요.

Git GUI 기본 3열 화면

왼쪽은 변경 목록과 커밋 폼, 가운데는 diff, 오른쪽은 커밋 히스토리. 실제 arcaC 저장소를 연 화면이에요.

아침에 앱을 켜면 어제 열어둔 저장소들이 탭으로 그대로 돌아옵니다. 창 배치도, 사이드 접힘도, 터미널 높이도요. 회사 저장소 탭에서 작업하다가 개인 프로젝트는 ⌘T로 새 탭에 엽니다.

왼쪽 [브랜치] 탭은 접이식 트리예요. feature/로 시작하는 브랜치들이 폴더로 묶여 있고, 이름 옆에 초록 ↑와 주황 ↓가 조용히 떠 있습니다. 올릴 게 있다는 뜻, 받을 게 있다는 뜻.

브랜치를 두 번 클릭하면 오른쪽 히스토리가 그 계보로 바뀌어요. 로컬·원격(☁)·태그(🏷)가 한 그래프에 있고 "지금 여기" 마커가 HEAD를 따라다닙니다.

Git GUI 브랜치 트리

codex·claude·ooo 같은 접두사가 폴더로 묶이고, 이름 옆 초록 ↑와 주황 ↓가 올릴 것·받을 것을 알려줘요. ➤가 지금 있는 자리.

작업하다 커밋할 게 생기면 왼쪽 [변경] 탭에서 체크박스로 골라 올리고, 컴포저에 메시지 쓰고 ⌘↵. 브랜치를 갈아타야 하는데 저장 안 한 게 있으면 앱이 알아서 치워뒀다가 다시 꺼내줍니다.

충돌이 나면 화면이 [변경] 탭으로 저절로 이동하고, 겹친 부분이 카드 한 장씩 나옵니다. "두 버전이 같은 곳을 다르게 고쳤어요. 어느 쪽을 쓸까요?"

가끔은 그냥 터미널이 편할 때가 있어요. ⌘`를 누르면 아래에서 진짜 쉘이 올라옵니다(node-pty). 거기서 커밋을 하면 위쪽 화면이 알아서 따라 갱신되고요. 앱이 모르는 사이에 저장소가 바뀌는 일이 없습니다.

Git GUI 터미널 도크

아래에서 올라오는 건 흉내가 아니라 진짜 쉘이에요. 여기서 커밋하면 위 화면이 알아서 따라옵니다.

리뷰 요청도 앱에서 만듭니다. 열린 PR 목록을 보고, 코멘트에 답하고, 승인하고, 병합하면 기본 브랜치로 이동해서 받아올지 물어봐요.

이게 5주 전엔 없던 하루입니다.

5주 동안 만들어진 것

항목수치
기간2026-07-15 ~ 08-19 (5주)
커밋691개
설계 스펙 문서27개 (에픽 E0~E15e)
소스 파일178개 (TS/TSX)
테스트 파일60개
워크스페이스 패키지6개
패키징electron-builder — .app/.dmg 생성·검증 완료

패키지 경계는 첫 편에서 정한 그대로예요. domain(순수 TS)·git-adapter(porcelain v2 파싱)·git-process(실행·취소·스트리밍)·ipc-contract(타입 계약)·hosting(GitHub)·desktop(화면). 5주 동안 이 경계를 한 번도 안 고쳤습니다.

0단계에서 민짜 HTML로 수직 한 줄부터 뚫었던 것이 여기서 값을 했어요. 화면은 그 뒤로 세 번쯤 갈아엎었는데, 파서와 도메인은 그대로였거든요.

27개의 스펙이 곧 개발 로그였습니다

5주에 691커밋이면 빠른 편인데, 비결은 손이 빨라서가 아니에요. 에픽 하나마다 같은 루프를 돌았습니다.

스펙 작성 → 구현 → 리뷰(실측) → 스펙 정정 → 머지

· 스펙에는 "무엇을 만든다"가 아니라
  "왜 지금 이걸 하는가 + 뭘 감수하는가"를 적는다
· 리뷰는 코드가 아니라 실제 동작을 측정한다
· 실측이 스펙과 다르면 코드가 아니라 스펙을 고친다

커밋 로그를 보면 `docs: E14c 스펙 정정 — Task 1 실측` 같은 게 반복돼요. 만들어보고 나서 설계 문서를 고친 흔적입니다. 처음 쓴 스펙이 맞았던 적이 별로 없거든요.

이 루프가 쌓이니 27개 스펙이 그 자체로 개발 일지가 됐어요. "그때 왜 그렇게 했지?"를 다시 물을 일이 거의 없었습니다.

가장 어려웠던 세 순간

1. 네이티브 탭을 포기한 날

저장소를 여러 개 열고 싶어서 macOS 네이티브 탭을 쓰려고 했어요. OS가 그려주니까 공짜라고 생각했죠.

구현 불가로 닫혔습니다. Electron에서 네이티브 탭은 표준 타이틀바에서만 켜지는데, 이 앱은 이미 헤더를 한 줄로 만들어 신호등 버튼과 같은 줄에 놓은 상태였거든요. 양자택일이었어요.

선택지얻는 것잃는 것
네이티브 탭OS가 그려줌 · 공짜한 줄 헤더 포기, 세로 공간 낭비
탭바 직접 그리기헤더 유지탭바·드래그·복원을 전부 구현

헤더를 지키는 쪽을 골랐습니다. 그래서 탭바를 창 맨 윗줄에 직접 그렸고, 그게 타이틀바 역할까지 겸해요. 탭 순서 바꾸기, 창 밖으로 떼어내 새 창 만들기, 창 사이로 옮기기까지 전부 손으로 만들었습니다.

OS가 해주던 걸 직접 하기로 하면, 그 뒤에 딸려오는 일이 생각보다 훨씬 많아요. 그런데 화면 한 줄이 매일 눈에 보이니까요. 후회는 안 합니다.

2. 15초에 크래시 157번

탭을 만들고 나서 리뷰가 잡아낸 문제예요. 탭 하나가 죽으면(렌더러 크래시) 창 전체가 인질이 됩니다.

탭바를 각 탭이 자기 안에 그리기 때문이에요. 활성 탭이 죽으면 탭바도 단축키도 그 죽은 화면 안에 있어서, 살아 있는 옆 탭으로 갈 방법이 없습니다. 유일한 출구가 창 닫기인데 그러면 멀쩡한 탭들까지 같이 잃고요.

그래서 죽으면 자동으로 다시 켜지게 했습니다. 그리고 실측에서 이게 나왔어요.

연속 자동 재시동 → 무한 루프
실측: 15초에 크래시 157회

"로드하면 반드시 죽는" 렌더러라면
reload 완료가 곧장 다음 크래시를 부른다

처방은 상한이었어요. 연속 3회까지만 자동 재시동하고, 로드 후 10초를 살아남으면 다음 크래시는 새 사건으로 세서 카운터를 리셋합니다. 상한을 넘기면 멈추고 죽은 표시를 남겨요.

무한 루프보다 정지가 낫다 — 자동 복구를 만들 때는 항상 이 문장이 필요하더라고요. 복구가 사고를 증폭시키는 경우가 실제로 있으니까요.

3. 한 달간 조용히 깨져 있던 것

제일 오싹했던 건 이거예요. 사이드바를 접으면 터미널 폭이 안 맞는 문제가 있었는데, 원인이 한 달 전 코드였습니다.

// 마운트 시점 상태를 굳혀버린 이펙트
useEffect(() => {
  // ... sessions 를 참조하지만 deps 는 []
}, []);

// 결과: refitActive 가 항상 activeId: null 로 호출
// 실측 17회 시도 → fit 0회

창 크기를 바꿀 때는 다른 코드의 부수효과가 이걸 가려줘서 멀쩡해 보였어요. 사이드 접기에서만 드러났습니다. 도크는 1160px인데 터미널은 737px, 오른쪽 35%가 빈 공간이었죠.

이걸 계기로 이 저장소 첫 lint 게이트를 넣었습니다. React 훅 규칙을 error로 올리고, 억제해둔 12곳을 전부 해소했어요. 억제 주석마다 "왜 지금은 못 푸는지 + 뭘 바꾸면 풀리는지"를 적어뒀더니, 그 주석들이 그대로 다음 에픽의 할 일 목록이 되더라고요.

규칙을 기계에 맡기는 이야기를 회사 코드베이스에서 그렇게 했는데, 개인 프로젝트에서도 결국 같은 결론에 도착했습니다.

아직 안 된 것들

0.0.1이라고 붙인 이유가 있어요.

남은 것상태
취소 가능한 Git 프로세스·실행 로그미착수 — 긴 작업 중단이 아직 안 됨
네트워크 진행 표시미착수
충돌·중단 상태별 테스트 fixture일부만
Windows·Linux미지원 — macOS만 패키징
submodule · LFS · sparse checkout설계에는 있고 구현은 아직

제품 목적 문서에는 submodule과 LFS도 1급으로 다루겠다고 써놨는데, 아직 못 했습니다. 쓰면서 아쉬운 순서대로 하는 중이에요.

그리고 정직하게 — 이건 아직 남에게 권할 만큼 검증된 앱은 아닙니다. 제 저장소들에서 매일 도는 정도고요.


결국 만든 건 초보용 앱이 아니었어요

이 시리즈를 시작할 때 목표는 "Git을 모르는 사람도 쓸 수 있는 앱"이었습니다. 그런데 3편에서 "저장하기"를 버리고 "커밋"으로 돌아왔고, 결국 개발자 어휘가 기본이 됐어요.

만들면서 알게 된 게 있어요. 제가 만들 수 있는 건 "내가 매일 쓰는 앱"이지 "남을 위한 앱"이 아니라는 것. 매일 쓰지 않으면 뭐가 불편한지 모르고, 모르면 못 고칩니다.

쉬운 말은 버린 게 아니라 미뤄뒀어요. 용어가 한 파일에 모여 있어서 표 하나만 더 만들면 되살아납니다. 다만 그건 이 앱이 저한테 충분히 좋아진 다음의 일이에요.

충돌을 카드로 만들고, 터미널을 넣고, 어휘를 바꾸고 — 그렇게 도구가 됐습니다. 이 시리즈는 여기서 닫아요.

다음은 만드는 이야기가 아니라 쓰는 이야기가 될 것 같습니다. 매일 쓰다 보면 또 불편한 게 나올 테니까요.

시리즈 이어읽기

Git GUI, 도구가 되기까지

4 / 5

이야기 나누기

반응을 남기고 새 글 소식을 받아보세요.

댓글0
서로를 존중하는 대화를 남겨주세요.

첫 댓글을 남겨 대화를 시작해보세요.

새 글 구독
새 글이 공개되면 이메일로 알려드려요.