Skip to content

Commit 1c01c62

Browse files
committed
Auto merge of #13341 - rimutaka:git-path-doc-9624, r=weihanglo
doc: Edits for git/path dependency sections Fixes #9624 ## Summary Made changes to [[Specifying dependencies from git repositories](https://doc.rust-lang.org/nightly/cargo/reference/specifying-dependencies.html#specifying-dependencies-from-git-repositories)] and [Specifying path dependencies](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#specifying-path-dependencies) sections of the Reference. * minor rephrasing for readability * added more examples * added sub-headings * rearranged a few paragraphs for readability ### Additional info `@weihanglo` proposed a small change in this comment #9624 (comment). It had been a while since I read that reference page, so I had a novice's point view and expanded the scope of the change to address the questions that I had while reading it. The combination of _git_, _path_ and _version_ keys was specially confusing until I read the Multiple locations section. If you think this is too much change for no gain I am happy to reverse the edits and only add the new info as per `@weihanglo` 's comment.
2 parents 00b9882 + 6b2c79c commit 1c01c62

File tree

1 file changed

+121
-54
lines changed

1 file changed

+121
-54
lines changed

src/doc/src/reference/specifying-dependencies.md

+121-54
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ versions before 1.0.0. While SemVer says there is no compatibility before
5151
and `x > 0`.
5252

5353
It is possible to further tweak the logic for selecting compatible versions
54-
using special operators, though it shouldn't be necessary most of the time.
54+
using special operators as described in the [Version requirement syntax](#version-requirement-syntax) section.
55+
56+
Use the default version requirement strategy, e.g. `log = "1.2.3"` where possible to maximize compatibility.
5557

5658
## Version requirement syntax
5759

@@ -158,16 +160,17 @@ separated with a comma, e.g., `>= 1.2, < 1.5`.
158160

159161
## Specifying dependencies from other registries
160162

161-
To specify a dependency from a registry other than [crates.io], first the
162-
registry must be configured in a `.cargo/config.toml` file. See the [registries
163-
documentation] for more information. In the dependency, set the `registry` key
164-
to the name of the registry to use.
163+
To specify a dependency from a registry other than [crates.io] set the `registry` key
164+
to the name of the registry to use:
165165

166166
```toml
167167
[dependencies]
168168
some-crate = { version = "1.0", registry = "my-registry" }
169169
```
170170

171+
where `my-registry` is the registry name configured in `.cargo/config.toml` file.
172+
See the [registries documentation] for more information.
173+
171174
> **Note**: [crates.io] does not allow packages to be published with
172175
> dependencies on code published outside of [crates.io].
173176
@@ -183,69 +186,113 @@ you need to specify is the location of the repository with the `git` key:
183186
regex = { git = "https://github.com/rust-lang/regex.git" }
184187
```
185188

186-
Cargo will fetch the `git` repository at this location then look for a
187-
`Cargo.toml` for the requested crate anywhere inside the `git` repository
188-
(not necessarily at the root --- for example, specifying a member crate name
189-
of a workspace and setting `git` to the repository containing the workspace).
189+
Cargo fetches the `git` repository at that location and traverses the file tree to find
190+
`Cargo.toml` file for the requested crate anywhere inside the `git` repository.
191+
For example, `regex-lite` and `regex-syntax` are members of `rust-lang/regex` repo
192+
and can be referred to by the repo's root URL (`https://github.com/rust-lang/regex.git`)
193+
regardless of where in the file tree they reside.
194+
195+
```toml
196+
regex-lite = { git = "https://github.com/rust-lang/regex.git" }
197+
regex-syntax = { git = "https://github.com/rust-lang/regex.git" }
198+
```
199+
200+
The above rule does not apply to [`path` dependencies](#specifying-path-dependencies).
190201

191-
Since we haven’t specified any other information, Cargo assumes that
192-
we intend to use the latest commit on the default branch to build
193-
our package, which may not necessarily be the main branch.
194-
You can combine the `git` key with the `rev`, `tag`, or `branch` keys to
195-
specify something else. Here's an example of specifying that you want to use
196-
the latest commit on a branch named `next`:
202+
### Choice of commit
203+
204+
Cargo assumes that we intend to use the latest commit on the default branch to build
205+
our package if we only specify the repo URL, as in the examples above.
206+
207+
You can combine the `git` key with the `rev`, `tag`, or `branch` keys to be more specific about
208+
which commit to use. Here's an example of using the latest commit on a branch named `next`:
197209

198210
```toml
199211
[dependencies]
200212
regex = { git = "https://github.com/rust-lang/regex.git", branch = "next" }
201213
```
202214

203-
Anything that is not a branch or tag falls under `rev`. This can be a commit
215+
Anything that is not a branch or a tag falls under `rev` key. This can be a commit
204216
hash like `rev = "4c59b707"`, or a named reference exposed by the remote
205-
repository such as `rev = "refs/pull/493/head"`. What references are available
206-
varies by where the repo is hosted; GitHub in particular exposes a reference to
207-
the most recent commit of every pull request as shown, but other git hosts often
208-
provide something equivalent, possibly under a different naming scheme.
209-
210-
Once a `git` dependency has been added, Cargo will lock that dependency to the
211-
latest commit at the time. New commits will not be pulled down automatically
212-
once the lock is in place. However, they can be pulled down manually with
213-
`cargo update`.
214-
215-
See [Git Authentication] for help with git authentication for private repos.
216-
217-
> **Note**: Neither the `git` key nor the `path` key changes the meaning of the
218-
> `version` key: the `version` key always implies that the package is available
219-
> in a registry. `version`, `git`, and `path` keys are considered [separate
220-
> locations](#multiple-locations) for resolving the dependency.
221-
>
222-
> When the dependency is retrieved from `git`, the `version` key will _not_
223-
> affect which commit is used, but the version information in the dependency's
224-
> `Cargo.toml` file will still be validated against the `version` requirement.
217+
repository such as `rev = "refs/pull/493/head"`.
218+
219+
What references are available for the `rev` key varies by where the repo is hosted.
220+
GitHub exposes a reference to the most recent commit of every pull request as in the example above.
221+
Other git hosts may provide something equivalent under a different naming scheme.
222+
223+
**More `git` dependency examples:**
224+
225+
```toml
226+
# .git suffix can be omitted if the host accepts such URLs - both examples work the same
227+
regex = { git = "https://github.com/rust-lang/regex" }
228+
regex = { git = "https://github.com/rust-lang/regex.git" }
229+
230+
# a commit with a particular tag
231+
regex = { git = "https://github.com/rust-lang/regex.git", tag = "1.10.3" }
232+
233+
# a commit by its SHA1 hash
234+
regex = { git = "https://github.com/rust-lang/regex.git", rev = "0c0990399270277832fbb5b91a1fa118e6f63dba" }
235+
236+
# HEAD commit of PR 493
237+
regex = { git = "https://github.com/rust-lang/regex.git", rev = "refs/pull/493/head" }
238+
239+
# INVALID EXAMPLES
240+
241+
# specifying the commit after # ignores the commit ID and generates a warning
242+
regex = { git = "https://github.com/rust-lang/regex.git#4c59b70" }
243+
244+
# git and path cannot be used at the same time
245+
regex = { git = "https://github.com/rust-lang/regex.git#4c59b70", path = "../regex" }
246+
```
247+
248+
Cargo locks the commits of `git` dependencies in `Cargo.lock` file at the time of their addition
249+
and checks for updates only when you run `cargo update` command.
250+
251+
### The role of the `version` key
252+
253+
The `version` key always implies that the package is available in a registry,
254+
regardless of the presence of `git` or `path` keys.
255+
256+
The `version` key does _not_ affect which commit is used when Cargo retrieves the `git` dependency,
257+
but Cargo checks the version information in the dependency's `Cargo.toml` file
258+
against the `version` key and raises an error if the check fails.
259+
260+
In this example, Cargo retrieves the HEAD commit of the branch called `next` from Git and checks if the crate's version
261+
is compatible with `version = "1.10.3"`:
262+
263+
```toml
264+
[dependencies]
265+
regex = { version = "1.10.3", git = "https://github.com/rust-lang/regex.git", branch = "next" }
266+
```
267+
268+
`version`, `git`, and `path` keys are considered separate locations for resolving the dependency.
269+
See [Multiple locations](#multiple-locations) section below for detailed explanations.
225270

226271
> **Note**: [crates.io] does not allow packages to be published with
227272
> dependencies on code published outside of [crates.io] itself
228273
> ([dev-dependencies] are ignored). See the [Multiple
229274
> locations](#multiple-locations) section for a fallback alternative for `git`
230275
> and `path` dependencies.
231276
232-
[Git Authentication]: ../appendix/git-authentication.md
277+
### Accessing private Git repositories
278+
279+
See [Git Authentication](../appendix/git-authentication.md) for help with Git authentication for private repos.
233280

234281
## Specifying path dependencies
235282

236283
Over time, our `hello_world` package from [the guide](../guide/index.md) has
237284
grown significantly in size! It’s gotten to the point that we probably want to
238285
split out a separate crate for others to use. To do this Cargo supports **path
239286
dependencies** which are typically sub-crates that live within one repository.
240-
Let’s start off by making a new crate inside of our `hello_world` package:
287+
Let’s start by making a new crate inside of our `hello_world` package:
241288

242289
```console
243290
# inside of hello_world/
244291
$ cargo new hello_utils
245292
```
246293

247294
This will create a new folder `hello_utils` inside of which a `Cargo.toml` and
248-
`src` folder are ready to be configured. In order to tell Cargo about this, open
295+
`src` folder are ready to be configured. To tell Cargo about this, open
249296
up `hello_world/Cargo.toml` and add `hello_utils` to your dependencies:
250297

251298
```toml
@@ -254,30 +301,50 @@ hello_utils = { path = "hello_utils" }
254301
```
255302

256303
This tells Cargo that we depend on a crate called `hello_utils` which is found
257-
in the `hello_utils` folder (relative to the `Cargo.toml` it’s written in).
304+
in the `hello_utils` folder, relative to the `Cargo.toml` file it’s written in.
305+
306+
The next `cargo build` will automatically build `hello_utils` and
307+
all of its dependencies.
258308

259-
And that’s it! The next `cargo build` will automatically build `hello_utils` and
260-
all of its own dependencies, and others can also start using the crate as well.
261-
However, crates that use dependencies specified with only a path are not
262-
permitted on [crates.io]. If we wanted to publish our `hello_world` crate, we
263-
would need to publish a version of `hello_utils` to [crates.io]
264-
and specify its version in the dependencies line as well:
309+
### No local path traversal
310+
311+
The local paths must point to the exact folder with the dependency's `Cargo.toml`.
312+
Unlike with `git` dependencies, Cargo does not traverse local paths.
313+
For example, if `regex-lite` and `regex-syntax` are members of a
314+
locally cloned `rust-lang/regex` repo, they have to be referred to by the full path:
315+
316+
```toml
317+
# git key accepts the repo root URL and Cargo traverses the tree to find the crate
318+
[dependencies]
319+
regex-lite = { git = "https://github.com/rust-lang/regex.git" }
320+
regex-syntax = { git = "https://github.com/rust-lang/regex.git" }
321+
322+
# path key requires the member name to be included in the local path
323+
[dependencies]
324+
regex-lite = { path = "../regex/regex-lite" }
325+
regex-syntax = { path = "../regex/regex-syntax" }
326+
```
327+
328+
### Local paths in published crates
329+
330+
Crates that use dependencies specified with only a path are not
331+
permitted on [crates.io].
332+
333+
If we wanted to publish our `hello_world` crate,
334+
we would need to publish a version of `hello_utils` to [crates.io] as a separate crate
335+
and specify its version in the dependencies line of `hello_world`:
265336

266337
```toml
267338
[dependencies]
268339
hello_utils = { path = "hello_utils", version = "0.1.0" }
269340
```
270341

271-
> **Note**: Neither the `git` key nor the `path` key changes the meaning of the
272-
> `version` key: the `version` key always implies that the package is available
273-
> in a registry. `version`, `git`, and `path` keys are considered [separate
274-
> locations](#multiple-locations) for resolving the dependency.
342+
The use of `path` and `version` keys together is explained in the [Multiple locations](#multiple-locations) section.
275343

276344
> **Note**: [crates.io] does not allow packages to be published with
277-
> dependencies on code published outside of [crates.io] itself
278-
> ([dev-dependencies] are ignored). See the [Multiple
279-
> locations](#multiple-locations) section for a fallback alternative for `git`
280-
> and `path` dependencies.
345+
> dependencies on code outside of [crates.io], except for [dev-dependencies].
346+
> See the [Multiple locations](#multiple-locations) section
347+
> for a fallback alternative for `git` and `path` dependencies.
281348
282349
## Multiple locations
283350

0 commit comments

Comments
 (0)