# Git sha of a project using Pkg

**URL:** <https://discourse.julialang.org/t/git-sha-of-a-project-using-pkg/27211>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 6, 2019, 9:46am UTC](https://discourse.julialang.org/t/git-sha-of-a-project-using-pkg/27211 "2019-08-06T09:46:34Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [August 6, 2019, 9:46am UTC](https://discourse.julialang.org/t/git-sha-of-a-project-using-pkg/27211/1 "2019-08-06T09:46:34Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [August 6, 2019, 1:10pm UTC](https://discourse.julialang.org/t/git-sha-of-a-project-using-pkg/27211/2 "2019-08-06T13:10:43Z")

</div>

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:

```julia
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.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [August 8, 2019, 5:33am UTC](https://discourse.julialang.org/t/git-sha-of-a-project-using-pkg/27211/3 "2019-08-08T05:33:04Z")

</div>

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`.

---

<div class="post-metadata">

**Author:** ![cserteGT3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/csertegt3/32/8283_2.png) [@cserteGT3](https://discourse.julialang.org/u/cserteGT3)\
**Post date:** [August 8, 2019, 6:26am UTC](https://discourse.julialang.org/t/git-sha-of-a-project-using-pkg/27211/4 "2019-08-08T06:26:39Z")

</div>

> [@pixel27](#):
>
> I suspect what you want to do is:
> 
> ```julia
> out = IOBuffer()
> run(pipeline(`git log --format=%H -1`, stdout=out))
> hash=strip(String(take!(out)))
> 
> ```

For similar usecase I do:

```julia
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)?

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [August 8, 2019, 7:19am UTC](https://discourse.julialang.org/t/git-sha-of-a-project-using-pkg/27211/5 "2019-08-08T07:19:56Z")

</div>

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`.

---

<div class="post-metadata">

**Author:** ![cserteGT3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/csertegt3/32/8283_2.png) [@cserteGT3](https://discourse.julialang.org/u/cserteGT3)\
**Post date:** [August 8, 2019, 7:31am UTC](https://discourse.julialang.org/t/git-sha-of-a-project-using-pkg/27211/6 "2019-08-08T07:31:48Z")

</div>

Thanks for the explanation!

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [August 8, 2019, 6:43pm UTC](https://discourse.julialang.org/t/git-sha-of-a-project-using-pkg/27211/7 "2019-08-08T18:43:03Z")

</div>

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`…

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [August 8, 2019, 8:04pm UTC](https://discourse.julialang.org/t/git-sha-of-a-project-using-pkg/27211/8 "2019-08-08T20:04:23Z")

</div>

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`](https://github.com/tkf/InteractiveCodeSearch.jl).

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [August 8, 2019, 8:22pm UTC](https://discourse.julialang.org/t/git-sha-of-a-project-using-pkg/27211/9 "2019-08-08T20:22:29Z")

</div>

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. 🙂
