Search code examples
gitgit-subtree

Push only part of git repository to second remote repository


I have an existing git repository (e.g. in my organisation's private repository) consisting of several sub-projects organised in specific folders. It there a way to clone each of these sub-projects to specific second remote repositories (e.g. on github)? I'm aware of git subtrees which seems to be convenient the other way around (having existing subprojects as dependencies in a new overall project). However, using subtree would require me to remove the sub-projects from the existing overall project and add them as subtrees again, if I understand correctly.

A requirement is to be able to push the entire project including its sub-projects to the private organisation's remote repository, to achieve a working version there.


Solution

  • Have you read the subtree docs?

      split [<local-commit>]
          Extract a new, synthetic project history from the history of the <prefix> subtree of <local-commit>,
          or of HEAD if no <local-commit> is given. The new history includes only the commits (including
          merges) that affected <prefix>, and each of those commits now  has the contents of <prefix> at the
          root of the project instead of in a subdirectory. Thus, the newly created history is suitable for
          export as a separate git repository.
    

    Sounds like what you want.

    Here's a worked example;

    Init a demo repo;

    mkdir subtree-split
    cd subtree-split/
    git init
    git commit -m "Init." --allow-empty
    

    Add some content for project A;

    mkdir A
    touch A/README.txt
    git add A/
    git commit -m "Readme for A."
    

    Add some content for project B;

    mkdir B
    touch B/README.txt
    git add B/
    git commit -m "Readme for B."
    

    Split off B as a new subtree;

    git subtree --prefix=B/ split 
    

    Make a new repository to push just the history of B to;

    cd ..
    mkdir subtree-B
    cd subtree-B
    git init
    git commit -m "Init subtree-B." --allow-empty
    

    Push the subtree B history to the remote;

    cd ../subtree-split/
    git subtree --prefix B/ push ../subtree-B HEAD
    

    Check the history of B;

    cd ../subtree-B
    git log --all  --pretty=oneline --abbrev-commit
    a26e5de (HEAD -> master) Init subtree-B.
    0523c62 (HEAD) Readme for B.
    

    No history of A!