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?

2
  • Did you find the answer? I have the exact same situation :) Commented Aug 13, 2019 at 17:46
  • 3
    We stopped using subtrees lol Commented Aug 13, 2019 at 22:12

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.