repo 저장소 구성 실습
구글 repo
툴에서 사용되는 Manifest 작성과 Git 저장소 구성 방법을 정리해 본다.
repo 특징
repo는 프로젝트가 여러 개의 Git 저장소로 구성된 경우에 편리하게 Git 저장소를 관리할 수 있도록 구글에서 Python으로 작성한 스크립트로, Manifest 파일을 이용하여 슈퍼 프로젝트에 여러 Git 프로젝트들을 나열할 수 있다.
참고 페이지
- repo 명령: repo 명령 참조
- repo Manifest 형식: repo Manifest Format 참조
repo 설치
- 아래와 같이 사용자 디렉토리에서 최신 버전으로 설치할 수 있다.
$ mkdir ~/bin $ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo $ chmod a+x ~/bin/repo
이후 ~/bin/ 경로를 PATH에 추가하면 된다.
이 경로로 repo가 실행될 때마다 자동으로 repo 버전을 검사해서 만약에 버전이 업데이트 되었으면 자동으로 repo 파일이 업데이트된다.
- 또는 아래 예와 같이 시스템 경로에 패키지로 설치할 수 있다.
$ sudo apt install repo
그런데 이 방법은 자동으로 repo가 최신 버전으로 업데이트되지 않는 문제가 발생한다. (
apt update
를 실행해도 마찬가지인데, 이는 APT 저장소에서 repo가 최신 버전으로 유지되지 않기 때문임)
그래서 나는 대안으로 자동으로 repo가 최신 버전으로 업데이트되도록 아래와 같이/root/repo_update.sh
파일을 자작하였다.#!/bin/sh curl https://storage.googleapis.com/git-repo-downloads/repo > /root/repo chmod +x /root/repo LATEST_REPO_VER=`/root/repo --version | grep "repo launcher version" | cut -d' ' -f4` SYSTEM_REPO_VER=`repo --version | grep "repo launcher version" | cut -d' ' -f4` UPDATED=`echo "$LATEST_REPO_VER > $SYSTEM_REPO_VER" | bc` if [ $UPDATED == 1 ]; then mv /root/repo /usr/bin/ else rm /root/repo fi
위 스크립트는 구글 저장소에 있는 repo와 시스템에 설치된 repo의 버전을 비교하여, 만약 구글 저장소에 있는 repo가 더 최신 버전이면 구글 저장소에 있는 repo를 시스템에 설치하는 일을 수행한다.
자동으로 위 스크립트가 매일 정해진 시간에 실행되도록 아래와 같이 root의 cron을 수정하였다.$ sudo crontab -e
여기에서 매일 새벽 4시에 해당 스크립트를 실행하도록 아래와 같이 추가하였다.
0 4 * * * /root/repo_update.sh
repo 저장소 구성, manifest 실습
- GitLab에서 빈 저장소를 생성한다. 예로 https://localhost/gitlab/test/manifest 저장소를 생성한다. (저장소 이름이 꼭 manifest라야 하는 것은 아니고, 자유롭게 사용 가능함)
- 생성한 저장소를 아래와 같이 clone 받은 후, 해당 디렉토리로 이동한다.
$ git clone https://localhost/gitlab/test/manifest.git $ cd manifest/
- 해당 디렉토리에서 Manifest 파일의 디폴트 이름인 default.xml 파일을 아래 예와 같이 작성한다.
<?xml version="1.0" encoding="UTF-8"?> <manifest> <remote name="origin" fetch="https://localhost/gitlab"/> <default revision="master" remote="origin"/> <project path="dir1" name="git_repo1.git"/> <project path="dir2" name="git_repo2.git"/> </manifest>
위 예는 https://localhost/gitlab/git_repo1.git 저장소를 dir1 디렉토리로, https://localhost/gitlab/git_repo2.git 저장소를 dir2 디렉토리로 clone 받는 예이다. (물론 이들 저장소는 이미 존재하는 저장소라야 함)
- 참고로 위에서 사용한 manifest 엘리먼트들의 의미는 다음과 같다.
<remote>
: 원격 저장소 정보 (하나 이상 기술할 수 있음)- name: 원격 저장소 이름 [required]
- fetch: Git URL prefix [required]
<default>
: project 엘리먼트에 없으면 여기 정보를 사용함 (오직 하나만 기술할 수 있음)- revision: Git branch 이름 [required]
- remote: remote element에 정의된 원격 저장소 이름 [required]
<project>
: 각 Git 프로젝트 정보 (하나 이상 기술할 수 있음)- path: Base 경로에서의 이 상대 경로에 프로젝트 소스가 clone 됨, 만약 이 속성이 없으면 project의 name 속성이 사용됨 [optional]
- name: 프로젝트의 고유한 이름, remote의 fetch URL에 추가하여 사용됨 [required]
- 위 default.xml 파일을 아래와 같이 commit 한다.
$ git add default.xml $ git commit -m "Add default.xml" $ git push -u origin master
- 이제 repo를 실험할 디렉토리를 생성하여 해당 디렉토리로 이동한 후, 아래와 같이 repo init를 실행한다.
$ repo init -u https://localhost/gitlab/test/manifest.git
결과로 .repo 디렉토리가 생성되었음을 확인할 수 있다.
참고로 repo init 명령시 본 예제에서는 Manifest 파일의 이름을 디폴트인 default.xml 이름으로 사용하였으므로
-m
옵션이 필요없으나, 만약에 다른 이름을 사용한 경우에는-m
옵션으로 지정해 주어야 한다. - 이후 아래와 같이 repo sync를 실행하면 각각의 Git 프로젝트를 clone 한 효과가 발생한다. (아래에서
--no-clone-bundle
옵션은 clone.bundle 관련 warning 메시지가 출력되지 않기 위해 추가하였음)$ repo sync --no-clone-bundle
결과로 default.xml 파일에서 project path로 지정된 디렉토리에 각각 name으로 지정된 저장소를 clone 해 왔음을 아래와 같이 확인할 수 있다.
$ ls -F dir1/ dir2/
정리
알겠지만 AOSP(Android Open Source Project) 등의 프로젝트에서 repo를 사용하고 있는데, 사내 프로젝트 등에서도 필요에 따라 적용할 수 있을 것 같다.
repo 저장소를 구성해 보기 위해서 구글링했더니, repo의 사용법은 많이 나와 있었지만 정작 저장소 구성 관련은 찾기가 힘들었다. 직접 repo 저장소를 구성해 보고 테스트하면서 방법을 알고 나니 간단하였다. 😋