-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is there a way to skip some submodules? #4247
Comments
Unfortunately we don't currently have a way of saying "exclude this submodule", but I could imagine interpreting the |
I noticed this for |
After #4837 is merged, it will be slower to add large repository with a lot of optional submodules as dependency. |
Is using |
The recommended way is to not have submodules I believe. See dtolnay/syn#183. Cargo fetches all submodules as part of checking out the repo, and reads the Cargo.toml after checking out the repo, so an #4247 (comment) proposes cloning the repo without submodules first, reading |
cargo install will always clone all submodules, which is bad ux https://github.com/rust-lang/cargo/issues/4247\#issuecomment-959912231
cargo install will always clone all submodules, which is bad ux https://github.com/rust-lang/cargo/issues/4247\#issuecomment-959912231
This is required because cargo will fetch submodules when taking a git dependency, even though it is not needed in this case. rust-lang/cargo#4247 The git command line correctly handles commits which are only present in forks, but cargo doesn't.
Respect submodule update=none strategy in .gitmodules Git lets users define the default update/checkout strategy for a submodule by setting the `submodule.<name>.update` key in `.gitmodules` file. If the update strategy is `none`, the submodule will be skipped during update. It will not be fetched and checked out: 1. *foo* is a big git repo ``` /tmp $ git init foo Initialized empty Git repository in /tmp/foo/.git/ /tmp $ dd if=/dev/zero of=foo/big bs=1000M count=1 1+0 records in 1+0 records out 1048576000 bytes (1.0 GB, 1000 MiB) copied, 0.482087 s, 2.2 GB/s /tmp $ git -C foo add big /tmp $ git -C foo commit -m 'I am big' [main (root-commit) 84fb533] I am big 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 big ``` 2. *bar* is a repo with a big submodule with `update=none` ``` /tmp $ git init bar Initialized empty Git repository in /tmp/bar/.git/ /tmp $ git -C bar submodule add file:///tmp/foo foo Cloning into '/tmp/bar/foo'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 1 (delta 0), pack-reused 0 Receiving objects: 100% (3/3), 995.50 KiB | 338.00 KiB/s, done. /tmp $ git -C bar config --file .gitmodules submodule.foo.update none /tmp $ cat bar/.gitmodules [submodule "foo"] path = foo url = file:///tmp/foo update = none /tmp $ git -C bar commit --all -m 'I have a big submodule with update=none' [main (root-commit) 6c355ea] I have a big submodule not updated by default 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 foo ``` 3. *baz* is a clone of *bar*, notice *foo* submodule gets skipped ``` /tmp $ git clone --recurse-submodules file:///tmp/bar baz Cloning into 'baz'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Compressing objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (3/3), done. Submodule 'foo' (file:///tmp/foo) registered for path 'foo' Skipping submodule 'foo' /tmp $ git -C baz submodule update --init Skipping submodule 'foo' /tmp $ ``` Cargo, on the other hand, ignores the submodule update strategy set in `.gitmodules` properties when updating dependencies. Such behavior can be considered against the wish of the crate publisher. 4. *bar* is now a lib with a big submodule with update disabled ``` /tmp $ cargo init --lib bar Created library package /tmp $ git -C bar add . /tmp $ git -C bar commit -m 'I am a lib with a big submodule but update=none' [main eb07cf7] I am a lib with a big submodule but update=none 3 files changed, 18 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/lib.rs /tmp $ ``` 5. *qux* depends on *bar*, notice *bar*'s submodules are fetched ``` /tmp $ cargo init qux && cd qux Created binary (application) package /tmp/qux $ echo -e '[dependencies.bar]\ngit = "file:///tmp/bar"' >> Cargo.toml /tmp/qux $ time cargo update Updating git repository `file:///tmp/bar` Updating git submodule `file:///tmp/foo` real 0m22.182s user 0m20.402s sys 0m1.714s /tmp/qux $ ``` Fix it by checking if a Git repository submodule should be updated when cargo processes dependencies. 6. With the change applied, submodules with `update=none` are skipped ``` /tmp/qux $ cargo cache -a > /dev/null /tmp/qux $ time ~/src/cargo/target/debug/cargo update Updating git repository `file:///tmp/bar` Skipping git submodule `file:///tmp/foo` real 0m0.029s user 0m0.021s sys 0m0.008s /tmp/qux $ ``` Fixes #4247.
The new patch doesn't solve all the problems. The repository can't control nested submodules. |
Do you mean that it doesn't skip a submodule that is a submodule of a skipped submodule?
|
No, I'm talking about skipping submodule that is a submodule of non-skipped submodule. For example, a native library may include tests framework as a submodule, so the layout becomes:
Apparently, testing framework is not necessary for a rust binding library, but it will be cloned anyway. |
#10717 only makes sure that submodules aren't updated according to |
Updating, in Git lingo, means - cloning, fetching missing commits, and updating the work tree. All three things. I assume by pulling in you have cloning in mind? If so, the submodules with #10717 merely puts Cargo on par with how Now that the use case has been clarified, I realize I should have used "linked to" instead of "fixes" in the commit description. |
Git lets users define the default update/checkout strategy for a submodule by setting the `submodule.<name>.update` key in `.gitmodules` file. If the update strategy is `none`, the submodule will be skipped during update. It will not be fetched and checked out: 1. *foo* is a big git repo ``` /tmp $ git init foo Initialized empty Git repository in /tmp/foo/.git/ /tmp $ dd if=/dev/zero of=foo/big bs=1000M count=1 1+0 records in 1+0 records out 1048576000 bytes (1.0 GB, 1000 MiB) copied, 0.482087 s, 2.2 GB/s /tmp $ git -C foo add big /tmp $ git -C foo commit -m 'I am big' [main (root-commit) 84fb533] I am big 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 big ``` 2. *bar* is a repo with a big submodule with `update=none` ``` /tmp $ git init bar Initialized empty Git repository in /tmp/bar/.git/ /tmp $ git -C bar submodule add file:///tmp/foo foo Cloning into '/tmp/bar/foo'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 1 (delta 0), pack-reused 0 Receiving objects: 100% (3/3), 995.50 KiB | 338.00 KiB/s, done. /tmp $ git -C bar config --file .gitmodules submodule.foo.update none /tmp $ cat bar/.gitmodules [submodule "foo"] path = foo url = file:///tmp/foo update = none /tmp $ git -C bar commit --all -m 'I have a big submodule with update=none' [main (root-commit) 6c355ea] I have a big submodule not updated by default 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 foo ``` 3. *baz* is a clone of *bar*, notice *foo* submodule gets skipped ``` /tmp $ git clone --recurse-submodules file:///tmp/bar baz Cloning into 'baz'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Compressing objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (3/3), done. Submodule 'foo' (file:///tmp/foo) registered for path 'foo' Skipping submodule 'foo' /tmp $ git -C baz submodule update --init Skipping submodule 'foo' /tmp $ ``` Cargo, on the other hand, ignores the submodule update strategy set in `.gitmodules` properties when updating dependencies. Such behavior can be considered against the wish of the crate publisher. 4. *bar* is now a lib with a big submodule with update disabled ``` /tmp $ cargo init --lib bar Created library package /tmp $ git -C bar add . /tmp $ git -C bar commit -m 'I am a lib with a big submodule but update=none' [main eb07cf7] I am a lib with a big submodule but update=none 3 files changed, 18 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/lib.rs /tmp $ ``` 5. *qux* depends on *bar*, notice *bar*'s submodules are fetched ``` /tmp $ cargo init qux && cd qux Created binary (application) package /tmp/qux $ echo -e '[dependencies.bar]\ngit = "file:///tmp/bar"' >> Cargo.toml /tmp/qux $ time cargo update Updating git repository `file:///tmp/bar` Updating git submodule `file:///tmp/foo` real 0m22.182s user 0m20.402s sys 0m1.714s /tmp/qux $ ``` Fix it by checking if a Git repository submodule should be updated when cargo processes dependencies. 6. With the change applied, submodules with `update=none` are skipped ``` /tmp/qux $ cargo cache -a > /dev/null /tmp/qux $ time ~/src/cargo/target/debug/cargo update Updating git repository `file:///tmp/bar` Skipping git submodule `file:///tmp/foo` real 0m0.029s user 0m0.021s sys 0m0.008s /tmp/qux $ ``` Fixes rust-lang#4247. Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
Git lets users define the default update/checkout strategy for a submodule by setting the `submodule.<name>.update` key in `.gitmodules` file. If the update strategy is `none`, the submodule will be skipped during update. It will not be fetched and checked out: 1. *foo* is a big git repo ``` /tmp $ git init foo Initialized empty Git repository in /tmp/foo/.git/ /tmp $ dd if=/dev/zero of=foo/big bs=1000M count=1 1+0 records in 1+0 records out 1048576000 bytes (1.0 GB, 1000 MiB) copied, 0.482087 s, 2.2 GB/s /tmp $ git -C foo add big /tmp $ git -C foo commit -m 'I am big' [main (root-commit) 84fb533] I am big 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 big ``` 2. *bar* is a repo with a big submodule with `update=none` ``` /tmp $ git init bar Initialized empty Git repository in /tmp/bar/.git/ /tmp $ git -C bar submodule add file:///tmp/foo foo Cloning into '/tmp/bar/foo'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 1 (delta 0), pack-reused 0 Receiving objects: 100% (3/3), 995.50 KiB | 338.00 KiB/s, done. /tmp $ git -C bar config --file .gitmodules submodule.foo.update none /tmp $ cat bar/.gitmodules [submodule "foo"] path = foo url = file:///tmp/foo update = none /tmp $ git -C bar commit --all -m 'I have a big submodule with update=none' [main (root-commit) 6c355ea] I have a big submodule not updated by default 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 foo ``` 3. *baz* is a clone of *bar*, notice *foo* submodule gets skipped ``` /tmp $ git clone --recurse-submodules file:///tmp/bar baz Cloning into 'baz'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Compressing objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (3/3), done. Submodule 'foo' (file:///tmp/foo) registered for path 'foo' Skipping submodule 'foo' /tmp $ git -C baz submodule update --init Skipping submodule 'foo' /tmp $ ``` Cargo, on the other hand, ignores the submodule update strategy set in `.gitmodules` properties when updating dependencies. Such behavior can be considered against the wish of the crate publisher. 4. *bar* is now a lib with a big submodule with update disabled ``` /tmp $ cargo init --lib bar Created library package /tmp $ git -C bar add . /tmp $ git -C bar commit -m 'I am a lib with a big submodule but update=none' [main eb07cf7] I am a lib with a big submodule but update=none 3 files changed, 18 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/lib.rs /tmp $ ``` 5. *qux* depends on *bar*, notice *bar*'s submodules are fetched ``` /tmp $ cargo init qux && cd qux Created binary (application) package /tmp/qux $ echo -e '[dependencies.bar]\ngit = "file:///tmp/bar"' >> Cargo.toml /tmp/qux $ time cargo update Updating git repository `file:///tmp/bar` Updating git submodule `file:///tmp/foo` real 0m22.182s user 0m20.402s sys 0m1.714s /tmp/qux $ ``` Fix it by checking if a Git repository submodule should be updated when cargo processes dependencies. 6. With the change applied, submodules with `update=none` are skipped ``` /tmp/qux $ cargo cache -a > /dev/null /tmp/qux $ time ~/src/cargo/target/debug/cargo update Updating git repository `file:///tmp/bar` Skipping git submodule `file:///tmp/foo` real 0m0.029s user 0m0.021s sys 0m0.008s /tmp/qux $ ``` Fixes rust-lang#4247. Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
cargo install will always clone all submodules, which is bad ux https://github.com/rust-lang/cargo/issues/4247\#issuecomment-959912231
cargo install will always clone all submodules, which is bad ux https://github.com/rust-lang/cargo/issues/4247\#issuecomment-959912231
It's not precisely what is intended, but it has a desirable side effect. Workaround-For: rust-lang/cargo#4247
Currently, cargo will populate all git submodule automatically and recursively. But sometimes not all submodules are needed, populate those unneeded modules (specially some large git repos) are just a waste of time. So is there a way to tell cargo to skip those submodules?
The text was updated successfully, but these errors were encountered: