summaryrefslogtreecommitdiff
path: root/svn-git-hash.pl
diff options
context:
space:
mode:
authorRenato Golin <renato.golin@linaro.org>2017-04-19 17:56:09 +0100
committerRenato Golin <renato.golin@linaro.org>2017-04-19 18:37:31 +0100
commit937c66c0d14d10933850e632b8109dd609af70bf (patch)
treebab8e580b149e112bfb71d60bea11edd090ed770 /svn-git-hash.pl
parentdbe3652af566dca6a9e49fcb92587a5d96920dba (diff)
svn-git-hash.pl: New script
This script collects the git hash of the closest commit, given an SVN revision. This is intended for LLVM usage, when checking out multiple repositories, given a single SVN revision number, but can work with any repository that is interlocked in the same way. Updates: - Renamed $SVN to $REVISION to disambiguate - Added multiple comments to make decisions explicit - Fixed typos Change-Id: I63482094f3cbdaa7d37be25619ba18ddbe89a1f2
Diffstat (limited to 'svn-git-hash.pl')
-rwxr-xr-xsvn-git-hash.pl63
1 files changed, 63 insertions, 0 deletions
diff --git a/svn-git-hash.pl b/svn-git-hash.pl
new file mode 100755
index 00000000..af94fe8e
--- /dev/null
+++ b/svn-git-hash.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/env perl
+#
+# This script finds the nearest git commit from an SVN revision.
+#
+# In the LLVM repository, all sub-projects are tied together, including their
+# release branches, so each commit is unique to one repository, and all other
+# repos have surrounding revision numbers. When we check out from SVN, providing
+# a number to a repository that doesn't have that revision will bring the last
+# commit in that repo before the chosen one.
+#
+# We need to simulate this here, without having git-svn, so that we can give a
+# single SVN revision number to a Jenkins job and have any number of
+# repositories checked out, and all of them guaranteed to be in the right place.
+#
+# This script was written for LLVM, but it's generic enough that it doesn't
+# depend on any LLVM behaviour, and would work on any number of repositories
+# interlocked in the same way.
+
+use strict;
+use warnings;
+
+my $USAGE = "$0 rNNNNN\n";
+
+# Basic checks
+# This should not be ran by users, so make sure we're at the base of the repo
+if (! -d ".git" and ! -f ".git") {
+ die "Not in a git repository.\n$USAGE";
+}
+my $REVISION = $ARGV[0];
+if (not defined $REVISION) {
+ die $USAGE;
+} elsif ($REVISION =~ /^r(\d+)$/) {
+ $REVISION = $1;
+} else {
+ die "Invalid SVN revision '$REVISION'. $USAGE";
+}
+
+# Current git/svn info
+my ($git, $svn);
+
+# Walk the log until the exact (or lower) revision is found
+open LOG, "git log|" || die "Can't run git log command: $!\n";
+foreach my $line (<LOG>) {
+ # Make sure we always update git hashes to the latest
+ # 11 chars, to be easy to compare to git log --pretty=oneline
+ if ($line =~ /^commit ([0-9a-f]{11})/) {
+ $git = $1;
+ next;
+ }
+ # When we get to the right SVN revision, just return the last git hash
+ # FIXME: For non-LLVM uses, a different branch may be needed
+ if ($line =~ /^\s+git-svn-id: .*trunk@(\d+) /) {
+ $svn = $1;
+ if ($svn <= $REVISION) {
+ if (not defined $git) {
+ die "Log format error, can't find git commit for SVN '$REVISION'.\n$USAGE";
+ }
+ print "$svn $git\n";
+ last;
+ }
+ }
+}
+close LOG;