How do I init submodules nested in a subtree?
Asked Answered
P

1

13

Apparently, adding a subtree of a repository that has submodules will break git submodule init. Here is a script which reproduces the problem:

#!/bin/sh
set -ex

mkdir submod
cd submod
git init
touch foo
git add foo
git commit -asm "This is a submodule"
cd ..

mkdir subtree
cd subtree
git init
git submodule add `realpath ../submod` submod
git commit -asm "This has reference to submodule"
cd ..

mkdir top
cd top
git init
touch bar
git add bar
git commit -asm "Dummy commit so HEAD resolves correctly"
git subtree add --prefix=subtree `realpath ../subtree` master

# This fails!
git submodule init

What this script is doing is:

  1. Create a repo submod
  2. Create a repo subtree that has a submodule reference to submod
  3. Create a repo top that has a subtree reference to subtree

Upon further consideration, it is clear what the problem is: the subtree mechanism has added subtree's submodule reference to submod to the tree, but the .gitmodules metadata remains in subtree/.gitmodules, not the top-level .gitmodules, which means that git submodule init fails. If we copy the contents of subtree/.gitmodules to .gitmodules, adjusting all the paths accordingly, that solves the problem...

[submodule "submod"]
    path = subtree/submod
    url = /Users/ezyang/Dev/labs/git-subtree-submod/submod

...but it is a bit of pain if the subtree has a lot of submodules. Is there a better way to do this?

Pease answered 31/7, 2017 at 18:16 Comment(2)
Did you find the answer? I have the exact same situation :)Sigrid
We stopped using subtrees lolPease
C
5

From what I can tell reading the docs and source code... Git subtree is completely separate from Git submodules and will not actively manage any submodules that may be contained within the subtree project itself.

As you found out, .gitmodules, which is critical to the function of git submodule init, needs to be maintained in the root of the "main" repository (for lack of a better term).

Upon further consideration, it is clear what the problem is: the subtree mechanism has added subtree's submodule reference to submod to the tree, but the .gitmodules metadata remains in subtree/.gitmodules, not the top-level .gitmodules, which means that git submodule init fails. If we copy the contents of subtree/.gitmodules to .gitmodules, adjusting all the paths accordingly, that solves the problem...

I strongly recommend not mixing these features.

Condottiere answered 25/2, 2020 at 16:1 Comment(2)
You might be able to cobble together a solution for copying the subtree .gitsubmodules into the main repository with the subtree merge strategy (not the subcommand) and filter-branch... but that seems like a nightmare. Also, you wouldn't be able to merge multiple subtree .gitsubmodules.Condottiere
Honestly, I copied the .gitmodules file from the subtree root to the root repo root and edited the name of the submodule and path and it works just fine. I don't see what all the fuss is about.Coldiron

© 2022 - 2024 — McMap. All rights reserved.