Pushing submodules recursively throws "fatal: src refspec must name a ref" if containing project is not on master branch
Asked Answered
P

1

20

I have a git repository with three submodules. The containing repository has two branches master and develop. All submodules only have one branch – the master branch.

When the containing repository is on the master branch, pushing to origin via git push --recurse-submodules=on-demand works as expected. Both the containing project as well as its submodules are pushed.

Now here is the problem. When the containing repository is on the develop branch, I am getting a problem when pushing via git push --recurse-submodules=on-demand. The push operation is cancelled and an error message is printed.

Here is the full output I get from git:

$ git push --recurse-submodules=on-demand
fatal: src refspec 'refs/heads/develop' must name a ref
fatal: process for submodule 'Frameworks/OpenLearnWareClient' failed

I can mitigate this problem by first pushing changes in each submodule manually and then pushing the containing repository. This however is very tedious and defeats the purpose of --recurse-submodules=on-demand.

Here is my .gitmodules file:

[submodule "Frameworks/OpenLearnWareKit"]
    path = Frameworks/OpenLearnWareKit
    url = [email protected]:kaiengelhardt/OpenLearnWareKit.git
    branch = master
[submodule "Frameworks/OpenLearnWareClient"]
    path = Frameworks/OpenLearnWareClient
    url = [email protected]:kaiengelhardt/OpenLearnWareClient.git
    branch = master
[submodule "Frameworks/KEFoundation"]
    path = Frameworks/KEFoundation
    url = [email protected]:kaiengelhardt/KEFoundation.git
    branch = master

I am using git version 2.20.1 (Apple Git-117).

Does anybody know what is going wrong here and how to make recursive pushing work?

Pleadings answered 23/4, 2019 at 15:49 Comment(6)
this might be of some helpSynergist
@Synergist That’s what OP is already doing but it fails in this case.Crinum
This absolutely seems like a bug with git itself. Still getting this with git version 2.24.0 on macOS mojave. I don't know how to file a bug with git, but all anyone would need to do is link to this SO question.Romish
Just found out, I can successfully run git push --recurse-submodules=on-demand on my dev branch, and it successfully pushed a new commit to a submodule. (Note: no PR workflow was used here, just pushing directly to my own branch)Romish
I got this error while using third-party submodules and found I could get the push to go through with --recurse-submodules=no. Obviously that's not the case in the OP, but leaving this comment for future searchers. My submodules both have detached heads.Coati
This seems to one problem caused by code changes as lore.kernel.org/git/[email protected]/T says. "by first pushing changes in each submodule manually" works for me.Terrijo
C
9

As far as I can tell (I’d like to be proved wrong!) there is no “recursive push” for submodule branches. In general, branches in submodules are an odd beast and don’t work the same way as regular branches in Git.

A close workaround is to use the git submodule foreach command to perform the pushes. This is still annoying but at least it solves the “tedious” aspect. Combine the commands as follows to ensure that a failed submodule push aborts the parent module push:

git submodule foreach --recursive 'git push' &&
git push

As far as I can tell this is essentially equivalent to passing --recurse-submodules=on-demand, but works with branches.

Crinum answered 21/5, 2019 at 10:47 Comment(2)
This sadly doesn't work if I have dependencies (to whose repos I don't have write access) as submodules. --recurse-submodules=on-demand just skips these, because I don't commit anything in those repos. But git push in the submodule asks for a password (which I don't have and don't want to have...)Monahan
@TS Unfortunately I don’t have a solution for this case. But in general you should mirror all submodule remotes. That is, submodules in your project should have remotes that you control and for which you therefore have push rights; otherwise your project is fragile: if the upstream maintainer of one of your submodules decides to delete their repository, or otherwise makes destructive changes to the repository, you’re screwed.Crinum

© 2022 - 2024 — McMap. All rights reserved.