How to change a git submodule to point to a subfolder?
Asked Answered
J

5

146

Skimming through the SubModule tutorial, I created a submodule out of the boto project. Then, I discovered that I actually need only a subset of this project - specifically, the boto folder.

I would like to change my submodule to point to this folder. When I look in .gitmodules, I see

[submodule "backup/src/boto"]
    path = backup/src/boto
    url = https://github.com/boto/boto.git

What URL should I use instead of https://github.com/boto/boto.git? After I change the URL, should I delete the boto folder locally and re-pull?

Jeaninejeanlouis answered 14/3, 2011 at 19:34 Comment(4)
It's not exactly what you want - not a submodule - but you might have a look at git subtreeAutocrat
What I ended up doing is having the entire submodule, and telling IntelliJ that the boto folder is a 'source folder', so it can find packages in it.Jeaninejeanlouis
I can't believe git doesn't do this natively...yikes.Orlene
Found a similar question - #1121727Pennebaker
A
86

I'm afraid the URL for submodules always just points to the repository - you can't specify that you only want a subfolder of a repository, in the same way that git doesn't support "narrow clones" in general.

If you can't live with having the whole repository as a submodule, you could always create a new repository that's cloned from boto and then set up a cron job to:

  1. git fetch that repository into a directory
  2. Use git filter-branch to update a branch where the subdirectory is at the top level.
  3. Add that branch of the repository as the submodule. However, that's all a bit fiddly and my preference would just be to live with having the whole repository as a submodule.
Always answered 14/3, 2011 at 20:5 Comment(0)
T
35

You cannot clone only a part of a repository. This is because git treats the repository as a whole object : when you get it, you get it all.

So, the solution here would be to fetch the submodule in another directory, then use a symlink to achieve your goal.

Trifoliate answered 14/3, 2011 at 20:6 Comment(4)
I have symlinks in windows... works well too. (that's because of msys I've on my machine, so I can use ln -s like in linux)Dupre
Vista and & come with MKLink. I use that. howtogeek.com/howto/windows-vista/…Camaraderie
You can use hard links insteadEase
@KindDragon: You can't hard link directoriesCaiaphas
P
25

All the answers here are pretty dated. You could use the newer git sparse-checkout command docs here, further examples in this article to grab pieces of a repo. This is effective if you only want a directory or two from a larger git project.

TLDR:

git sparse-checkout init --cone
git sparse-checkout set <dir1> <dir2> ...
git checkout main
Plastic answered 10/2, 2022 at 22:5 Comment(2)
That seems fine if the files are you in YOUR (mono) repo, but what about when the files you want are a subset of a different mono repo - aka a subfolder of a submodule?Spectacular
The article says, if you ran git sparse-checkout set A/B, then Git would include files with names A/B/C.txt (immediate child of A/B) and A/D.txt (immediate sibling of A/B) as well as E.txt (immediate sibling of A). Personally, I consider this limiting: I only want A/B/C.txt. In the context of the question, here's my take: "sparse-checkout lets you exclude root subdirs from your repo. submodule lets you include the root of another repo anywhere in your repo."Collyer
D
18

What you want to do is create a branch in the submodule and move the folder up and delete what you don't need. You can then manage that branch instead. If you want to push up your changes, you should be able to back merge first. Git will know that you moved the files and do the merge successfully.

Hope this helps.

Duce answered 14/3, 2011 at 21:51 Comment(7)
What is a "back merge" ? Can you offer an example?Centro
a merge that goes "upstream" - from a higher order branch to a lower order one. Linus hates those. They tie in history from other branches that may have been merged already.Duce
Could you please add some example about "back merge" in this situation?Customhouse
Typically it's when you try and keep your feature branch current by merging in things from a mainline branch where everyone is merging their latest changes. This is bad because it ties your branch to others' work. If the product requires your branch but not one of the other ones already in the integration branch, it's not possible.Duce
interesting idea, have anyone tried this? I am going to try soon, but still not sure that "back merge" can be clear and automated...Breed
Did you try, dear @Breed ? Are you with us still?! Considering what Adam Dymitruk stated regarding the hate, some may get... worried...Jeanicejeanie
In my exact case, I ended up moving folders with history using git filter-branch --subdirectory-filter from this gist from my starred list, as I did not actually need merging back.... To be honest, I don't remember more details on the case @JeanicejeanieBreed
D
7

Save the submodule to the submodules/ directory, and then create a symlink:

git submodule add https://github.com/user/repo submodules/repo
ln -s submodules/repo/subdir .
git add subdir

Result:

./
  submodules/
    repo/
      subdir/

  subdir  -->  ./submodules/repo/subdir

One benefit to this approach is that it can be reused with multiple subdirectories.

Divertissement answered 14/6, 2023 at 7:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.