NOTE:
The mentioned LATEST
and RELEASE
metaversions have been dropped for plugin dependencies in Maven 3 "for the sake of reproducible builds", over 6 years ago.
(They still work perfectly fine for regular dependencies.)
For plugin dependencies please refer to this Maven 3 compliant solution.
If you always want to use the newest version, Maven has two keywords you can use as an alternative to version ranges. You should use these options with care as you are no longer in control of the plugins/dependencies you are using.
When you depend on a plugin or a dependency, you can use the a version value of LATEST or RELEASE. LATEST refers to the latest released or snapshot version of a particular artifact, the most recently deployed artifact in a particular repository. RELEASE refers to the last non-snapshot release in the repository. In general, it is not a best practice to design software which depends on a non-specific version of an artifact. If you are developing software, you might want to use RELEASE or LATEST as a convenience so that you don't have to update version numbers when a new release of a third-party library is released. When you release software, you should always make sure that your project depends on specific versions to reduce the chances of your build or your project being affected by a software release not under your control. Use LATEST and RELEASE with caution, if at all.
See the POM Syntax section of the Maven book for more details. Or see this doc on Dependency Version Ranges, where:
- A square bracket (
[
& ]
) means "closed" (inclusive).
- A parenthesis (
(
& )
) means "open" (exclusive).
Here's an example illustrating the various options. In the Maven repository, com.foo:my-foo has the following metadata:
<?xml version="1.0" encoding="UTF-8"?><metadata>
<groupId>com.foo</groupId>
<artifactId>my-foo</artifactId>
<version>2.0.0</version>
<versioning>
<release>1.1.1</release>
<versions>
<version>1.0</version>
<version>1.0.1</version>
<version>1.1</version>
<version>1.1.1</version>
<version>2.0.0</version>
</versions>
<lastUpdated>20090722140000</lastUpdated>
</versioning>
</metadata>
If a dependency on that artifact is required, you have the following options (other version ranges can be specified of course, just showing the relevant ones here):
Declare an exact version (will always resolve to 1.0.1):
<version>[1.0.1]</version>
Declare an explicit version (will always resolve to 1.0.1 unless a collision occurs, when Maven will select a matching version):
<version>1.0.1</version>
Declare a version range for all 1.x (will currently resolve to 1.1.1):
<version>[1.0.0,2.0.0)</version>
Declare an open-ended version range (will resolve to 2.0.0):
<version>[1.0.0,)</version>
Declare the version as LATEST (will resolve to 2.0.0) (removed from maven 3.x)
<version>LATEST</version>
Declare the version as RELEASE (will resolve to 1.1.1) (removed from maven 3.x):
<version>RELEASE</version>
Note that by default your own deployments will update the "latest" entry in the Maven metadata, but to update the "release" entry, you need to activate the "release-profile" from the Maven super POM. You can do this with either "-Prelease-profile" or "-DperformRelease=true"
It's worth emphasising that any approach that allows Maven to pick the dependency versions (LATEST, RELEASE, and version ranges) can leave you open to build time issues, as later versions can have different behaviour (for example the dependency plugin has previously switched a default value from true to false, with confusing results).
It is therefore generally a good idea to define exact versions in releases. As Tim's answer points out, the maven-versions-plugin is a handy tool for updating dependency versions, particularly the versions:use-latest-versions and versions:use-latest-releases goals.
What you are trying to do is called a sparse checkout, and that feature was added in git 1.7.0 (Feb. 2012). The steps to do a sparse clone are as follows:
mkdir <repo>
cd <repo>
git init
git remote add -f origin <url>
This creates an empty repository with your remote, and fetches all objects but doesn't check them out. Then do:
git config core.sparseCheckout true
Now you need to define which files/folders you want to actually check out. This is done by listing them in .git/info/sparse-checkout
, eg:
echo "some/dir/" >> .git/info/sparse-checkout
echo "another/sub/tree" >> .git/info/sparse-checkout
Last but not least, update your empty repo with the state from the remote:
git pull origin master
You will now have files "checked out" for some/dir
and another/sub/tree
on your file system (with those paths still), and no other paths present.
You might want to have a look at the extended tutorial and you should probably read the official documentation for sparse checkout and read-tree.
As a function:
function git_sparse_clone() (
rurl="$1" localdir="$2" && shift 2
mkdir -p "$localdir"
cd "$localdir"
git init
git remote add -f origin "$rurl"
git config core.sparseCheckout true
# Loops over remaining args
for i; do
echo "$i" >> .git/info/sparse-checkout
done
git pull origin master
)
Usage:
git_sparse_clone "http://github.com/tj/n" "./local/location" "/bin"
Note that this will still download the whole repository from the server – only the checkout is reduced in size. At the moment it is not possible to clone only a single directory. But if you don't need the history of the repository, you can at least save on bandwidth by creating a shallow clone. See udondan's answer below for information on how to combine shallow clone and sparse checkout.
As of git 2.25.0 (Jan 2020) an experimental sparse-checkout command is added in git:
git sparse-checkout init
# same as:
# git config core.sparseCheckout true
git sparse-checkout set "A/B"
# same as:
# echo "A/B" >> .git/info/sparse-checkout
git sparse-checkout list
# same as:
# cat .git/info/sparse-checkout
Best Answer
If the artifact that you depend on is a snapshot version then maven will check for a new snapshot every time you build, thats why it is a good practice to lock down your dependencies to a released version.
You can "override" the repository declarations by defining a
<mirror>
in the settings.xml.See http://maven.apache.org/settings.html#Mirrors
I usually set up a locally hosted repository manager (preferably nexus) and then define mirrorOf(*) = local-repo-manager/url.
Nexus allows multiple repo's to be grouped with a predefined search order. Nexus repo's can be locally hosted or caching/proxies to public repo's.
I usually have a locally hosted 3rd party repo at the front of the group, where I can store artifacts that are not published on public repo's.