What is the difference between opam pin and opam install, when to use one vs the other?

I’ve obviously read the man pages but I still don’t understand:

  1. what the difference is
  2. when I should use one vs the other

man pages reference:

opam pin
This command allows one to pin a package to a specific version, but has been extended to allow much more than that.

The syntax is

opam pin add <package name> <target>
Where <target> may be a version, but also an URL of a local path, an archive, or even a git, mercurial or darcs repository. The package will be kept up-to-date with its origin on opam update and when explicitly mentioned in a command, so that you can simply run opam upgrade <package name> to re-compile it from its upstream. If the upstream includes opam metadata, that will be used as well.

opam pin add camlpdf 1.7                                      # version pin
opam pin add camlpdf ~/src/camlpdf                            # path
opam pin add opam-lib https://github.com/ocaml/opam.git#1.2   # specific branch or commit
opam pin add opam-lib --dev-repo                              # upstream repository
This is actually a powerful mechanism to divert any package definition, and can even be used to locally create packages that don't have entries in the repositories.

This can be used in conjunction with opam source to patch an existing package in a breeze:

opam source <package> --dev-repo --pin
cd <package>; hack hack hack;
opam upgrade .

for install

opam install
This command downloads, builds and installs packages along with all their dependencies. You can specify one or several packages, along with version constraints. E.g:

opam install lwt
opam install ocp-indent ocp-index.1.0.2
opam install "ocamlfind>=1.4.0"

page: opam - Usage

related: Is an opam pin project needed when one wants to install an opam project with opam reinstall or 'make'? - Stack Overflow

As the documentation states, opam pin “allows local customisation of the packages in a given switch” (or “divert any package definition”, in the part you quoted). So, if you do not need to replace an official package definition with your own customization, just use opam install. But if you want to install an unofficial version of the package (e.g., an upstream branch, or your own changes), then use opam pin to override the source of the package.

There is a bit of overlap between the two commands, since doing opam install camlpdf=1.7 and opam pin add camlpdf 1.7 achieve a similar effect. The difference is that the latter command creates a customized package that happens to match exactly the specified version, but you can later modify it using opam pin edit, e.g., to tweak the dependencies.

4 Likes

I thought pin was useful for this:

if you want to ensure that your project uses the same version of a package across different development environments.

is it not?

I am seeing some code that pings a package e.g. with

    command = (['opam', 'pin', '-y']
               + root_option()
               + ['--switch', switch]
               + [coq_package, coq_package_pin])

and then tries to reinstall it with:

command: list = ['opam', 
'reinstall', 
root_option(), 
'--yes', 
'--switch',
 switch,
 '--keep-build-dir', 
coq_project]

is the pin really needed for the opam re-install to work? What might be the rationale to do such a pin before the opam reinstall?

In addition I am also installing some packages with make & wondering if that is needed.

command: list = ['make', '-C', coq_proj_path]

My Guess

The related url says:

As the documentation states, opam pin “allows local customisation of the packages in a given switch” (or “divert any package definition”, in the part you quoted). So, if you do not need to replace an official package definition with your own customization, just use opam install.

in my case I am downloading the coq proj source and then installing it myself from it – either with opam install or make. With make I can just pass the direct path. With opam install the pin command actuall “maps” the name to the exact path of the proj. So my guess is that in my aplication (due to using the coq projs myself) I do need the opam pin.

Is this right?

related to this discussion: coq_project_name at some point I cared about this because I wanted to remove the pin but now that I understand that I need it for custimizations of coq projs installs it sounds safer to stick with opam pin.

I am still curious if I need to opam pin if we are building the projects with make clean -C e.g. make clean -C ~/proverbot9001/coq-projects/CompCert.

is this true?

opam pin is a command in OPAM that allows you to pin a specific version of a package to your local system. This means that whenever you run opam install for that package, it will always install the version that you have pinned, rather than the latest version available. This can be useful if you want to ensure that your project always uses the same version of a dependency, even if a newer version becomes available.

opam install is the main command used to install packages in OPAM. It downloads and installs the latest version of the specified package, along with any dependencies that are required. You can also use opam install to install specific versions of packages, by specifying the version number along with the package name. For example, you could run opam install foo.1.2 to install version 1.2 of the foo package.

In summary, opam pin is used to pin a specific version of a package to your local system, while opam install is used to install the latest version of a package, or a specific version if specified.