How to programatically get the latest commit date on a CVS checkout
Asked Answered
K

3

10

For a script I'm working on to implement bisection using CVS, I want to figure out what the 'timestamp' is of the current checkout. In other words, if I'm on a branch/tag, I want to know the last timestamp something got commited to that branch/tag. If I'm on head, I want to know the last timestamp on head.

I know this is not 100% guaranteed, since cvs checkouts can have different files at different timestamps/revisions/..., but a correct-in-most-cases solution is fine by me.

Naively, I thought that

cvs log -N | grep ^date: | sort | tail -n 1 | cut -d\; -f1

was going to do it, but it turns out it goes through the whole commit history, for all branches/tags.

Kinchinjunga answered 25/6, 2009 at 15:39 Comment(0)
K
3

CVS files on a branch being at different timestamps, the accuracy of picking any one file to get the last time-info for the branch is hardly worth.

But, it can get better if there is some file which will be changed often. For, example, in one of my bases, there is a version.h file which is updated on every version shift (minor or major). That can be used for time-info on the current version (again not accurate to all the files in the branch, but it does give a bottom line).

So, if you know a file that can give you a bottom line value,

cvs log path/to/version.h -r branch/tag | grep ^date | sort | tail -1

will give you the last timestamp for that file.


If you can enumerate the entire file set of the base like this,

find /base/dir -type f | grep -v CVS > files.txt

then, you can loop the cvs command above for each file,

rm -f allFiles.txt
for f in $(<files.txt); do cvs log $f ...etc... tail -1 >> allFiles.txt
sort allFiles.txt | tail -1

Last line of the sort will give you exact date for the most recent commit.
Alas, you will not get the file name (which can also be done with some more fu)

Kalikalian answered 25/6, 2009 at 17:36 Comment(2)
That was the only thing I could come up with too, roughly. In the end, I did one cvs log though, and parsed that for all files. Doing it on each file was going to be dead slow.Kinchinjunga
I think this does not support sticky dates, i.e. it will still give the most recent date instead of the chosen one.Purview
L
0

A faster way to get the latest time a file was changed (which builds upon the answer given by nik) is:

cvs log -bd `date +%Y-%m-%d` ChangeLog | grep ^date

If you want to get only the date, use:

cvs log -bd `date +%Y-%m-%d` ChangeLog | grep ^date | sed 's/date: \([^ ]*\).*/\1/'

This uses the -b flag which uses the default branch and -d which allows you to tell CVS you only care about the latest version up until a given time. The `` expression then passes the current date as the limit, giving you the most recent commit.

On the gnuplot CVS repository, using the -d flag decreases the execution time from ~4s to ~1.5s.

Lanielanier answered 13/8, 2013 at 11:42 Comment(0)
D
0

I came across this thread when looking for a way to grab the timestamp for a file in CVS via a tag programmatically. The other answers are sufficient but I wanted to add my own as follows:

cvs rlog -r<tag_or_revision> <file_path> | grep ^date | cut -c 7-25

I noticed that there cannot be a space between -r and <tag>. It seems a range of tags or revisions as –r<tag1>:<tag2> is also appropriate.

I also wanted to get the date including the full timestamp and found that using cut to perform a substring on the static range of characters seemed easier than using sed.

Finally, and most importantly for my needs I found that the rlog command works as a remote log, whereas the log command requires that the files are actually checked out. In my case I just wanted to lookup the timestamp for files based on a tag and the added step of having to check out the files to perform a log was a major deterrent so I just wanted to add that the rlog command may be useful for your needs.

Dragone answered 23/1, 2019 at 20:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.