Git sha of a project using Pkg

I am running an estimation as a batch job on a server, saving the results in a JSON file.

I would like to add the git sha of the project as extra infromation (so that we can backtrack if necessary), how can I obtain it via the Pkg API as a string?

I’m not sure the Package manager has the SHA of the current project, it’s used to track the modules the project is dependent on.

And that value couldn’t be stored in the Project.toml or Manifest.toml because when you checked them in the hash would change.

I suspect what you want to do is:

out = IOBuffer()
run(pipeline(`git log --format=%H -1`, stdout=out))
hash=strip(String(take!(out)))

That assumes that git is setup where the program runs.

If you store Manifest.toml somewhere (maybe with the result file), you can recover the commit from it (more or less; see below). Find the git-tree-sha1 entry of your project and run git log --format=format:'%H %T' | grep $GIT_TREE_SHA1 | cut -d' ' -f1 inside the Git repository of your project. A few caveats:

  • This may find more than one commit sha if you have multiple commits with exactly the same content of the tree.
  • If you have a very fancy setup where your Julia project is not at the root of the Git repository, I think above one linear would fail. I think it wouldn’t be super hard to do a brute-force search using LibGit2.

Another solution is to use ]add YourProject#COMMIT_SHA so that the commit sha would be embedded in Manifest.toml.

For similar usecase I do:

hash = read(`git log -n 1 --pretty=format:"%H"`, String)

Th result is the same, but I’d like to ask if there’s any difference in behaviour (i.e. is one better than the other)?

I’d say read(cmd, String) is better because pipeline passthrough stdin. For example, run(pipeline(`head -n1`, stdout=out)) in REPL blocks until you hit enter.

Also, git log output is for human consumption. For example, it may launch a pager depending on your ~/.gitconfig setting. For scripting, I’d use more low-level interface like git rev-parse HEAD.

2 Likes

Thanks for the explanation!

This is actually one of the things that drives me batty with Julia…how would I know that I can call read on a Cmd?!?!?!!?

In the program I’m working on, I needed to execute curl and get the output. Reading the documentation on Cmd it appeared that pipeline and IOBuffer was the way to get the output. There was nothing that indicated I could use read. Or that passing a Cmd to read causes it to execute.

There is documentation on the read method that does mention Cmd…but that assumes I’m smart enough to guess(?) that I can use Cmd with read

At some point, I learned that Cmd is like a file. You can also open it. So it then started sound natural to me. But I guess it’s better if help?> Cmd lists a list of functions you can use with it. You can also call methodswith(Cmd, supertypes=true) or use @searchmethods ::Cmd.

Yeah, I’ll have to start doing that. I was wondering if it would make more sense if the documentation was organized by first argument type…but then there would have to be an exception if the first argument was a function, and go by second argument type…But I’m sure there would be problems with THAT layout as well. :slight_smile: