Git add remotes to submodules recursively
Asked Answered
A

1

3

I have a git repo located on my machine at /path/to/repo, which contains several submodules, /path/to/repo/submoduleA and /path/to/repo/foo/bar/submoduleB.

Due to a workflow that I cannot change, the git repo gets copied (as in scp -r) to a remote server, where I work on the code. I want to pull the changes back to the original machine. Cloning/pushing from the remote server isn't an option.

It is tedious to go to each submodule and do

git remote add <name> <url>:/server/path/to/repo/<path to submodule>

Is there a faster way? Something magical like

git remote add --submodules <name> <url>:/server/path/to/repo

executed from the top-level repo that will recurse to each submodule and add the appropriate relative path onto the remote of each submodule? git remote --help doesn't show anything useful, and neither the Git Pro Book section on submodules.

My best guess is something like

git submodule foreach 'git remote add <name> <url>:/server/path/to/repo/...'

might work, if there there is a way to replace the ... with the loop-dependent relative path of each submodule in that foreach. I just don't know of such a mechanism built into git submodule foreach

Arvonio answered 1/11, 2019 at 22:34 Comment(0)
P
1

git submodule foreach does include a list of variables which should help:

The command has access to the variables:

  • $name: the name of the relevant submodule section in .gitmodules,
  • $sm_path: the path of the submodule as recorded in the immediate superproject,
  • $displaypath: contains the relative path from the current working directory to the submodules root directory,
  • $sha1: the commit as recorded in the immediate superproject, and
  • $toplevel: the absolute path to the top-level of the immediate superproject.

So in your case:

git submodule foreach 'git remote add $name <url>:/server/path/to/repo/$sm_path'

$displaypath would replace the ... with the loop-dependent relative path of each submodule.
But, as noted by the OP waldol1 in the comments, $sm_path is a fixed value, as opposed to a relative path.

Example with docker/docker.github.io, executed in the subfolder tests:

D:\git\docker.github.io\tests>git submodule foreach "echo $displaypath"
Entering 'src/github.com/gdevillele/frontparser'
src/github.com/gdevillele/frontparser

vs.

D:\git\docker.github.io\tests>git submodule foreach "echo $sm_path"
Entering 'src/github.com/gdevillele/frontparser'
tests/src/github.com/gdevillele/frontparser
Prindle answered 2/11, 2019 at 0:12 Comment(2)
Thanks, this looks promising. Just to double check my understanding, if I execute the foreach from /path/to/repo, then $sm_path == $diplaypath, right? But if I execute it from a different directory, then they aren't equal, but $sm_path is what I'd need, so wouldn't it be more flexible to just do git submodule foreach 'git remote add $name <url>:/server/path/to/repo/$sm_path'?Arvonio
@Arvonio I confirm your understanding, and I have edited the answer accordingly, with an example.Prindle

© 2022 - 2024 — McMap. All rights reserved.