repo 저장소 구성 실습

구글 repo 툴에서 사용되는 Manifest 작성과 Git 저장소 구성 방법을 정리해 본다.

repo 특징

repo는 프로젝트가 여러 개의 Git 저장소로 구성된 경우에 편리하게 Git 저장소를 관리할 수 있도록 구글에서 Python으로 작성한 스크립트로, Manifest 파일을 이용하여 슈퍼 프로젝트에 여러 Git 프로젝트들을 나열할 수 있다.

참고 페이지

repo 설치

  1. 아래와 같이 사용자 디렉토리에서 최신 버전으로 설치할 수 있다.
    $ mkdir ~/bin   
    $ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
    $ chmod a+x ~/bin/repo
    

    이후 ~/bin/ 경로를 PATH에 추가하면 된다.

    이 경로로 repo가 실행될 때마다 자동으로 repo 버전을 검사해서 만약에 버전이 업데이트 되었으면 자동으로 repo 파일이 업데이트된다.

  2. 또는 아래 예와 같이 시스템 경로에 패키지로 설치할 수 있다.
    $ 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 실습

  1. GitLab에서 빈 저장소를 생성한다. 예로 https://localhost/gitlab/test/manifest 저장소를 생성한다. (저장소 이름이 꼭 manifest라야 하는 것은 아니고, 자유롭게 사용 가능함)
  2. 생성한 저장소를 아래와 같이 clone 받은 후, 해당 디렉토리로 이동한다.
    $ git clone https://localhost/gitlab/test/manifest.git
    $ cd manifest/
    
  3. 해당 디렉토리에서 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 받는 예이다. (물론 이들 저장소는 이미 존재하는 저장소라야 함)

  4. 참고로 위에서 사용한 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]
  5. 위 default.xml 파일을 아래와 같이 commit 한다.
    $ git add default.xml
    $ git commit -m "Add default.xml"
    $ git push -u origin master
    
  6. 이제 repo를 실험할 디렉토리를 생성하여 해당 디렉토리로 이동한 후, 아래와 같이 repo init를 실행한다.
    $ repo init -u https://localhost/gitlab/test/manifest.git
    

    결과로 .repo 디렉토리가 생성되었음을 확인할 수 있다.

    참고로 repo init 명령시 본 예제에서는 Manifest 파일의 이름을 디폴트인 default.xml 이름으로 사용하였으므로 -m 옵션이 필요없으나, 만약에 다른 이름을 사용한 경우에는 -m 옵션으로 지정해 주어야 한다.

  7. 이후 아래와 같이 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 저장소를 구성해 보고 테스트하면서 방법을 알고 나니 간단하였다. 😋

카테고리:

업데이트: