Shallow clone with submodules in git, how to use pointed commits and not latest ones? [duplicate]
Asked Answered
A

1

12

I know it's possible to have shallow submodules using the --depth option with git submodule update.

However, If I run

git submodule update --init --recursive --depth 1

on my project with several submodules, I get a fatal: reference is not a tree. So I've tried again with

git submodule update --init --recursive --depth 100

which worked correctly, however I'd like to keep depth at 1.

It seems to me that --depth 1 pulls the latest commit in the submodule, not the commit pointed by the main repository, and that's why setting it to 100 solved the problem, since it pulled a longer list of commits, including the pointed ones.

Unfortunately, if that's the case then I cannot generally be sure the latest 100 commits include the one I need.

How do I tell git to use the pointed commits and not the latest ones in the shallow clone with submodules?

I'm using git 1.9.4 on Windows.

Antilog answered 28/11, 2014 at 12:40 Comment(1)
See also git config -f .gitmodules submodule.<name>.shallow true with https://mcmap.net/q/13855/-git-submodule-without-extra-weightOpiate
B
7

Unfortunately there doesn't seem to be a way to do a git fetch with only a specific commit ID. If there is I would really want to know. However I have dealt with your problem in two different ways: one, if it's possible, is to create a tag or branch on the remote repository which points to the commit I want, say we call it "ref". This way I can fetch the remote ref and the --depth will apply to it, not the latest tip. Instead of git submodule update --init I do:

git submodule init
git clone --depth 1 -b ref --separate-git-dir .git/modules/sub/ repository sub

where "sub" is the name and path of the submodule (for simplicity let's say they are the same)

The other way, if you can't create tags or branches in the remote repository, is to search for the commit you want in a loop:

git submodule init
id=$(git submodule status|sed -ne 's/.\([a-z0-9]*\) sub.*/\1/p'
git clone --depth 1 --separate-git-dir -n .git/modules/sub/ repository sub    
cd sub
while ! git rev-list $id ; do
    git fetch --depth $((i+=1))
done
git checkout $id

You could increment with more than just one commit at a time to make it go faster, but you might end up with some earlier commits than the one you want.

Burnie answered 12/12, 2014 at 13:48 Comment(5)
Hey. thanks for the tip, looks like it's close to what I am looking for. Do you know if it's possible to clone a specific tag from remote, while keeping the clone as shallow as possible? Will the --depth 1 work with the tag ref?Hanger
Sorry for a very late reply, I remember the answer to your question was yes, but I'm not able to test it again right now. just out of curiosity, did you try it, and, did it work as you wanted?Burnie
Yes, I tried, and it kinda worked. However, I opted for a different project setup and avoided using submodules for now.Hanger
It's been a while, I've accepted the answer as it provides a solution (besides being the only one :) ).Antilog
What about the -b option on git submodule add, can it take a tag as well?Sternick

© 2022 - 2024 — McMap. All rights reserved.