Search code examples
gitgithubchef-infragit-submodules

Manage different codebases using single git repository instead of submodules


After reading this article on submodules, it seems like they exist only to link to external git repositories from within your own. However, I am expecting submodules to simply allow you to manage multiple, separate commit histories from within one repository.

Is it possible to have non-external git repositories? I'd like to manage all of my chef cookbooks under one repository with separate commit histories for each, without needing to create a bunch of git repos

EDIT: I don't think I made my use case clear. What I meant was that I wanted to have the list of cookbooks for each of my servers in uniquely addressable places; not that I wanted a submodule for an individual cookbook. In this case, mu's answer addresses the problem quite effectively.


Solution

  • Yes, you can do so using orphan branches. The orphan branch will start afresh from a new parent, so it won't have any commits in common with any other branch.

    This way, you can have multiple branches, each corresponding to a different commit history for your respective cookbook.

    So all you need to do is:

    git checkout --orphan newbranch
    

    From the git checkout man page:

    --orphan <new_branch>

    Create a new orphan branch, named <new_branch>, started from <start_point> and switch to it. The first commit made on this new branch will have no parents and it will be the root of a new history totally disconnected from all the other branches and commits.

    FWIW, you can push completely unrelated branches between repositories, all you need to ensure is that the branch names space doesn't collide.

    So, for example, if you have 2 existing cookbook repositories, cookbook1 and cookbook2, create a new repository cookbook, add this repository cookbook as a remote in the existing repositories using git remote add cookbook url/to/cookbook, and now you can push your existing repo history to this repo using cd cookbook1 && git push cookbook master:cookbook1 and cd cookbook2 && git push cookbook master:cookbook2

    NOTE: As others have pointed out already, it makes more sense to have individual repos for each cookbook, so only use this approach if it matches your use case completely.