Count number of SVN commits within a repository directory - php

I need to find the number of commits for a directory within a repository. I will be dealing with the result within PHP so would probably need to utilise exec(). It will be running on Linux.
I have a slightly quirky repository where the directory structure looks a little like:
/trunk/section1
/trunk/section2
/trunk/section3 (and so on)
I'm going to use the result as part of the version number for each section. As it stands I use the latest revision but ideally would like to have it numbered sequentially instead of 84 -> 120 -> 400 etc.
I plan on counting the commits and using '3' instead of '400', using the above example.

If you really like to count the number of commits just use the following:
svn log -q --stop-on-copy URL/trunk | grep "^r" | wc -l
will printout the number of commits.

I'm not familiar with how to invoke this with php, but you can use the svn log --xml path/to/repository/trunk/section1 command to get the result in xml format. From there it shouldn't be too difficult to count the number of <logentry> nodes in the output.

Related

Checking content of many small files in PHP

I have an unusual problem. Using PHP script, I have to traverse through a folder with around 1 million small text files (size ranges from 1KB to 1MB), and pick only those with ctime in certain interval AND content containing particular search string.
First part (picking files that have time of creation in certain range) I managed using readdir but checking the file content for search string proves to be a challenge. Using file_get_contents (and then stripos) simply won't do. It's slow, it brings my PHP script to its knees.
I'm sure I'm not the first one with this kind of a problem, but I'm not a PHP developer. This code has been inherited from previous dev. I'm not sure which alternative I should be using and what code would spare my server RAM and CPU.
I would try shell_exec combined with find and grep:
$output = shell_exec("find . -type f -ctime $MyCtime -exec grep -H -m 1 $MySearchString {} +;");
-H to show filename
-m 1 to stop searching at first ocurrence in file
PHP won't handle it easily(it will take lots of time + will overload the CPU), consider to use bash and regular expressions to solve the problem
Simply saying, PHP is not the right tool in the situation

Get git commit details without "git" command

First, I've seen and read Git commit date.
How can I get the date of the current HEAD commit in git repo without execution any "git" command? Example: I'm execution commands from PHP and I cannot call exec, but I want to get current commit details.
I have access to .git folder of this repo, but it doesn't seem to be useful for commit details. I was only able to get:
Current branch from .git/HEAD
Current commit id (SHA) from .git/refs/heads/<branch>
But no commit message and no commit date. Is there any way to get it from the fileset?
You can't.
Well, you might be able to, but there are too many complex issues.
Specifically, each Git object is stored in a database of all objects, indexed by hash-ID keys. Some objects are loose: stored as separate files. Such a file is zlib-deflated. Any zlib-inflator can read this file and turn the compressed data into readable, useful data, and what you will see if you do this with a commit hash ID is the actual commit object content:
$ git cat-file -p HEAD | sed 's/#/ /'
tree 1fd4a47af4942cbdee0bdcb4375612ab521a4a51
parent 5571d085b3c9c2aa9470a10bcf2b8518d3e4ec99
author Junio C Hamano <gitster pobox.com> 1531941857 -0700
committer Junio C Hamano <gitster pobox.com> 1531941857 -0700
Third batch for 2.19 cycle
Signed-off-by: Junio C Hamano <gitster pobox.com>
(Here I have used a Git command to do the job, which violates your rule.) The dates are those two time stamps on the author and committer lines. You can simply decode them however you like, though remember to use the time zone offset, -0700 here, as well. (The internal content is prefixed with a header, in this case commit <size>\0, as all Git objects have headers.)
But loose is not the only way objects get stored. Once an object has been lying around loose for a while, Git will eventually pack the object into a pack file. The format of pack files is quite complicated. It is documented—see the Git technical documentation file—but it's subject to change and not worth coding when git cat-file -p already does all the work for you.
So, just use a Git command. This does mean you need Git installed, but you probably need that anyway.
Can't you do something like this. ORS is the line separator just in case you have multiple rows in the file.
awk 'BEGIN { ORS=" " }; { print $1 }' ./.git/FETCH_HEAD

phpunit : how to get the count of tests in a test directory without running test

I would like to statically get a count of number of tests in a directory. Is there something available that I can use? Phpunit seems to have a count before test runs say 0/100 and increments it as the test completes. I would like to fetch that number before hand and exit the run possibly.
The --count-tests option of phploc can give you, just like the grep / wc -l line shown above, an estimate of the number of tests. Due to data providers, for instance, there cannot be an exact number without actually executing the tests.
You can get the list of tests by running the command, phpunit --list-tests.
To get the count, run the command, phpunit --list-tests | wc -l

diff images between 2 servers

I have 2 servers serv1 and serv2 and need to compare the images in those 2 servers to detect which files are missing or has been modified.
So far I have 3 options:
- Create an API using PHP
I created an API file that will return all the images in serv1/www/app/images/
get the modification time of each images
return the result as json
output is something like this: { 'path/to/file' : 123232433422 }
I fetch that in serv2, decode then merge the array to the images in serv2/www/app/images
get the array_diff, works fine
cons:
- takes a lot of time (fetching, decoding, merging, looping, comparison... )
- Use rsync
Dry run to get the list of images that is existing in serv1 but is missing or modified in serv2 (very fast :))
cons:
apache can't run ssh because it's not authorized to access ~/.ssh/
would need to give apache permission but my client doesn't want it
so in short, i cannot use anything that would require permission
- maybe I could use some library or vendor but I doubt my client would allow me. If it can be shell script or a php built in function, I'll do it as long as it's possible.
So my question is if there is another way to fetch the images and modification date of those images without requiring authentication? My first solution is okay if it can be optimized cause if the array is too large, it takes a lot of time.
I hope the solution can be done in PHP, or Shell script.
Please help give me more options. Thanks
Install utility md5deep (or sha1deep) on both servers.
Execute md5deep on first server and save result to text file:
user#server1> md5deep -l -r mydir > server1.txt
Result file would look like this:
e7c3fcf5ad7583012379ec49e9a47b28 .\a\file1.php
2ef76c2ecaefba21b395c6b0c6af7314 .\b\file2.txt
45e19bb4b38d529d6310946966f4df12 .\c\file3.bin
...
Then, copy file server1.txt to second server and run md5deep in negative matching mode:
md5deep -l -r -X server1.txt mydir
This will print checksums and names of all files on second server which are different from first server.
Alternatively, you can compare text files created by md5deep -l -r dir yourself using diff or similar utility.
Last note - it may be easier to simply run md5deep -l -r mydir | gzip > md5deep.txt.gz in cron on each server, such that you have ready to compare filelist with checksums on each server (gzipped so it is fast to fetch).

How can I get the Subversion revision number in PHP?

I want to have my PHP application labeled with the revision number which it uses, but I don't want to use CruiseControl or update a file and upload it every time. How should I do it?
SVN keywords is not a good solution. As others pointed out adding $Revision$ in a file only affects the specific file, which may not change for a long time.
Remembering to "edit" a file (by adding or removing a blank line) before every commit is pointless. You could as well just type the revision by hand.
One good way to do it (that I know of) is to have an automated deployment process (which is always a good thing) and using the command svnversion. Here is what I do:
Wherever I need the revision I do an include: <?php include 'version.php'; ?>. This "version.php" file only has the revision number. Moreover it is not part of the repository (it set to be ignored). Here is how I create it:
1) On projects where SVN is installed on the server, I also use it for deployment. Getting the latest version to the server I have a script that among other things does the following (it runs on the server):
cd /var/www/project
svn update
rm version.php
svnversion > version.php
2) On projects where SVN is not installed my deployment script is more complex: it creates the version.php file locally, zips the code, uploads and extracts it
Assuming your webroot is a checked-out copy of the subversion tree, you could parse the /.svn/entries file and hook out the revision number (4th line here)...
In PHP:
$svn = File('.svn/entries');
$svnrev = $svn[3];
unset($svn);
This is how I got it to work.
If your server is setup to allow shell_exec AND you have SVN installed just run:
$revision = `svnversion`;
or
$revision = shell_exec('svnversion');
From this answer:
You can do it by adding the following
anywhere in your code
$Id:$
So for example Jeff did:
<div id="svnrevision">svn revision: $Id:$</div>
and when checked in the
server replaced $Id:$ with the current
revision number. I also found this reference.
There is also $Date:$, $Rev:$,
$Revision:$
Bit late now, but use a Subversion post-commit hook. In your repository's hooks folder, create a shell script like this one:
#!/bin/bash
REPOS="$1"
REV="$2"
cd /web/root
rm -f /web/root/templates/base.html
/usr/bin/svn update
/bin/sed -i s/REVISION/$REV/ /web/root/templates/base.html
This particular example assumes your live site is in /web/root and the development code is held elsewhere. When you commit a dev change, the script deletes the prior live template (to avoid conflict messages), runs the update and replaces occurrences of REVISION in the template with the actual revision number.
More on hooks here
In most cases the code on the server would actually contain an "Export" of the code, not a checkout, and therefore not contain the .svn folders. At least that's the setup I see most often. Do others actually check out their code onto the web server?
You can get close with SVN Keywords. Add $Revision$ where you want the revision to show, but that will only show the last revision that particular file was changed, so you would have to make a change to the file each time. Getting the global revision number isn't possible without some sort of external script, or a post-commit hook.
You could also do it like this:
$status = #shell_exec('svnversion '.realpath(__FILE__));
if ( preg_match('/\d+/', $status, $match) ) {
echo 'Revision: '.$match[0];
}
The easiest way is to use the Subversion "Keyword Substitution". There is a guide here in the SVN book (Version Control with Subversion).
You'll basically just have to add the text $Rev$ somewhere in your file.
Then enable the keyword in your repository. On checkout SVN will substitute the revision number into the file.
See my response to the similar question "Mark" svn export with revision.
If you capture the revision number when you export you can use:
svn export /path/to/repository | grep ^Exported > revision.txt
To strip everything but the revision number, you can pipe it through this sed command:
svn export /path/to/repository | grep ^Exported | sed 's/^[^0-9]\+\([0-9]\+\).*/\1/' > revision.txt
$svn_rev=file_get_contents('/path.to.repository/db/current');
Another possibility to do this is to run a cron that executes the steps described in the "Deploy Process" (assuming it is a *nix/FreeBSD server).
If performance is an issue, then you could do:
exec('svn info /path/to/repository', $output);
$svn_ver = (int) trim(substr($output[4], strpos($output[4], ':')));
This of course depends on your having done a checkout, and the presence of the svn command.

Categories