Asti's Notes
Sync git modules to .gitmodules
And a tale of git in Powershell

.gitmodules is not git submodules

A .gitmodules file is sort of indicative - it’s not what actually is being tracked by Git. When you start a new project, and you have to include a bunch of submodules, you may think of starting off by copying and editing a .gitmodules file with all the submodules you want, but that literally does nothing.

You’ll find out that you have to git submodule add everything by hand. Well, we could just automate that.

Reading .gitmodules

Git has some commands to help us read .gitmodules. It’s behind git config --file.

Let’s get all the keys first.

git config --file .gitmodules --list

That was easy. We got a list of keys. And to get a value for a specific key:

function lookup($key, $defaultValue = "") {        
	$value = git config --file $gitmodules --get "$key" 2>&1 
	if($LASTEXITCODE -ne 0) { $defaultValue } else { $value }

Extracting submodules

We just get a list of the unique submodules, and lookup the keys for path, url and branch (if it exists).

all | 
foreach { $_ -split "\."  | select -Index 1 } | 
select -Unique |
foreach {[pscustomobject]@{ 
	Path = lookup "submodule.$_.path"; 
	Url = lookup "submodule.$_.url";  
	Branch = lookup "submodule.$_.branch" "master";

That gives us something like this:

Path               Url                                                      Branch  
----               ---                                                      ------  
stm32-core         STM32F03
src/rtt                  master  
src/node           master  
src/sens           master  
rtt                      master  

Pretty neat.

std from PowerShell

While all that remains is call git submodule add with the parameters we just found, you will quickly run into a problem:

git : Cloning into 'D:/Experiments/Subtest/src/rtt'...
At D:\Experiments\Subtest\SyncSubmodules.ps1:29 char:9
+         git submodule add $sub.Url $sub.Path
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Cloning into 'D...est/src/rtt'...:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

There is actually no error here - PowerShell thinks that any output in stderr is due to an error. Even if we redirect stderr, the stderr stream will end up propagating downstream. In order to avoid this, we redirect then reproject every element to an stdout stream.

2>&1 | foreach { "$_" }

So our add becomes:

git submodule add $sub.Url $sub.Path 2>&1 | foreach { "$_" }

Now that we all that pieces, we can make the module.


cd to path with .gitmodules


Last modified on 2019-06-17