diff --git a/bin/add-parents.py b/bin/add-parents.py index fb06e24..f281e9d 100755 --- a/bin/add-parents.py +++ b/bin/add-parents.py @@ -1,88 +1,88 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # -*- coding: utf-8 -*- """ Usage: git filter-branch --parent-filter "$(add-parents )" Outputs a shell script for filter-branch --parent-filter, to add extra parents to existing commits. parentmap must be a filename with *git* revisions formatted like this: f3ca1dab5c862581690a988ab41ac59a292095f8 1ddbe3918159275dd514aea734839583bfd24c59 fceef269d3a1c3e9321f5dd376f6b305176854d6 da3e27ee47f6016cff637045f29a74f90a4cdab2 For each line in the parentmap, the returned script will add the first revision as a new parent for the second revision. In other words, it adds a new first->second connection between revisions. Most probably, the first revision will predate the second. Only full SHA-1 IDs are supported, not general revision parameters, like abbreviated hashes or tag names. It seems to work better if you use --date-order in filter-branch, because the date order usually matches the SVN revision order. You can use bin/translateRevlist.py to convert a list of SVN revision number pairs into git revision pairs usable in this script. """ import sys import re if len(sys.argv) < 2: parentmap = sys.stdin elif len(sys.argv) == 2: if sys.argv[1] == '-': parentmap = sys.stdin else: parentmap = file(sys.argv[1], 'r') else: print >> sys.stderr, "usage: add-parents [filename]" sys.exit(1) code_template=""" parents=; clear=no case $GIT_COMMIT in %s esac; if [ -n "$parents" ]; then if [ "x$clear" = "xno" ]; then cat; fi for parent in $parents; do echo " -p $(map $parent)"; done; else cat; fi """ # given mappings[A] = [B,C]: B and C will be added as new parents of A mappings={} to_clear={} for line in parentmap: match = re.match(r'(clear|[0-9a-fA-F]{40})\s+([0-9a-fA-F]{40})\b', line) if match: # add $1 as a parent of $2 = if commit is $2, add $1 as its parent newparent = match.group(1) child = match.group(2) if newparent == 'clear': to_clear[child] = 1 else: if child not in mappings: mappings[child] = [] mappings[child].append(newparent) case_lines=[] for child, parents in mappings.iteritems(): line = " %s)" % child if child in to_clear: line += " clear=yes;" line += " parents='%s';;" % (' '.join(parents)) case_lines.append(line) print code_template % '\n'.join(case_lines) diff --git a/bin/nullgzip.py b/bin/nullgzip.py index 9ccf74e..8fea9a9 100755 --- a/bin/nullgzip.py +++ b/bin/nullgzip.py @@ -1,35 +1,36 @@ -#! /usr/bin/python +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- from __future__ import print_function import gzip import sys CHUNKSIZE = 4096 if len(sys.argv) != 3: print('Usage: %s ' % sys.argv[0], file=sys.stderr) print('Creates an uncompressed gzip file from a gzip input file.', file=sys.stderr) sys.exit(0) try: inFile = gzip.open(sys.argv[1], 'rb') except IOError: print('Cannot open input file.', file=sys.stderr) sys.exit(1) try: outFile = gzip.open(sys.argv[2], 'wb', 0) except IOError: print('Cannot open output file.', file=sys.stderr) sys.exit(1) try: with inFile, outFile: bytes = inFile.read(CHUNKSIZE) while bytes: outFile.write(bytes) bytes = inFile.read(CHUNKSIZE) except IOError: print('Error while copying content from input file to output file.', file=sys.stderr) sys.exit(1) diff --git a/bin/stripFITS.py b/bin/stripFITS.py index c885696..e84ba32 100755 --- a/bin/stripFITS.py +++ b/bin/stripFITS.py @@ -1,36 +1,36 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # -*- coding: utf-8 -*- """ Some .xpm files in ksnake contain binary data at the end. This is a copy of the same image but in FITS format. Those files have been generated by xv 3.10a which had this bug: By cleverly harnessing the amazing power of a missing 'break' statement, xv was writing XPM files with a FITS version of the image conveniently tacked on the end. Hilarity ensues. (cited from http://www.trilon.com/xv/downloads.html) """ import os def hasFITS(lines): return any('SIMPLE =' in x for x in lines) for dirpath, _, filenames in os.walk('.'): for filename in filenames: if filename.endswith('.xpm'): fullName = os.path.join(dirpath, filename) with open(fullName, 'r') as xpmFile: lines = xpmFile.readlines() xpmFile.close() if hasFITS(lines): with open(fullName,'w') as xpmFile: for line in lines: if 'SIMPLE =' in line: break xpmFile.write(line) xpmFile.close() xpmFile.close() diff --git a/bin/translateRevlist.py b/bin/translateRevlist.py index a95e155..612821e 100755 --- a/bin/translateRevlist.py +++ b/bin/translateRevlist.py @@ -1,97 +1,97 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # -*- coding: utf-8 -*- import subprocess import re import sys ''' Converts a list of SVN revisions into the corresponding git revisions in the current repository. The input file should contain any number of SVN revisions per line, as decimal numbers. If there's multiple revisions per line, they're usually separated by whitespace, but any non-word character will work too. In addition, you can follow the revision number with an @ sign and a path to be matched exactly against the SVN path. This is useful when a single SVN commit is converted into multiple git commits based on different SVN paths. For example, to match a commit containing the following: svn path=/branches/kstars/hdevalence/kstars/; revision=1121256 ...you can use "1121256@/branches/kstars/hdevalence/kstars/". This path must match *exactly*. It's not enough to give a prefix. Any other text will be passed unmodified. Only the decimal numbers in the file (possibly followed by @/path) will be converted, and everything else will stay untouched. ''' def get_log_messages(): p = subprocess.Popen(['git','log','-z', '--format=format:%H%x01%b', '--all'], stdout=subprocess.PIPE) rawdata = p.communicate()[0] data = dict((pair.split('\x01') for pair in rawdata.split('\x00'))) p.wait() return data import collections def create_svn_map(msg_map): svnmap = collections.defaultdict(lambda: {}) for gitrev, msg in msg_map.items(): match = re.search(r"^svn path=([^; ]+); revision=(\d+)", msg, re.MULTILINE) if match: svnrev = int(match.group(2)) path = match.group(1) svnmap[svnrev][path] = gitrev return svnmap def process_integers(line, func): result = '' last_idx = 0 for match in re.finditer('\\b(\d+)(?:@(/[a-zA-Z0-9/_.-]+))?', line): result += line[last_idx:match.start()] # append text before this match result += func(int(match.group(1)), match.group(2)) # and append the processed integer we matched last_idx = match.end() result += line[last_idx:] # finally, append text after the last match (maybe only the final newline) return result if len(sys.argv) < 2: input_file = sys.stdin elif len(sys.argv) == 2: input_file = file(sys.argv[1], 'r') else: print >> sys.stderr, "usage: translateRevlist.py [filename]" sys.exit(1) print >> sys.stderr, "translateRevlist getting git log...", log_messages = get_log_messages() print >> sys.stderr, "done" svnmap = create_svn_map(log_messages) def get_match(svnrev, path=None): if path is None: if len(svnmap[svnrev]) == 0: sys.stderr.write("error: r%d not found in log\n" % svnrev) sys.exit(1) elif len(svnmap[svnrev]) > 1: sys.stderr.write("warning: %d has more than one match:\n" % svnrev) for path,gitrev in svnmap[svnrev].items(): sys.stderr.write(" %d@%s %s\n" % (svnrev,path,gitrev)) #return ','.join(['%d@%s' % (svnrev,path) for path in svnmap[svnrev].keys()]) return svnmap[svnrev].values()[0] else: return svnmap[svnrev][path] for line in input_file: if line.startswith('#'): continue new_line = process_integers(line, get_match) sys.stdout.write(new_line) # vim: set ts=4 sw=4 et tw=78: