#!/usr/bin/python # # find a linux kernel commit message (including its associated diff) # given a search text provided by the user # # Copyright (C) 2009 Michael S Gilbert # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os import re import sys import urllib import tempfile if ( len( sys.argv ) < 2 ): sys.stderr.write( 'usage: %s {only-rc|oldest-version=2.6.#}\n' % sys.argv[0] ) sys.exit( 1 ) if ( len( sys.argv ) > 2 ): onlyrc = sys.argv[2] == 'only-rc' if sys.argv[2].startswith( 'oldest-version=' ): oldest_version = int( sys.argv[2].split( '=' )[1].split( '.' )[2] ) else: oldest_version = 12 else: onlyrc = False oldest_version = 12 if not os.path.exists( '/usr/bin/git' ): sys.stderr.write( 'error: this script uses git; please install the package\n' ) sys.exit( 1 ) # if not already downloadeded, clone stable kernel.org git repo giturl = 'git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6-stable.git/' gitdir = './linux-2.6-stable' if not os.path.exists( os.path.join( gitdir , '.git/HEAD' ) ): sys.stdout.write( 'Existing git repository not found; will now clone from kernel.org.\n\n' ) sys.stdout.write( 'This may take a while, so if you already have a working stable repository,\n' ) sys.stdout.write( 'please copy it to the current directory with the name \'%s\'.\n' % gitdir.lstrip( './' ) ) sys.stdout.write( 'Note that this *is not* Linus Torvald\'s repository, it is the stable repo:\n' ) sys.stdout.write( '%s\n\n' % giturl) if ( os.system( 'git clone %s %s' % ( giturl , gitdir ) ) != 0 ): sys.exit( 1 ) # if kernel.org repository has updates, pull them os.chdir( gitdir ) fread = open( './.git/refs/heads/master' , 'r' ) local_hash = fread.readline().strip( '\n' ) fread.close() fread = urllib.urlopen( 'http://ftp%s/packed-refs' % giturl[9::] , 'r' ) split = [ '' , '' ] while ( split[1] != 'refs/heads/master' ): split = fread.readline().strip( ' \n' ).split() if len( split ) < 2: split = [ '' , '' ] remote_hash = split[0] fread.close() if ( local_hash != remote_hash ): if ( os.system( 'git pull' ) != 0 ): sys.exit( 1 ) # retrieve set of release tags pipe = os.popen( 'git tag -l' ) tags = pipe.readlines() tags.reverse() pipe.close() # generate changelog+diff files lastversion = '' ismainline = True rootname = 'changelog+diff' for tag in tags: version = tag.strip( '\n' ) isnotrc = tag.find( '-rc' ) < 0 if isnotrc: ismainline = False if isnotrc or ismainline: if ( lastversion != '' ): fname = '%s-%s' % ( rootname , lastversion.lstrip( 'v' ) ) if onlyrc and ( lastversion.find( '-rc' ) < 0 ): break elif ( int( version.split( '.' )[2].split( '-' )[0] ) >= oldest_version ): if not os.path.exists( fname ): tmpname = tempfile.mkstemp()[1] sys.stdout.write( 'generating: %s\n' % fname ) if ( os.system( 'git log -p %s..%s > %s' % ( version , lastversion , tmpname ) ) != 0 ): os.system( 'rm %s' % tmpname ) sys.exit( 1 ) if ( os.system( 'cp %s %s' % ( tmpname , fname ) ) != 0 ): os.system( 'rm %s' % tmpname ) sys.exit( 1 ) os.system( 'rm %s' % tmpname ) lastversion = version # search thru the generated files for text of interest lastfname = '' foundtext = False pipe = os.popen( 'grep \'%s\' $(ls -r %s*)' % ( sys.argv[1] , rootname ) ) pline = pipe.readline() while pline: fname = pline.split( ':' )[0] if fname != lastfname: fread = open( fname , 'r' ) line = fread.readline() while line: if line.startswith( 'commit' ): if foundtext: sys.stdout.write( 'found search text \'%s\' in release %s:\n' % ( sys.argv[1] , fname[len( rootname )+1::] ) ) sys.stdout.write( commit ) foundtext = False commit = '| %s' % line else: commit += '| %s' % line if re.search( sys.argv[1] , line ): foundtext = True line = fread.readline() fread.close() lastfname = fname pline = pipe.readline() pipe.close()