Shallow clone of a submodule is perfect because they snapshot at a particular revision/changeset. It's easy to download a zip from the website so I tried for a script.
#!/bin/bash
git submodule deinit --all -f
for value in $(git submodule | perl -pe 's/.*(\w{40})\s([^\s]+).*/\1:\2/'); do
mysha=${value%:*}
mysub=${value#*:}
myurl=$(grep -A2 -Pi "path = $mysub" .gitmodules | grep -Pio '(?<=url =).*/[^.]+')
mydir=$(dirname $mysub)
wget $myurl/archive/$mysha.zip
unzip $mysha.zip -d $mydir
test -d $mysub && rm -rf $mysub
mv $mydir/*-$mysha $mysub
rm $mysha.zip
done
git submodule init
git submodule deinit --all -f clears the submodule tree which allows the script to be reusable.
git submodule retrieves the 40 char sha1 followed by a path that corresponds to the same in .gitmodules. I use perl to concatenate this information, delimited by a colon, then employ variable transformation to separate the values into mysha and mysub.
These are the critical keys because we need the sha1 to download and the path to correlate the url in .gitmodules.
Given a typical submodule entry:
[submodule "label"]
path = localpath
url = https://github.com/repository.git
myurl keys on path = then looks 2 lines after to get the value. This method may not work consistently and require refinement. The url grep strips any remaining .git type references by matching to the last / and anything up to a ..
mydir is mysub minus a final /name which would by the directory leading up to the submodule name.
Next is a wget with the format of downloadable zip archive url. This may change in future.
Unzip the file to mydir which would be the subdirectory specified in the submodule path. The resultant folder will be the last element of the url-sha1.
Check to see if the subdirectory specified in the submodule path exists and remove it to allow renaming of the extracted folder.
mv rename the extracted folder containing our sha1 to its correct submodule path.
Delete downloaded zip file.
Submodule init
This is more a WIP proof of concept rather than a solution. When it works, the result is a shallow clone of a submodule at a specified changeset.
Should the repository re-home a submodule to a different commit, re-run the script to update.
The only time a script like this would be useful is for non-collaborative local building of a source project.