Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to treat a meta-repository of git repositories?

Tags:

git

Given a tree of git repositories in a project directory, e.g.

Projects/
+A/
|+.git/
+B/
|+.git

I'd like to set up a git repository Projects.git that does not track the project's contents but only their existence and status. Someone cloning this repository should only have a sekeleton of uncloned repositories A, B etc. and individually activate whether they are kept in sync or not. A typical workflow would look like this:

  • First time setup: git clone server:Projects.git
  • Activate project A, which also clones it
  • Now every git-push/pull, independently of whether it's in Projects/ or Projects/A should update both A.git and Projects.git's information about A. Anything related to B should be ignored since it's inactive and locally empty
  • Activate project B, cloning that as well
  • Now any git-push/pull in Projects should also do so in both A and B, while a push/pull in A should not influence B
  • Deactivate project A, which (after verifying A.git doesn't need a git-push) empties the local directory A, with no influence on Project.git

How can this be treated best? My current approach would be some hook-magic, but I'm not familiar enough with git submodules to see whether this could be achieved with submodules or whether I need to use some other solution.

like image 984
Tobias Kienzler Avatar asked Oct 08 '12 09:10

Tobias Kienzler


3 Answers

The 'meta' tool is fantastic for this.

You can find it on npm: https://www.npmjs.com/package/meta

You can use it to clone a meta-repo and all sub-repos at once which is great.

You then use it to apply operations to all your sub-repos, eg to pull your meta-repo and all sub-repos:

cd my-repo
meta git pull

There's an article here with help to get started and use 'meta': https://medium.com/@patrickleet/mono-repo-or-multi-repo-why-choose-one-when-you-can-have-both-e9c77bd0c668

like image 59
Ashley Davis Avatar answered Sep 21 '22 10:09

Ashley Davis


This is indeed what submodules are for:
Tracking the exact configuration (ie the exact commit SHA1) of each subrepos.

As detailed in "How do I git clone --recursive and checkout master on all submodules in a single line?", you can clone your parent repo and all its submodules in one command.

As explained in "True nature of submodules", you can modify them provided you realize that each one is in a DETACHED HEAD mode (you need to checkout a local branch first), and that you need to commit and push in the submodule first, before going back to the parent repo, commit and push there (to record the new configuration, ie the new submodules SHA1)

You can remove a submodule directory without damaging the parent repo references to that submodule.


The OP Tobias Kienzler comments:

It sounds kind of what I want, but the detached head is rather useless in this case - when I clone a submodule, it should be at it's master head.
Basically I'm looking for a way to have a local index of all projects available without having to clone them individually, and a "sync all projects that are currently cloned" all-in-one command.

I suggests having a look at git-slave:

Gitslave creates a group of related repositories—a superproject repository and a number of slave repositories—all of which are concurrently developed on and on which all git operations should normally operate;
so when you branch, each repository in the project is branched in turn.
Similarly when you commit, push, pull, merge, tag, checkout, status, log, etc; each git command will run on the superproject and all slave repositories in turn.

like image 24
VonC Avatar answered Sep 22 '22 10:09

VonC


why not use what git already provides:

git submodule [--quiet] foreach [--recursive]

git submodule foreach git checkout develop
git submodule foreach git commit
git submodule foreach git push
like image 39
Daimon Rasmussen Avatar answered Sep 21 '22 10:09

Daimon Rasmussen