How to change git submodules url locally?
Asked Answered
H

5

19

The original .gitmodules file uses the hard coded https urls but for some automated tests I clone from ssh and make the submodule urls relative as in ../ModuleName. I don't want to push these changes back into the repo either.

# change the https://github.com/ with [email protected]:
sed -i 's/https:\/\/github.com\//[email protected]:/g' ".git/config"
# delete the url lines from the submodule blocks of .git/config
sed -i '/submodule/ {$!N;d;}' ".git/config"
# change hardcoded https:// urls of submodules to relative ones
sed -i 's/https:\/\/github.com\/ProjName/../g' ".gitmodules"
# also make the same change in the .git/modules/*/config
sed -i 's/https:\/\/github.com\/ProjName/../g' .git/modules/*/config
# sync and update
git submodule sync
git submodule update --init --recursive --remote

With the snippet above, it does what I want. However, the annoying thing is, .git/modules/ folder doesn't seem to be under version control but if I just delete it, git submodule sync and most other Git operations just stop working.

Is there a way to get the .git/modules regenerated after modifying the .gitmodules and .git/config files?

Hauser answered 3/2, 2017 at 16:11 Comment(0)
S
42

If you want to modify the URL used for a submodule only for the local repo, then don't modify the .gitmodules file, that is only for changes that you want to push.

Instead, first initialize the local submodule config:

git submodule init

Then modify the .git/config file to change the submodule URL as usual. (Again, no need to modify .gitmodules here, and if this is a new clone you probably won't have .git/modules yet.)

As @jthill points out, an easier way to modify the submodule URLs is:

git config submodule.moduleName.url ssh://user@server/path

At this point you don't want to run git submodule sync, because that will overwrite the changes you just made with the values from the .gitmodules file. Instead, go straight to:

git submodule update --recursive --remote
Stumble answered 4/2, 2017 at 0:13 Comment(4)
Yes, this answers my original question and thank you very much. As a slightly different question, is there a way to recreate the .git/modules folder if it gets messed up some how? Because, once it's created, if I delete it manually, almost all git commands are upset from that point onwards.Hauser
@Hauser Possible solution here.Stumble
Take a look at the git submodule init documentation, it's a clear explanation of how this works and why.Protagonist
A drawback of this approach is that git submodule update --remote may have other side effects, if submodule.<name>.branch is set. I would recommend using git submodule set-url followed by git restore .gitmodules.Dustindustman
D
4

I believe this approach has advantages over the accepted answer:

$ git submodule set-url moduleName ssh://user@server/path
$ git restore .gitmodules  # or: git reset HEAD .gitmodules

This will change the URL everywhere, and then set it back to the previous value in the one place you don't want to change (.gitmodules).

Why this is better than the accepted answer: when setting the URL with git config submodule.moduleName.url, the command used to propagate this change into the actual submodule checkout is git submodule update --remote. However, updating the URL is only a side effect of that command, its main use is to (potentially) check out a different commit in the submodule. On the other hand, set-url only does what it says on the can.

Dustindustman answered 3/11, 2021 at 9:35 Comment(0)
T
3

Not only you can change the submodule URL with git config submodule.moduleName.url, but:

  • With Git 2.25 (Q1 2020), you can modify it.
    See "Git submodule url changed" and the new command git submodule set-url [--] <path> <newurl>

  • with Git 2.22 (Q2 2019), you can also unset it:

See commit b57e811, commit c89c494 (08 Feb 2019), and commit 7a4bb55 (07 Feb 2019) by Denton Liu (Denton-L).
(Merged by Junio C Hamano -- gitster -- in commit 01f8d78, 25 Apr 2019)

submodule--helper: teach config subcommand --unset

This teaches submodule--helper config the --unset option, which removes the specified configuration key from the .gitmodule file.

That is:

git submodule--helper config --unset submodule.submodule.url &&
git submodule--helper config submodule.submodule.url >actual &&
test_must_be_empty actual

With Git 2.27 (Q2 2020), the rewriting various parts of "git submodule" in C continues, include set-url.

See commit 6417cf9 (08 May 2020) by Shourya Shukla (periperidip).
(Merged by Junio C Hamano -- gitster -- in commit 9e8ed17, 13 May 2020)

submodule: port subcommand 'set-url' from shell to C

Signed-off-by: Shourya Shukla

Convert submodule subcommand 'set-url' to a builtin. Port 'set-url' to 'submodule--helper.c' and call the latter via 'git submodule.sh'.

Thoughtless answered 27/4, 2019 at 21:46 Comment(0)
S
0

I tried the above solution but had a mess of problems for some reason. The following is an alternative.

In a new repository:

  1. git submodule init
  2. Initialize each submodule manually with git clone ../local/path/to/submodule.git path/in/repo/submodule

Whenever the root repository submodule hashes change and you need to sync the submodules:

  1. Update the root repository
  2. git submodule update with maybe --force and --recursive for good measure
Slant answered 16/2, 2018 at 12:28 Comment(0)
K
-1

I have tried modifying the config file as mentioned, but ran into a new problem: Now instead of having the wrong URL and getting a fatal error I get this instead: " fatal: could not get a repository handle for submodule 'xxx\xxxxx\xxx' ". Merely changing the URL seems to have pushed the problem forward somewhere else, the program still can't reach my desired submodule.

Kelp answered 15/3, 2022 at 10:49 Comment(1)
This does not seem to answer Is there a way to get the .git/modules regenerated after modifying the .gitmodules and .git/config files?Mihalco

© 2022 - 2024 — McMap. All rights reserved.