Search code examples
gitrepositoryrepo

Howto use repo tool to mirror a project composed of several git repositories


I want to make a fork of a project composed of several .git repos, pushing all of them to different (local) repositories, but maintaining exactly the same set of branches and tags for each individual git repo.

This project is initially downloaded using the "repo" tool. There is a manifest.xml file describing the location of each single .git repository, downloaded with repo init, and then repo sync clones all the git repos.

I will use bitbucket.com in this example, but don't focus the attention on bitbucket, is just an example.

This are the steps I am doing right now:

  1. Create an empty manifest.git repository in bitbucket. Then:

    cd existing-manifest.git
    git remote set-url origin ssh://git@bitbucket.com/project/manifest.git
    git push -u origin --all
    git push origin --tags
    
  2. Create the set of git repos manually inside bitbucket. Then:

    #! /bin/sh
    for LINE in $(repo forall -c 'echo ${REPO_PROJECT}":"${REPO_PATH}')
    do
        REPO_PROJECT=$(echo $LINE | cut -f 1 -d ":")
        REPO_PATH=$(echo $LINE | cut -f 2 -d ":")
        pushd $REPO_PATH
        git remote add origin ssh://git@bitbucket.com/project/${REPO_PROJECT}.git
        git push -u origin --all
        git push origin --tags
        popd
    done
    

After that, edit the manifest.xml manually to change the default remote of each project and commit the new manifest.xml in my custom repo.

This is a very manual process, not very friendly. So my questions are:

  1. Can this process be improved in some way?
  2. Is possible just using the "repo" tool?

Solution

  • The 2nd step can be improved. repo forall is enough and you don't need to wrap it with for.

    repo forall -p -c 'git remote add origin ssh://git@bitbucket.com/project/${REPO_PROJECT}.git \
                       && git push -u origin --all --tags'
    

    The manifest.xml can have these tags and attributes,

    <remote fetch="ssh://git@bitbucket.com/project" name="origin" />
    <default remote="origin" revision="foo" />
    <project name=bar path=bar />
    

    which define a default remote origin, so that you don't need to specify the remote for every project unless one or more of them are hosted in other places. For the project bar, its default remote will be origin ssh://git@bitbucket.com/project/bar for both fetch and push.