Thomas Vander Stichele
Thomas Vander Stichele

Reputation: 36549

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

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.

Upvotes: 10

Views: 7544

Answers (3)

mynameispaulie
mynameispaulie

Reputation: 91

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.

Upvotes: 0

Jon Gjengset
Jon Gjengset

Reputation: 4236

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.

Upvotes: 0

nik
nik

Reputation: 13450

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)

Upvotes: 3

Related Questions