]> asedeno.scripts.mit.edu Git - git-svn-keywords.git/blobdiff - git-svn-keywords.py
Bump copyright through 2010
[git-svn-keywords.git] / git-svn-keywords.py
index bf8191c68607dc58d91bf3282f8f403be1dd90c4..f3fddb84a56145730a862c1d9aef138f9725cd7e 100755 (executable)
@@ -1,7 +1,7 @@
-#!/usr/bin/python
+#!/usr/bin/python2.6
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2009 Alejandro R. Sedeño <asedeno@mit.edu>
+# Copyright (c) 2009-2010 Alejandro R. Sedeño <asedeno@mit.edu>
 
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation files
@@ -32,7 +32,7 @@ from optparse import OptionParser
 from fnmatch import fnmatch
 import git
 
-VERSION = "0.9"
+VERSION = "0.9.1"
 
 # Where we keep data in the repo.
 def gsk(g):
@@ -66,33 +66,65 @@ def get_svn_keyword_re(s):
         svn_keywords_re[s] = re.compile('\$(' + ('|'.join(svn_keywords[s])) + ')[^$]*\$')
     return svn_keywords_re[s]
 
-# Parse the unhandled log.
-def _do_parse_unhandled(f, lastrev=None):
-    # Compile the regular expressions we'll be using here.
-    re_rev = re.compile("^r(\d+)$")
-    re_keywords = re.compile("^\s+[-+]file_prop: (\S+) svn:keywords ?(\S*)$")
-
-    rev = None
-    for line in f:
-        m = re_rev.match(line)
-        if m:
-            rev = m.group(1)
-            continue
+def conf_right_version():
+    ver = -1
+    if CONFIG.has_option('core', 'version'):
+        ver = CONFIG.get('core', 'version')
+    return ver == VERSION
 
-        if (lastrev >= int(rev)):
-            continue
+def read_file_data():
+    if conf_right_version():
+        FILES.read(FILES_PATH)
 
-        m = re_keywords.match(line)
-        if m:
-            path = urllib.unquote(m.group(1))
-            keywords = set(urllib.unquote(m.group(2)).split(' '))
-            if not FILES.has_section(path):
-                FILES.add_section(path)
-            FILES.set(path, rev, keywords)
+def get_last_rev(path):
+    if not CONFIG.has_section(path):
+        CONFIG.add_section(path)
+
+    lastrev = None
+    if conf_right_version() and CONFIG.has_option(path, 'lastrev'):
+        try:
+            lastrev = CONFIG.getint(path, 'lastrev')
+        except ValueError:
+            lastrev = None
+    return lastrev
 
-    lastrev = max(int(rev), lastrev)
-    CONFIG.set('core', 'lastrev', lastrev)
-    CONFIG.set('core', 'version', VERSION)
+
+# Parse the unhandled log.
+def _do_parse_unhandled(directory):
+    base = os.path.join(directory)
+    for d in os.listdir(base):
+        subent = os.path.join(base, d)
+        if (d == 'unhandled.log' and os.path.isfile(subent)):
+            rev = None
+            strip_prefix = g.git.config('--get','svn-remote.svn.fetch').split(':')[0]
+            lastrev = get_last_rev(subent)
+            with open(subent, 'r') as f:
+                # Compile the regular expressions we'll be using here.
+                re_rev = re.compile("^r(\d+)$")
+                re_keywords = re.compile("^\s+[-+]file_prop: (\S+) svn:keywords ?(\S*)$")
+
+                for line in f:
+                    m = re_rev.match(line)
+                    if m:
+                        rev = m.group(1)
+                        continue
+
+                    if (lastrev >= int(rev)):
+                        continue
+
+                    m = re_keywords.match(line)
+                    if m:
+                        path = urllib.unquote(m.group(1))
+                        path = os.path.relpath(path, strip_prefix)
+                        keywords = set(urllib.unquote(m.group(2)).split(' '))
+                        if not FILES.has_section(path):
+                            FILES.add_section(path)
+                        FILES.set(path, rev, keywords)
+            if rev:
+                lastrev = max(int(rev), lastrev)
+                CONFIG.set(subent, 'lastrev', lastrev)
+        elif (os.path.isdir(subent)):
+            _do_parse_unhandled(subent)
 
 def parse_svn_unhandled(g):
     try:
@@ -101,18 +133,8 @@ def parse_svn_unhandled(g):
         if e.errno != errno.EEXIST:
             raise
 
-    ver = -1
-    if CONFIG.has_option('core', 'version'):
-        ver = CONFIG.get('core', 'version')
-
-    lastrev = None
-    if ver == VERSION:
-        FILES.read(FILES_PATH)
-        if CONFIG.has_option('core', 'lastrev'):
-            lastrev = CONFIG.getint('core', 'lastrev')
-
-    with open(g.path + '/svn/refs/remotes/git-svn/unhandled.log', 'r') as f:
-        _do_parse_unhandled(f, lastrev=lastrev)
+    _do_parse_unhandled(os.path.join(g.path, 'svn'))
+    CONFIG.set('core', 'version', VERSION)
 
     with open(FILES_PATH, 'wb') as f:
         FILES.write(f)
@@ -134,28 +156,42 @@ def get_path_info(g, path):
 
     # tranlsate that into an svn revision id
     if not CONFIG.has_option('CommitToRev', commit):
-        CONFIG.set('CommitToRev',commit,g.git.svn('find-rev', commit))
+        file_rev = g.git.svn('find-rev', commit)
+        if not file_rev:
+            file_rev = "%iM" % find_last_svn_rev('HEAD')
+        CONFIG.set('CommitToRev', commit, file_rev)
         write_config = True
-    file_rev = CONFIG.get('CommitToRev', commit)
+    else:
+        file_rev = CONFIG.get('CommitToRev', commit)
+        if file_rev[-1] is 'M':
+            # Rewrite old nnnnnnM commits if they're now available in SVN
+            commit = g.commits('HEAD', path, 1)[0].id
+            file_rev2 = g.git.svn('find-rev', commit)
+            if file_rev2:
+                CONFIG.set('BlobToCommit', blob, commit)
+                CONFIG.set('CommitToRev', commit, file_rev2)
+                write_config = True
+                file_rev = file_rev2
 
     # get information about that revision
     info_dict = {}
-    if not CONFIG.has_option('RevInfo', file_rev):
-        for line in g.git.svn('info', path).split("\n"):
-            k, v = line.split(": ", 1)
-            if k == 'Last Changed Date':
-                info_dict['Date'] = v
-            elif k == 'Last Changed Author':
-                info_dict['Author'] = v
-        CONFIG.set('RevInfo', file_rev, info_dict)
-        write_config = True
-    else:
-        info = CONFIG.get('RevInfo', file_rev)
-        info_dict.update(info if type(info) is dict else eval(info))
-
-    if write_config:
-        with open(CONFIG_PATH, 'wb') as f:
-            CONFIG.write(f)
+    if file_rev:
+        if not CONFIG.has_option('RevInfo', file_rev):
+            for line in g.git.svn('info', path).split("\n"):
+                k, v = line.split(": ", 1)
+                if k == 'Last Changed Date':
+                    info_dict['Date'] = v
+                elif k == 'Last Changed Author':
+                    info_dict['Author'] = v
+            CONFIG.set('RevInfo', file_rev, info_dict)
+            write_config = True
+        else:
+            info = CONFIG.get('RevInfo', file_rev)
+            info_dict.update(info if type(info) is dict else eval(info))
+
+        if write_config:
+            with open(CONFIG_PATH, 'wb') as f:
+                CONFIG.write(f)
 
     info_dict['Revision'] = file_rev
     return info_dict
@@ -169,6 +205,7 @@ def find_last_svn_rev(treeish, parent=0):
 
 # Do the work.
 def smudge(g, options):
+    read_file_data()
     parse_svn_unhandled(g)
     rev_head = find_last_svn_rev('HEAD')
     url_base = g.git.svn('info', '--url')
@@ -254,6 +291,12 @@ if __name__ == '__main__':
             print "You are not in a git repository or working directory."
             exit(1)
 
+        if g.bare:
+            print "This appears to be a bare git repository."
+            exit(1)
+
+        os.chdir(g.wd)
+
         CONFIG_PATH = os.path.join(gsk(g), 'conf.ini')
         FILES_PATH = os.path.join(gsk(g), 'files.ini')
         FILEINFO_PATH = os.path.join(gsk(g), 'fileinfo.ini')