Merge branch 'jk/diff-algo-finishing-touches'
[gitweb.git] / contrib / remote-helpers / git-remote-bzr
index 9466cb9de1d0dbe7d6569d01d628eb52f549549a..bd25e082027f90e614f3f265b94b49979d96e49f 100755 (executable)
@@ -25,6 +25,7 @@ bzrlib.plugin.load_plugins()
 
 import bzrlib.generate_ids
 import bzrlib.transport
+import bzrlib.errors
 
 import sys
 import os
@@ -183,21 +184,24 @@ def get_filechanges(cur, prev):
 
     changes = cur.changes_from(prev)
 
+    def u(s):
+        return s.encode('utf-8')
+
     for path, fid, kind in changes.added:
-        modified[path] = fid
+        modified[u(path)] = fid
     for path, fid, kind in changes.removed:
-        removed[path] = None
+        removed[u(path)] = None
     for path, fid, kind, mod, _ in changes.modified:
-        modified[path] = fid
+        modified[u(path)] = fid
     for oldpath, newpath, fid, kind, mod, _ in changes.renamed:
-        removed[oldpath] = None
+        removed[u(oldpath)] = None
         if kind == 'directory':
             lst = cur.list_files(from_dir=newpath, recursive=True)
             for path, file_class, kind, fid, entry in lst:
                 if kind != 'directory':
-                    modified[newpath + '/' + path] = fid
+                    modified[u(newpath + '/' + path)] = fid
         else:
-            modified[newpath] = fid
+            modified[u(newpath)] = fid
 
     return modified, removed
 
@@ -332,12 +336,9 @@ def export_branch(branch, name):
 
 def export_tag(repo, name):
     global tags
-    try:
-        print "reset refs/tags/%s" % name
-        print "from :%u" % rev_to_mark(tags[name])
-        print
-    except KeyError:
-        warn("TODO: fetch tag '%s'" % name)
+    print "reset refs/tags/%s" % name
+    print "from :%u" % rev_to_mark(tags[name])
+    print
 
 def do_import(parser):
     global dirname
@@ -512,6 +513,11 @@ class CustomTree():
     def get_symlink_target(self, file_id):
         return self.updates[file_id]['data']
 
+def c_style_unescape(string):
+    if string[0] == string[-1] == '"':
+        return string.decode('string-escape')[1:-1]
+    return string
+
 def parse_commit(parser):
     global marks, blob_marks, bmarks, parsed_refs
     global mode
@@ -551,6 +557,7 @@ def parse_commit(parser):
             f = { 'deleted' : True }
         else:
             die('Unknown file command: %s' % line)
+        path = c_style_unescape(path).decode('utf-8')
         files[path] = f
 
     repo = parser.repo
@@ -651,12 +658,25 @@ def do_capabilities(parser):
 
     print
 
+def ref_is_valid(name):
+    return not True in [c in name for c in '~^: \\']
+
 def do_list(parser):
     global tags
     print "? refs/heads/%s" % 'master'
-    for tag, revid in parser.repo.tags.get_tag_dict().items():
+
+    branch = parser.repo
+    branch.lock_read()
+    for tag, revid in branch.tags.get_tag_dict().items():
+        try:
+            branch.revision_id_to_dotted_revno(revid)
+        except bzrlib.errors.NoSuchRevision:
+            continue
+        if not ref_is_valid(tag):
+            continue
         print "? refs/tags/%s" % tag
         tags[tag] = revid
+    branch.unlock()
     print "@refs/heads/%s HEAD" % 'master'
     print