195개의 리포지토리를 한눈에: 메타-리포와 AI 에이전트가 이를 필요로 하는 이유
요약
대규모 코드베이스를 관리하는 어려움을 해결하기 위해 'overrepo'와 같은 메타-리포지토리 개념이 소개되었습니다. 이는 수많은 개별 리포지토리를 하나의 클론과 통합된 운영 인터페이스로 제공하여, 에이전트나 개발자가 전체 시스템을 한눈에 파악하고 작업할 수 있게 돕습니다.
핵심 포인트
- 메타-리포는 여러 리포지토리를 단일 클론으로 관리하는 방법입니다.
- 개발자/AI 에이전트는 전체 코드베이스의 구조화된 지도가 필요합니다.
- 이는 Android의 'repo' 도구와 npm의 '.meta' 개념에서 유래했습니다.
이번 주에 한 클라이언트가 간단한 질문을 했습니다. “에이전트가 전체 플랫폼을 볼 수 있나요?”
플랫폼은 대략 195개의 git 리포지토리로 구성되어 있습니다. 프론트엔드, 서비스, Terraform, 그리고 아무도 누가 작성했는지 기억하지 못하는 몇 가지 라이브러리가 포함됩니다. 어떤 에이전트도 이 모든 것을 볼 수 없습니다. 새로운 개발자 역시 마찬가지입니다.
그래서 overrepo가 구축되었습니다. 매니페스트(manifest), 셀렉터(selector), 그리고 맵(map)을 갖춘 것입니다.
제가 이것을 만든 이유
에이전트는 더 이상 혼자 작동하지 않습니다. 서로 작업을 위임하고, 호출하며, 효율적으로 작동하기 위해 코드베이스 전반의 점들을 연결하려고 시도합니다.
하지만 점들을 연결하려면 점들이 필요합니다. 무엇이 존재하는지에 대한 그림 없이는 모든 에이전트가 0에서 시작하게 됩니다. 즉, 매번 작업마다 grep을 하거나, 추측하거나, 같은 구조를 재발견해야 합니다.
overrepo는 그들에게 탄탄한 출발점을 제공합니다. 어떤 에이전트든 무언가를 건드리기 전에 읽을 수 있는 플릿(fleet)의 문서화된 지도입니다.
또한 제가 끊임없이 겪었던 상황도 해결해 줍니다. 예를 들어, T3 Turbo, Nx, Turborepo 또는 pnpm workspaces를 사용하여 구축한다고 가정해 봅시다. 여러분의 앱과 패키지는 하나의 리포지토리 안에 깔끔하게 정리되어 있습니다. 그런 다음 경계를 넘나드는 작업이 발생합니다. 즉, 한 리포지토리의 API, 다른 리포지토리의 인프라, 세 번째 리포지토리의 공유 SDK 같은 경우입니다. 갑자기 여러 클론을 수동으로 다루게 됩니다. 이것이 바로 메타-리포가 채우는 정확한 간극입니다.
그리고 만약 에이전트가 클라우드 VM에서 실행되는 더 진보된 단계라면, 이는 매우 실용적입니다. 두 개의 리포지토리 수정 작업 때문에 새로운 VM을 띄워 195개의 리포지토리를 복제하는 것은 원치 않을 것입니다. overrepo를 사용하면 에이전트는 태그나 경로로 선택된 현재 작업에 필요한 리포지토리만 클론하여 작업을 시작할 수 있습니다.
메타-리포가 나오는 배경
문제 자체는 오래되었습니다. 안드로이드(Android)가 대규모에서 가장 먼저 이 문제를 겪었습니다. 수백 개의 git 리포지토리를 함께 체크아웃하고 작업해야 했기 때문입니다. 구글의 해결책은 repo 도구였습니다. 이는 모든 리포지토리, 그 경로와 원격 저장소를 나열하는 하나의 매니페스트 파일과, 이들을 모두 동기화하는 명령어로 구성되어 있었습니다.
나중에, meta npm 패키지가 같은 아이디어를 일반 팀에 가져왔습니다. 부모 폴더의 .meta 파일이 자식 리포지토리를 나열하고, 하나의 명령어가 그들 전체에서 실행되도록 했습니다.
한 문장으로 요약하면 메타-리포지토리(meta-repo)란: 많은 리포지토리를 유지하되, 하나의 클론과 하나의 운영 인터페이스를 제공하는 것입니다.
이것이 가능하게 하는 것들:
- 하나의 클론. 새로운 머신, 새로운 팀원, CI 작업: 단 하나의 명령으로 전체 시스템(fleet)이 디스크에 올바른 경로로 준비됩니다.
- 작동할 수 있는 하나의 장소. 풀(Pull), 상태 확인, 스크립트 실행, 모든 것을 대상으로 grep 검색. 위키에서 복사해 붙여넣은 셸 루프가 아닙니다.
- 전체 시스템에 대한 하나의 설명서. 매니페스트(manifest)는 무엇이 존재하고, 어디에 위치하며, 어떤 용도로 사용되는지를 나열한 목록입니다.
변하지 않는 것은 다음과 같습니다: 각 리포지토리는 자체적인 히스토리, CI, 권한, 소유자 및 릴리스 주기를 유지합니다.
모노레포(Monorepo), 서브모듈(submodules), 메타-리포(meta-repo)
**모노레포(monorepo)**는 모든 것을 하나의 리포지토리로 병합합니다. 하나의 히스토리, 하나의 CI, 프로젝트 전반에 걸친 원자적 변경이 가능합니다. 첫날부터 선택한다면 훌륭하지만, 이미 자체 파이프라인과 소유자가 있는 195개의 리포지토리가 존재하는 상황에서는 채택하기 어렵습니다. 마이그레이션 자체가 별도의 프로젝트가 됩니다.
**Git 서브모듈(submodules)**은 리포지토리를 분리된 상태로 유지하지만, 각 자식(child)을 부모 리포지토리 내의 특정 커밋에 고정합니다. 이는 알려진 버전으로 의존성(dependency)을 벤더링(vendoring)하는 데 유용합니다. 하지만 독립적으로 출시되는 서비스가 200개라면, 항상 최신 상태를 유지하지 못하는 부모 리포지토리가 되고, git submodule update는 일종의 의식이 됩니다.
**메타-리포(meta-repo)**는 리포지토리를 분리된 상태로 유지하며 아무것도 고정하지 않습니다. 부모는 어떤 커밋에 있는지가 아니라 어떤 리포지토리들이 존재하고 어디에 위치하는지만 알고 있습니다. 각 자식은 자체 속도로 움직입니다. 상위 계층(layer)은 단지 조정 역할만 합니다.
이것이 중간 지점입니다. 하지만 도구화 측면에서는 이 부분이 취약해지는 경향이 있습니다.
클래식 도구가 ~200개 규모에서 어려움을 겪는 이유
스크립트 기반의 메타 도구(meta tools)가 적절한 형태입니다. 그러나 이 규모에서는 몇 가지 요소들이 추가되는 것이 아니라, 핵심 기능으로 갖춰져야 합니다:
- 이름 목록을 나열하는 방식이 아닌 의도(
가장 마지막 것은 새로운 것입니다. 2년 전에는 아무도 이것을 요구하지 않았습니다. 오늘날 그것은 제가 메타-리포지토리를 찾게 만드는 이유입니다.
overrepo의 기능
overrepo.yaml에서 플릿(fleet)을 한 번에 설명합니다: 경로, URL, 태그, 그리고 리포지토리별 선택적 설명이 있습니다. 그런 다음:
overrepo init # 디스크에 이미 있는 리포지토리로부터 매니페스트를 빌드합니다.
overrepo sync # 누락된 것을 클론합니다.
overrepo status --dirty # 로컬 변경 사항은 무엇인가요?
...
선택(Selection)은 모든 명령어에서 동일하게 작동합니다: --tags, --paths, --projects, 또는 --all. 기준들은 AND로 결합됩니다. exec는 선택 없이 실행을 거부하므로, 실수로 모든 곳에 무언가를 실행할 수 없습니다.
아무도 195개의 매니페스트 항목을 손으로 작성하고 싶어 하지 않습니다. import는 stdin에서 JSON 카탈로그를 읽습니다. GitHub CLI와 jq를 사용하면 리포지토리 토픽이 태그가 됩니다:
gh repo list acme --limit 1000 --json name,sshUrl,description,repositoryTopics \
| jq '{projects: map({name: .name, url: .sshUrl, desc: .description, tags: ((.repositoryTopics // []) | map(.name))})}' \
...
다음 달에 다시 실행하면, 편집 내용을 건드리지 않고도 새로운 리포지토리들을 가져옵니다.
맵(map): AI 에이전트를 위한 컨텍스트
이 부분이 저에게 가장 중요합니다.
하나의 리포지토리에 투입된 에이전트는 하나의 리포지토리만 볼 수 있습니다. API를 변경하라고 요청하면, 다른 194개의 리포지토리 중 어떤 것이 그 API를 호출하는지 전혀 알지 못합니다.
- **각 리포지토리별 마크다운 요약본(One Markdown summary per repository)**을 매니페스트(manifest) (이름, 경로, 원격 저장소, 태그, 설명)와 해당 리포지토리를 기반으로 생성합니다.
- 전체 목록을 나열하는 **
index.md**를 제공하여 에이전트가 195개의 항목을 한 번에 스캔하고 중요한 세 가지를 선택할 수 있게 합니다. - 설정한
summary.outDir폴더 옆에 요약본을 출력합니다. 이 요약본들을 버전 관리하고, 어시스턴트의 지침(instructions)을 해당 폴더로 지정하면 됩니다.
이 맵을 신뢰할 수 있게 만드는 두 가지 세부 사항이 있습니다:
- 요약본은 각 클론의
origin/HEAD에서 읽어옵니다. 사용자의 더티 로컬 체크아웃(dirty local checkout), 미완성 브랜치 또는 디버그 해킹 내용이 에이전트가 진실이라고 믿는 정보에 절대 새어나가지 않습니다. - CI 환경에서는, 요약본이 오래되었을 경우
overrepo context --check가 실패합니다.--prune은 사라진 리포지토리의 요약본을 제거합니다. 이 맵은 조용히 부패하지 않습니다.
결과는 간단합니다: 에이전트는 먼저 인덱스를 읽고, 그 다음 올바른 리포지토리를 엽니다. 헤매는 시간이 줄어들고, 잘못된 추측이 줄어들며, 컨텍스트 창(context windows) 크기가 작아집니다. 원래 인간을 위해 작성했을 태그와 설명이 이제 기계의 탐색 수단이 됩니다.
최악의 날을 대비하여 (Built for the bad day)
200개의 리포지토리가 있다면, 항상 무언가 고장 난 것이 있습니다. overrepo는 이를 가정합니다:
- 하나의 리포지토리가 실패하더라도 다른 리포지토리에는 영향을 주지 않습니다. 종료 코드(exit code)를 통해 무엇이 실패했는지 알려줍니다.
- Git은 절대 프롬프트하지 않습니다. SSH는 배치 모드(batch mode)로 실행됩니다.
- 일시적인 네트워크 오류에 대해서는 타임아웃 및 백오프(backoff)를 사용한 재시도 기능을 제공합니다.
- 클론된 내용은
..overrepo-partial디렉토리에 위치하며, 완료될 때만 제자리를 찾습니다. 절반만 클론되어 실제인 척하는 리포지토리는 없습니다.
overrepo doctor는 git, 원격 접근(remote access), 매니페스트, 누락된 클론, 고아 리포지토리(orphan repositories) 및 중단된 클론을 확인합니다.
요구 사항: PATH에 Node.js와 git이 설치되어 있어야 합니다. 그것뿐입니다.
핵심 요약 (The takeaway)
- 메타-레포(meta-repo)는 오래된 아이디어입니다: 많은 레포지토리, 하나의 매니페스트, 하나의 클론, 행동할 수 있는 한 곳.
- 이는 모노레포(monorepo)가 아니며 (병합된 히스토리가 없음), 서브모듈(submodules)도 아닙니다 (고정된 커밋이 없음). 각 레포지토리는 독립적으로 유지됩니다.
- 약 200개의 레포지토리 규모에서, 매니페스트 자체가 제품입니다: 경로, URL, 태그, 설명이 하나의 일반 YAML 파일에 담겨 있습니다.
- 기억에 의존하는 것이 아니라 태그나 경로로 선택합니다. 실패를 가정합니다: 격리된 오류, 프롬프트 없음, 원자적 클론(atomic clones).
- 에이전트들에게 지도를 제공하세요. 기본 브랜치에서 생성되고, 버전 관리되며, CI에서 확인됩니다.
- 작업에 필요한 것만 클론합니다. 에이전트들이 새로운 클라우드 VM에서 실행될 때 매우 중요합니다.
아직 베타 단계이며, 여러분의 도움이 필요합니다
npm install -g overrepo
overrepo는 여전히 베타 버전입니다. MIT 라이선스이며, 실제 195개 레포지토리 규모의 플릿에서 작동하며, 제가 아직 사용해보지 않은 여러분의 플릿에서는 발견하지 못한 미흡한 부분이 있습니다.
이것이 바로 지금 피드백이 중요한 이유입니다. 모양을 쉽게 바꿀 수 있는 시기이기 때문입니다. 만약 수십 개 또는 수백 개의 레포지토리를 다루고 있다면, 사용해보고 무엇이 깨지는지, 무엇이 빠져 있는지, 지도가 무엇을 포함해야 하는지 알려주세요. 이슈(Issues), 아이디어 및 풀 리퀘스트(Pull requests) 모두 환영합니다. GitHub에서 함께 만들어 봅시다: github.com/maximeshr/overrepo. 패키지는 npm에 있습니다.
저는 Maxime입니다. 예전에는 코드를 작성했지만, 이제는 주방을 운영합니다: 많은 코드베이스에 걸쳐 AI 에이전트를 오케스트레이션하고 에이전트 워크플로우를 확장하는 일을 합니다. 더 자세한 내용은 okq.me에서 확인하세요.
여기서 저를 팔로우하여 에이전트 친화적인 툴링 및 이야기에 대한 더 많은 내용을 얻고, 댓글로 여러분의 다중 레포지토리 설정 처리 방법을 알려주세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기