Skip to content

Instantly share code, notes, and snippets.

@mnunberg
Last active August 29, 2015 13:56
Show Gist options
  • Save mnunberg/8855974 to your computer and use it in GitHub Desktop.
Save mnunberg/8855974 to your computer and use it in GitHub Desktop.
Parse 'git describe' output
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
static void find_delim(char *s, char **res, int *ix)
{
for(; *ix && s[*ix] != '-'; *ix -= 1);
if (*ix) {
s[*ix] = '\0';
*res = s + *ix + 1;
} else {
*res = s;
}
}
int main(int argc, char **argv)
{
char vbuf[4096] = { 0 };
char *version, *ncommits, *sha;
FILE *po;
int buflen;
char *format;
int force;
int ncommits_i;
if (argc != 2) {
fprintf(stderr, "Usage: %s <FORMAT>\n", argv[0]);
exit(EXIT_FAILURE);
}
/** Get the output */
po = popen("git describe --long", "r");
if (!po) {
perror("git describe");
exit(EXIT_FAILURE);
}
if (!fgets(vbuf, sizeof(vbuf), po)) {
fprintf(stderr, "git describe closed stream\n");
exit(EXIT_FAILURE);
}
fclose(po);
buflen = strlen(vbuf);
vbuf[buflen-2] = '\0';
buflen -= 1;
find_delim(vbuf, &sha, &buflen);
find_delim(vbuf, &ncommits, &buflen);
version = vbuf;
sscanf(ncommits, "%d", &ncommits_i);
format = argv[1];
force = *format == 'F';
if (force) {
format++;
}
if (!force) {
force = ncommits_i;
}
for (; *format; format++) {
switch (*format) {
case 'T':
case 't':
printf("%s\n", version);
break;
case 'N':
case 'n':
if (force) {
printf("%s\n", ncommits);
}
break;
case 's':
case 'S':
if (force) {
printf("%s\n", sha);
}
}
}
return 0;
}
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
my $rv = GetOptions(
'basetag|t' => \my $PrintBase,
'ncommits|n' => \my $PrintCount,
'sha|s' => \my $PrintSHA,
'force|f' => \my $Force,
'help|h' => \my $WantHelp);
my $HELPTEXT =
<<EOF;
-t --basetag Print base tag
-n --ncommits Print number of commits since base
-s --sha Print abbreviated SHA1
-f --force Always print ncommits/sha, even if HEAD is a tag
EOF
if (!$rv) {
print $HELPTEXT;
exit(1);
}
if ($WantHelp) {
print $HELPTEXT;
exit(0);
}
my $output = qx(git describe --long);
$output =~ s/\s+$//g;
$output =~ s/^\s+//g;
my @components = split('-', $output);
my $sha = pop @components;
my $ncommits = pop @components;
my $version = join('-', @components);
if ($PrintBase) {
print "$version\n";
}
if (!$Force) {
$Force = int($ncommits);
}
if ($PrintSHA && $Force) {
print "$sha\n";
}
if ($PrintCount && $Force) {
print "$ncommits\n";
}
#!/usr/bin/env python
from optparse import OptionParser
from subprocess import Popen, PIPE
op = OptionParser()
op.add_option('--basetag',
help="Print base tag", action='store_true')
op.add_option('--ncommits',
help="Print number of commits since tag",
action='store_true')
op.add_option('--abbrev-sha',
help="Print abbreviated SHA1",
action='store_true')
op.add_option('--always-print-extra',
help="Always print abbrev/ncommits, even if HEAD==tag",
action='store_true')
options, args = op.parse_args()
stdout, stderr = Popen(['git', 'describe', '--long'], stdout=PIPE).communicate()
components = stdout.strip().split('-')
sha = components.pop()
ncommits = components.pop()
version = "-".join(components)
print_extras = (int(ncommits)) or options.always_print_extra
if options.basetag:
print version
if options.ncommits and print_extras:
print ncommits
if options.abbrev_sha and print_extras:
print sha
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment