Get UTC date of last commit - bash

I'm trying to put together a bash/sh script that gets the UTC time of the last commit from a svn repo (the other VCSs are easy)
I understand that i can just do svn propget --revprop -rHEAD svn:date and get it rather easily, but there is no guarantee that the svn checkout will be online, so I'd prefer an offline version, if possible.
Maybe something to do with getting the UTC time from svn info? (by screwing with the timezones)
Summary: How can i get the UTC time of a svn commit, while not having access to the server?
Thanks

You can use svn log -r COMMITTED and extract date info from it. This is valid for offline copies.
svn log -r COMMITTED | sed -nE 's/^r.*\| ([0-9]{4}-[0-9]{2}-[0-9]{2} \S+ \S+).*/\1/p' | xargs -i -- date -ud '{}' '+%s'
The -u option makes date show UTC time instead.
Actually we don't need to use xargs:
date -ud "$(exec svn log -r COMMITTED | sed -nE 's/^r.*\| ([0-9]{4}-[0-9]{2}-[0-9]{2} \S+ \S+).*/\1/p')" '+%s'
UPDATE: I got the wrong command. The command above won't work offline. Here's the right one:
date -ud "$(svn info | sed -nE 's/^Last Changed Date: (\S+ \S+ \S+).*/\1/p')" '+%s'

I'm silly. As soon as i actually realised i just need to convert one timezone to another, it was obvious:
date -u +[format] -d $(svn info | <some grepping and cutting here>)
In my case, this is:
date -u +"%Y%m%d-%H%M" -d "$(svn info | grep 'Date' | cut -d' ' -f4-6)"
Of course, my solution probably isn't optimal, and if someone knows a better way, that'd be much appreciated :)

It turns out that the xml output of "svn info" has a zulu timestamp:
$ svn info --xml | grep date
<date>2015-04-30T15:38:49.371762Z</date>
So your bash command might be:
svn info --xml | grep -oP '(?<=<date>).*?(?=</date>)'

I just stumbled on this post. Ended up figuring out that svn uses env variable TZ, so for example:
TZ= svn log
will log dates in UTC

Related

Translate git-log old commiter timestamp to strict ISO 8601 timestamp

I am responsible for deploying an application and as part of the deployment process, I need to get the latest committer timestamp in strict ISO 8601 format and place it in the database. For recent versions of git, it's fairly straight forward:
$ git log --pretty=format:'%cI' -n1
2019-05-29T10:24:58+04:00
But unfortunately, I have a few older instances where the switch %cI does not exist in the installed git. So to get close to the ISO 8601, I use %ci instead, resulting in:
$ git log --pretty=format:%ci -n1
2019-05-29 10:24:58 +0400
We will eventually upgrade the machines to a later version of operating system, and consequently a more modern version of git. Newer versions of git has this in the man page:
• %ci: committer date, ISO 8601-like format
• %cI: committer date, strict ISO 8601 format
But in the meantime, I want to massage this ISO 8601-like string on the older machines to the strict ISO 8601 format above. I wrote a bad looking one-liner to do this and it seems to work:
$ git log --pretty=format:'%ci' -n1 | sed -e 's/ /T/1' -e 's/ //1' -e 's/.\{22\}/&:/1'
2019-05-29T10:24:58+04:00
Simply, it replaces the first space with a T, the second space with nothing and inserts a colon : at the 22nd character position. How do I do this better? I tried looking up ways to do this with the date command; no luck.
you mean something like this?
date -d "$(git log --pretty=format:%ci -n1)" --iso-8601=seconds
Using sed:
$ echo '2019-05-29 10:24:58 +0400' | sed -e 's/ /T/' -e 's/ //' -e 's/..$/:\0/'
2019-05-29T10:24:58+04:00
Replace the first space with T, remove the second space, replace the last 2 characters with a colon and those 2 chars.

How to use grep to get mercurial changeset id?

So from the below I want to fetch the 6e4a01192927part in my bash script
$ hg log -l1
changeset: 1775:6e4a01192927
branch: xxx
tag: tip
parent: 1772:7892c965215d
parent: 1774:5a9a3e060869
user: Firstname Lastname <someone#something.xyz>
date: Thu Jan 25 09:55:35 2018 +0000
summary: Merged in fix/something (pull request #85)
I am on Mac, El Capitan so it seems I am very limited in the ways I can grep it..
For example grep -oP isn't supported..
I have gotten this far but then hit a brick wall..
$ hg log -l1 | sed -n 1p # fetching first line only
changeset: 1775:6e4a01192927
If you are absolutely sure of the search string use Awk to match the first field and print the field next to it
hg log -l1 | awk -F: '$1=="changeset"{print $NF}'
Here $1 and $NF represent the first and the last fields split by the de-limiter :
Also a bash trick do it would be to read the first line from the command and use paramter expansion syntax
read -r firstLine < <(hg log -l1)
echo "${firstLine##*:}"
Mercurial has many ways to give you just the id of the most recent (or any) commit.
$ hg id -i -r .
68e111c5bd42
or using log:
$ hg log -l 1 --template '{node|short}'
68e111c5bd42
fewer processes spawned and more portable.

Grep a time stamp in the H:MM:SS format

Working on the file an need to grep the line with a time stamp in the H:MM:SS format. I tried the following egrep '[0-9]\:[0-9]\:[0-9]'. Didn't work for me. What am i doing wrong in regex?
$ date -u | egrep '\d{1,2}:\d{1,2}:\d{1,2}'
Fri May 2 00:59:47 UTC 2014
Try a site like http://regexpal.com/
Here is the fix:
grep '[0-9]:[0-9][0-9]:[0-9][0-9]'
If you need get timestamp only, and your grep is gnu grep.
grep -o '[0-9]:[0-9][0-9]:[0-9][0-9]'
and if you work more harder, limit on time format only:
grep '[0-2][0-9]:[0-5][0-9]:[0-5][0-9]'
Simplest way that I know of:
grep -E '([0-9]{2}:){2}[0-9]{2}' file
If you need month and day also:
grep -E '.{3,4} .{,2} ([0-9]{2}:){2}[0-9]{2}' file

Sorting git timestamp in the shell

I have a list of Git timestamps in the format Mon Jan 1 01:01:01 2013 +0500. I need sort them in the shell somehow and have no clue how to approach this. So far I've created two arrays - one for months and one for days.
Any suggestions?
Thanks.
EDIT: This is not a git log that I'm going through, this is just a bunch of git timestamps that I have pulled out from different repos.
You can use date to convert to a format that's easier to sort, such as epoch. I'll assume you have a file called dates.in, with one date per line.
#!/bin/bash
while read d; do
date -d "$d" +%s
done <dates.in | sort | \
while read d; do
date -d "#$d"
done

using bash to get revision number from subversion

I want to write a shell script in bash to deploy websites from an svn repository. When I deploy a website, I name the exported directory website_name-Rrevision_number. I'd like the bash script to automatically rename the exported directory, so it needs to learn the current revision number from the export directory. If I run
$> svn info http://svn-repository/trunk
Path: trunk
URL: http://svn-repository/mystery/trunk
Repository Root: http://svn-repository/mystery
Repository UUID: b809e6ab-5153-0410-a985-ac99030dffe6
Revision: 624
Node Kind: directory
Last Changed Author: author
Last Changed Rev: 624
Last Changed Date: 2010-02-19 15:48:16 -0500 (Fri, 19 Feb 2010)
The number after the string Revision: is what I want. How do I get that into a bash variable? Do I do string parsing of the output from the svn info command?
Use svnversion. This will output the revision number/range with minimal additional cruft
REVISION=`svn info http://svn-repository/trunk |grep '^Revision:' | sed -e 's/^Revision: //'`
It's simple, if inelegant.
Parsing the 'Revision' string is not portable across different locales.
Eg. with my locale it is like:
...
Wersja: 6583
Rodzaj obiektu: katalog
Zlecenie: normalne
Autor ostatniej zmiany: ...
Ostatnio zmieniona wersja: 6583
Data ostatniej zmiany: 2013-03-21 11:33:44 +0100 (czw)
...
You don't wanna parse that :)
So, the best approach is to use 'svnversion' as oefe suggested. This is the tool mentioned for this purpose.
just use one awk command. much simpler as well.
var=$(svn info http://svn-repository/trunk | awk '/^Revision:/{print $2}')
Without using sed, grep or awk:
REVISION=`svn info --show-item=revision --no-newline`
svn info http://svn-repository/trunk | grep Revision | tr -d 'Revison: '
Spits out the revision
Use backticks in your shell script to execute this and assign the results to a variable:
REVISION=`svn info http://svn-repository/trunk | grep Revision | tr -d 'Revison: '`
There are probably a dozen different ways to do this, but I'd go with something simple like:
revision="$(svn info http://svn-repository/trunk | grep "^Revision:" | cut -c 11-)"
This will give you the head revision number
svn info -r 'HEAD' | grep Revision | egrep -o "[0-9]+"
egrep is extended grep.
REVISION=$(svn info http://svn-repository/trunk |grep '^Revision:' | sed -e 's/^Revision: //p')
echo $REVISION

Resources