Is there an easy way to "repin" a local opam package?

I am often in a situation where I have an opam package pinned to a local git commit. Then I make some changes to the repository adding some commits. Then, I want to update the pin to the most recent commit.

I usually accomplish this by running opam unpin . followed by opam pin ., but this is quite slow since it leads to a lot of recompilation. Also, sometimes after running pin again, even when there are no reported errors or build failures, the new version still does not point to the latest commit. Overall, it’s a pain.

Is this the suggested way to repin a package? Am I the only one who’s ran into this difficulty, and is there any way to make it more ergonomic or faster?

Thanks all

Can’t you simply pin it ?

Basically the first one pins to a particular commit the second one pins to your head.

opam pin .#commitish
opam pin .

(That is, there is no need to unpin)

Interesting, I didn’t know unpin was unnecessary and that you could put the commit hash directly in the command. Except it still doesn’t seem to work, so maybe there’s something else I have wrong.

In particular, I’m working with js_of_ocaml. With my current pin I have:

$ which js_of_ocaml
~/.opam/5.0.0/bin/js_of_ocaml
$ js_of_ocaml --version
5.4.0+git-5.3.0-191-g70664e97-dirty

HEAD is 70664e97a3. In the js_of_ocaml directory, I run:

$ opam pin .#70664e97a3
This will pin the following packages: js_of_ocaml, js_of_ocaml-tyxml, js_of_ocaml-toplevel, js_of_ocaml-ppx_deriving_json, js_of_ocaml-ppx, js_of_ocaml-lwt, js_of_ocaml-compiler. Continue? [Y/n] y
[NOTE] Package js_of_ocaml is currently pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#new_deadcode (version 5.4.0).
[js_of_ocaml.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3
js_of_ocaml is now pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3 (version 5.4.0)
[NOTE] Package js_of_ocaml-tyxml is currently pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#new_deadcode (version 5.4.0).
[js_of_ocaml-tyxml.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3
js_of_ocaml-tyxml is now pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3 (version 5.4.0)
[NOTE] Package js_of_ocaml-toplevel is currently pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#new_deadcode (version 5.4.0).
[js_of_ocaml-toplevel.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3
js_of_ocaml-toplevel is now pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3 (version 5.4.0)
[NOTE] Package js_of_ocaml-ppx_deriving_json is currently pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#new_deadcode (version 5.4.0).
[js_of_ocaml-ppx_deriving_json.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3
js_of_ocaml-ppx_deriving_json is now pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3 (version 5.4.0)
[NOTE] Package js_of_ocaml-ppx is currently pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#new_deadcode (version 5.4.0).
[js_of_ocaml-ppx.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3
js_of_ocaml-ppx is now pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3 (version 5.4.0)
[NOTE] Package js_of_ocaml-lwt is currently pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#new_deadcode (version 5.4.0).
[js_of_ocaml-lwt.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3
js_of_ocaml-lwt is now pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3 (version 5.4.0)
[NOTE] Package js_of_ocaml-compiler is currently pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#new_deadcode (version 5.4.0).
[js_of_ocaml-compiler.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3
js_of_ocaml-compiler is now pinned to git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3 (version 5.4.0)
The following actions will be performed:
  ↻ recompile js_of_ocaml-compiler          5.4.0*
  ↻ recompile js_of_ocaml-toplevel          5.4.0*
  ↻ recompile js_of_ocaml                   5.4.0*
  ↻ recompile js_of_ocaml-ppx_deriving_json 5.4.0*
  ↻ recompile js_of_ocaml-ppx               5.4.0*
  ↻ recompile js_of_ocaml-tyxml             5.4.0*
  ↻ recompile js_of_ocaml-lwt               5.4.0*
===== ↻ 7 =====
Do you want to continue? [Y/n] y
[js_of_ocaml.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3
[js_of_ocaml-compiler.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3
[js_of_ocaml-lwt.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3
[js_of_ocaml-ppx.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3
[js_of_ocaml-ppx_deriving_json.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3
[js_of_ocaml-toplevel.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3
[js_of_ocaml-tyxml.5.4.0] no changes from git+file:///home/micahcantor/Work/tarides/js_of_ocaml#70664e97a3

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
⊘ removed   js_of_ocaml-lwt.5.4.0
⊘ removed   js_of_ocaml-ppx_deriving_json.5.4.0
⊘ removed   js_of_ocaml-toplevel.5.4.0
⊘ removed   js_of_ocaml-tyxml.5.4.0
⊘ removed   js_of_ocaml-ppx.5.4.0
⊘ removed   js_of_ocaml.5.4.0
⊘ removed   js_of_ocaml-compiler.5.4.0
∗ installed js_of_ocaml-compiler.5.4.0
∗ installed js_of_ocaml-toplevel.5.4.0
∗ installed js_of_ocaml.5.4.0
∗ installed js_of_ocaml-ppx_deriving_json.5.4.0
∗ installed js_of_ocaml-ppx.5.4.0
∗ installed js_of_ocaml-tyxml.5.4.0
∗ installed js_of_ocaml-lwt.5.4.0
Done.

But afterwards I still have:

$ js_of_ocaml --version
5.4.0+git-5.3.0-191-g70664e97-dirty

I don’t think I have the best mental model of what opam pin really does, so I’m probably messing something up here. Thanks.

Mmh, I’m unsure why it’s doing that but that could be a bug in opam. Which version are you using? If it’s the 2.1.5, could you try using the latest alpha:

bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh) --dev"

Oh, it seems I have an old version of opam for some reason… I have 2.0.5

Also rather than js_of_ocaml --version (which I remember finding confusing) you should rather check opam info js_of_ocaml -f source-hash which tells you which commit opam used.

Hm, opam info js_of_ocaml -f source-hash does indeed give 70664e97. Do you know why that would diverge from js_of_ocaml --version? I’d really like to be sure I’m running correct version though, since I’m trying to benchmark subtle performance differences between them.

No I’m afraid. I don’t know how js_of_ocaml derives that output, only that it tended to confuse me :–)

Interesting! Maybe @vouillon or @hhugo know more.

js_of_ocaml uses git describe --always --dirty to derive the version number.

Rereading the whole thread, there doesn’t actually seem to be any problem in the end.
The git command simply prints the git hash a little differently than what you expected.

The command outputs something of the form:

<latest tag>-g<git hash>

As you can see the git hash is actually the same. The git command only puts a g prefix for some reason and shortens it a little.

70664e97a3 = 70664e97

The dirty suffix is a bit weird though since it seem to be present even though you are using a VCS pin.

true. @micahcantor have you tried the latest opam release?

As you can see the git hash is actually the same. The git command only puts a g prefix for some reason and shortens it a little.

Wow, I feel silly now because I completely didn’t notice that.

@micahcantor have you tried the latest opam release?

Yes, I upgraded to opam 2.2.0~alpha2, and now after pinning I get 5.4.0+git-70664e9-dirty from the js_of_ocaml version. Still says dirty for some reason but the g prefix seems to be gone? Thanks for the help though, I guess nothing was really wrong before but feeling less confused now.

Pinning is not the main goal, no. I have a Python script in another repository that benchmarks by shelling out to js_of_ocaml. So I really just want an easy way to put the executable in my PATH, and at some point @otini mentioned I could do this with opam pin so I stuck with it.

after a quick test, it looks like it’s because the opam file for js_of_ocaml-compiler contains a call to dune subst before dune build. dune subst will modify an unknown number of files in the current dune project and those changes are obviously not commited so git will show this as dirty.

1 Like