43

I'm currently using a collection of three commands to get the current tag, branch and the date and SHA1 of the most recent commit.

git describe --always --tag
git log -1 --format="%H%n%aD"
git rev-parse --abbrev-ref HEAD

Which will output something like:

1.2.3-5-gdeadbeef
deadbeef3b8d90071c24f51ac8f26ce97a72727b
Wed, 19 May 2010 09:12:34 +0200
master

To be honest, I'm totally fine with this. But I'm using these commands from Maven and anyone who'd used Maven before, knows how much things like external commands bloat the POM. I just want to slim down my pom.xml and maybe reduce execution time a bit.

Koraktor
  • 41,357
  • 10
  • 69
  • 99
  • 1
    Why do you use such things within Maven or in POM ? – khmarbaise May 19 '10 at 08:04
  • 4
    To generate information about the package built. It's the easiest way to "link" a binary package like a JAR with it's corresponding status in a Git repository. – Koraktor May 19 '10 at 08:20

6 Answers6

52
  1. git log is extremely flexible, with lots and lots of options. You might not be able to reproduce the exact output of the three commands above, but you might come close enough to achieve the effect you need.

    For example:

    git log --pretty=format:'%ad %h %d' --abbrev-commit --date=short -1
    

    produces the date, SHA-1 and symbolic references (including tags) of the latest (HEAD) commit:

    2010-05-20 45bd5e7 (HEAD, origin/master)

    After which, presumably, sed and/or awk or maybe Maven-native methods can do the fine-tuning/polishing. Note that a particular tag is associated with a particular commit, so if it was three commits prior to HEAD that was tagged with, for example, "v1.0.0", you are not going to see "v1.0.0" showing up with the above.

  2. A simpler single command to provide a succint description of a commit is:

    git describe
    

    which writes out the latest applicable tag, the number of commits since the tagged commit, and the SHA1:

    v3.3.0-46-g71a77dc

  3. I am not at all familiar with Maven, and have no idea how easy/difficult it is to run external processes, so am unsure whether any of the following help in any way, but I thought I might mention it just in case.

    For the exact purpose that you describe, i.e. tagging builds, in an autoconf/automake framework, I actually use something like:

    BUILDTAG="`git symbolic-ref HEAD 2> /dev/null | cut -b 12-`-`git log --pretty=format:\"%h\" -1`"
    

    which produces something suitable for tacking onto the end of a program path:

    master-c5282ff

    A more extended description, suitable for including as a comment or a printed identifier:

    BUILDDESC="$(git symbolic-ref HEAD 2> /dev/null | cut -b 12-)-$(git log --pretty=format:'%h, %ad' -1)"
    

    produces something like:

    master-c5282ff, Fri Mar 12 22:19:51 2010 -0600

I think playing around with git log, possibly in conjunction with text processing tools/methods will get you what you want.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
Jeet
  • 38,594
  • 7
  • 49
  • 56
  • Before starting to use something like `sed` or `awk` to get almost (!) what I want, I'll most likely stay with my three separate commands. Thanks anyway. – Koraktor May 20 '10 at 10:46
  • Minor note: #3 produces output `master-"c5282ff"` – msanford Apr 10 '15 at 16:51
10

I don't use Maven, so I don't know how you are calling these commands, but adding custom commands to git is fairly trivial.

Create a script called git-tbc that looks like this:

#!/bin/bash

git describe --always --tag
git log -1 --format="%H%n%aD"
git rev-parse --abbrev-ref HEAD

Make sure git-tbc is in your PATH, you can now call "git tbc". Is this what you were looking for?

Peter Farmer
  • 9,020
  • 5
  • 27
  • 29
  • This is definitely a nice way to solve my problem. Didn't think about creating a custom Git command. But I'd be more interested in a single, built-in Git command. I don't want to have to distribute custom Git commands to other developers. :X – Koraktor May 19 '10 at 08:22
  • 1
    Fair comment, you could include the command in git repository and let git do the work for you, but again dev's would need to modify their PATH. – Peter Farmer May 19 '10 at 08:42
  • Another thing I'd like to avoid. Before including arbitrary commands in bash scripts inside my repositories, I'd rather stay with multiple executions for those commands. Just a matter of preference. Thanks though. – Koraktor May 19 '10 at 08:59
  • The best way to add something this simple as a git command is to use an alias. If you want to go one step farther, the easiest thing is to set `GIT_EXEC_PATH="/path/to/git/libexec/git-core:/path/to/my-git-commands"` so that you don't actually have to touch the installation. – Cascabel May 19 '10 at 12:54
  • 1
    @Jefromi Why mangle with GIT_EXEC_PATH when just putting your git commands within your PATH will be fine, I always run a ~/bin on my dev boxes for other custom commands. – Peter Farmer May 19 '10 at 15:39
  • 1
    @Peter Farmer: Well, if you want a batch script, throw it in your PATH, sure. If you want to run it as `git tbc`, though, it needs to be in the git exec path. This is where git looks to find its commands. (A few versions ago, git did indeed throw all of its commands in your PATH, but this has been changed. You should not expect to find any git commands in your path anymore.) – Cascabel May 19 '10 at 20:16
  • Guess I'd better upgrade my installation then. – Peter Farmer May 19 '10 at 21:31
  • 1
    Jefromi (and Peter), I have the latest version of Git. And it *still* finds any command on my PATH that is prefixed with "git-", and allows me to invoke it as "git ". No need to mess with GIT_EXEC_PATH. – Jeet May 20 '10 at 10:57
  • @Peter, Jeet: Ah, I see. It does indeed still work through PATH. However, the entire reason that the git binaries were moved out of its `bin` installation directory was to avoid cluttering your PATH with things that will always be run as `git ` instead of `git-command`. By placing them in your PATH, you're just setting yourself to head back in that direction, but it's your choice if you want to do that. – Cascabel May 20 '10 at 12:47
6

I created a Maven plugin for exactly this purpose, which really fits my needs (in fact it exceeds them by now).

It's called Mavanagaiata, it's open-source and available from Maven Central.

Koraktor
  • 41,357
  • 10
  • 69
  • 99
4

My "repo" for things like that is always bash_completion. Ok, "tab tab" is the way bash becomes a productive tool, so, where all that magic stuff come from?

there is a /etc/bash_completion.d/ directory where extensions for bash completion are left. there must be a git file executable, open it and seek for something like get_refs(). If you give it a check you will find that git describe and git for-each-ref are your friends, let's try some examples:

A common repo:

$ cd /your/git/repo; git branch -a
  master
  blaster
* brunch
  lunch
  remotes/origin/master
  remotes/origin/develop
  remotes/github/master

Which is my checked branch?

$ git describe --contains --all HEAD
brunch

What are my remotes?

$ git remote
origin
github

What are the branches on remotes?

$ git for-each-ref --format="%(refname:short)" refs/remotes
origin/master
origin/develop
github/master

What are my local branches?

$ git branch
  master
  blaster
* brunch
  lunch

...a more parseable branches output?

$ git for-each-ref --format="%(refname:short)" refs/heads
master
blaster
brunch
lunch

What about tags?

$ git for-each-ref --format="%(refname:short)" refs/heads refs/remotes refs/tags
master
blaster
brunch
lunch
origin/master
origin/develop
github/master
release-0_1
release-0_2
release-1_0

check the "man pages" for this commands, there's much more inside!.

albfan
  • 12,542
  • 4
  • 61
  • 80
  • 1
    I have no idea why this was upvoted; it's not at all answering the (very plainly stated) question: namely, to get the "current tag, branch, date and SHA1 of the most recent commit." Useful or not, it doesn't answer the question. – michael Feb 10 '13 at 10:35
  • His own response seems valid enough, so why bother with another bash script?. Many people could reach this question to get any kind of ref about his own repo. I guess that's the reason for upvote it. my response was upload more than a year later from the question, with many good answers around. – albfan Feb 20 '13 at 01:25
  • But, your answer would also require a bash script to glue the various pieces together, too, no? Sure, you've posted some interesting snippets of git-fu (plus, the tip of harvesting bash-completion is also a good idea.) But the only problem is that we came to this question specifically looking for the most recent commit's "tag + branch + date + SHA1" (i.e, the answer to the question). Not just "branch" or "tag" (that's all you've shown): each individually easily googled; but the combo (in one command) isn't. But we have to read through "stuff y'all might find interesting" just to find this out. – michael Feb 21 '13 at 03:40
  • I'm agree. I forgot to mention http://stackoverflow.com/a/6719718/848072. Is the same response as @Peter Farmer – albfan Feb 21 '13 at 10:02
3

I have found this Maven Plugin: https://github.com/alx3apps/jgit-buildnumber, which seems a good replacement of buildnumber-maven-plugin for git projects. Furthermore it is available from Maven Central Repositories.

It works nicely in Maven 3. For Maven 2 multi-module projects, simply add the following line in the properties section of your parent pom:

<session.executionRootDirectory>${basedir}</session.executionRootDirectory>
edrabc
  • 1,259
  • 1
  • 14
  • 23
1

This displays the commit id of HEAD, as well as any branches or any tags that also happen to be exactly at HEAD.

git reflog --decorate -1

Sample output:

484c27b (HEAD, tag: deployment-2014-07-30-2359, master, origin/master) HEAD@{0}: 484c27b878ca5ab45185267f4a6b56f8f8d39892: updating HEAD
webmat
  • 58,466
  • 12
  • 54
  • 59