meta icon indicating copy to clipboard operation
meta copied to clipboard

Support DVCS

Open pboling opened this issue 2 years ago • 6 comments

🚀 Feature Proposal

DVCS, or Distributed Version Control Systems, like git, allow for code to be hosted in a distributed manner. I am now beginning to replicate my projects on 2, 3, 4 (more?!?) different source forges. I am also starting to convert at least one of these projects into a "distributed" meta repo using this tool (🛖1, 🧊2, 🧪3, 🐙4!).

My goal is for each sub-project to push to an "all" instead of an "origin", where "all" targets several remote repositories.

Motivation

Without this feature it seems that I'll need to not use most of this project's features and run lots of manual commands on each sub-project.

Example

meta git push all would push to all.

Of course I can already do meta exec git push all... So this feature request is about how to configure the multi-repo'd projects.

Currently we have:

meta project create [folder] [repo]
meta project import [folder] [repo]

I'd like to have a way to run the necessary commands (as in my summary article already linked) to setup the "all" remote with many target repos. Perhaps a new command distribute:

meta project distribute [folder (existing project)] [repo (new)] [remote name (default "all")]

And that would run something like this:

cd [folder]
git remote add all [original repo] # See NOTES.1 and NOTES.2
git remote set-url --add --push [remote name] [repo] && \
 

NOTES:

  1. It would need to determine the original repo URL first, to add it as the first member of "all".
  2. It will be easiest to do this every time distribute is run. If "all" already exists it will just fail that command, as follows:
❯ git remote add all git://original/repo.git
error: remote all already exists.
  1. It will do the wrong thing if you add the original again as a push target, which you need to do only the first time you add a new push target to all. It will add the same push target multiple times.
❯ git remote add all [email protected]:pboling/require_bench.git
❯ git remote set-url --add --push all git://another/repo.git
# Original has to be added back, because previous command removed it 🤦 
❯ git remote set-url --add --push all [email protected]:pboling/require_bench.git
# Search for Original repo to ensure it is added back as a push target
❯ git remote -v | egrep "all\s+git@github\.com:pboling\/require_bench\.git\s+\(push\)"
all	[email protected]:pboling/require_bench.git (push)

# First time around, ^ is fine, as the original is a fetch and push target 1x each.
# But, the next time around, it doesn't work so well, so you'd need to test if the original repo is already a push url:
❯ git remote set-url --add --push all git://yet-another/repo.git
# Somehow detect if the original is already present as a push target, and only add it back if missing.

pboling avatar Apr 15 '23 07:04 pboling

I set one of the repos in my meta repo linked above as an array with two git repos to see what it would do.

> meta git update
...
/Users/pboling/src/meta/rubocop-lts: command 'git clone [email protected]:rubocop-lts/rubocop-lts.git,[email protected]:rubocop-lts/rubocop-lts.git rubocop-lts' exited with error: Error: Command failed: git clone [email protected]:rubocop-lts/rubocop-lts.git,[email protected]:rubocop-lts/rubocop-lts.git rubocop-lts

That's pretty dense, but the command that ran was:

git clone [email protected]:rubocop-lts/rubocop-lts.git,[email protected]:rubocop-lts/rubocop-lts.git rubocop-lts

And the problem is obviously that it ran a single command with both git repos, instead of the set of commands to add the additional repos after the first as push targets.

pboling avatar Apr 15 '23 10:04 pboling

interesting - wasn't aware you could have multiple push targets for a remote.

meta-project is mostly just executing commands in child processes, so doesn't sound too difficult to create theoretically

patrickleet avatar Apr 19 '23 20:04 patrickleet

git push all is my new favorite thing, and I can push to all my DVCS remotes at once!

pboling avatar Apr 20 '23 00:04 pboling

Found a sequence of commands that may be helpful. Requires grep and cut, but those are fairly universal on POSIX machines. git remote -v | grep origin | grep fetch | cut -w -f2

Used like this:

❯ git remote -v
all	[email protected]:rubocop-lts/meta.git (fetch)
all	[email protected]:~galtzo/rubocop-lts-meta (push)
all	[email protected]:rubocop-lts/meta.git (push)
all	[email protected]:rubocop-lts/meta.git (push)
all	[email protected]:rubocop-lts/meta.git (push)
origin	[email protected]:rubocop-lts/meta.git (fetch)
origin	[email protected]:rubocop-lts/meta.git (push)
❯ orig=$(git remote -v | grep origin | grep fetch | cut -w -f2)
❯ echo $orig
[email protected]:rubocop-lts/meta.git

pboling avatar Apr 20 '23 02:04 pboling

all is just a name though, right? you could set up origin to push to many as well?

patrickleet avatar Apr 20 '23 16:04 patrickleet

Yeah, correct; technically origin is just a name as well, just very common due to it being a default value.

pboling avatar Apr 20 '23 17:04 pboling