/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to roundtrip.py

More work on roundtripping support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
"""Roundtripping support."""
18
 
 
 
17
"""Roundtripping support.
 
18
 
 
19
Bazaar stores more data than Git, which means that in order to preserve
 
20
a commit when it is pushed from Bazaar into Git we have to stash
 
21
that extra metadata somewhere.
 
22
 
 
23
There are two kinds of metadata relevant here:
 
24
 * per-file metadata (stored by revision+path)
 
25
  - usually stored per tree
 
26
 * per-revision metadata (stored by git commit id)
 
27
 
 
28
Bazaar revisions have the following information that is not
 
29
present in Git commits:
 
30
 * revision ids
 
31
 * revision properties
 
32
 * ghost parents
 
33
 
 
34
Tree content:
 
35
 * empty directories
 
36
 * path file ids
 
37
 * path last changed revisions [1]
 
38
 
 
39
 [1] path last changed revision information can usually
 
40
     be induced from the existing history, unless
 
41
     ghost revisions are involved.
 
42
 
 
43
This extra metadata is stored in so-called "supplements":
 
44
  * CommitSupplement
 
45
  * TreeSupplement
 
46
"""
 
47
 
 
48
from bzrlib import osutils
19
49
 
20
50
from cStringIO import StringIO
21
51
 
22
52
 
23
 
class BzrGitRevisionMetadata(object):
24
 
    """Metadata for a Bazaar revision roundtripped into Git.
 
53
class CommitSupplement(object):
 
54
    """Supplement for a Bazaar revision roundtripped into Git.
25
55
 
26
56
    :ivar revision_id: Revision id, as string
27
57
    :ivar properties: Revision properties, as dictionary
39
69
        self.properties = {}
40
70
 
41
71
    def __nonzero__(self):
42
 
        return bool(self.revision_id or self.properties)
 
72
        return bool(self.revision_id or self.properties or self.explicit_parent_ids)
 
73
 
 
74
 
 
75
class TreeSupplement(object):
 
76
    """Supplement for a Bazaar tree roundtripped into Git.
 
77
 
 
78
    This provides file ids (if they are different from the mapping default)
 
79
    and can provide text revisions.
 
80
    """
 
81
 
43
82
 
44
83
 
45
84
def parse_roundtripping_metadata(text):
46
85
    """Parse Bazaar roundtripping metadata."""
47
 
    ret = BzrGitRevisionMetadata()
 
86
    ret = CommitSupplement()
48
87
    f = StringIO(text)
49
88
    for l in f.readlines():
50
89
        (key, value) = l.split(":", 1)
55
94
        elif key == "testament3-sha1":
56
95
            ret.verifiers["testament3-sha1"] = value.strip()
57
96
        elif key.startswith("property-"):
58
 
            ret.properties[key[len("property-"):]] = value[1:].rstrip("\n")
 
97
            name = key[len("property-"):]
 
98
            if not name in ret.properties:
 
99
                ret.properties[name] = value[1:].rstrip("\n")
 
100
            else:
 
101
                ret.properties[name] += "\n" + value[1:].rstrip("\n")
59
102
        else:
60
103
            raise ValueError
61
104
    return ret
73
116
    if metadata.explicit_parent_ids:
74
117
        lines.append("parent-ids: %s\n" % " ".join(metadata.explicit_parent_ids))
75
118
    for key in sorted(metadata.properties.keys()):
76
 
        lines.append("property-%s: %s\n" % (key.encode(encoding), metadata.properties[key].encode(encoding)))
 
119
        for l in metadata.properties[key].split("\n"):
 
120
            lines.append("property-%s: %s\n" % (key.encode(encoding), osutils.safe_utf8(l)))
77
121
    if "testament3-sha1" in metadata.verifiers:
78
122
        lines.append("testament3-sha1: %s\n" %
79
123
                     metadata.verifiers["testament3-sha1"])
92
136
    return split[0], parse_roundtripping_metadata(split[1])
93
137
 
94
138
 
95
 
def inject_bzr_metadata(message, metadata, encoding):
96
 
    if not metadata:
 
139
def inject_bzr_metadata(message, commit_supplement, encoding):
 
140
    if not commit_supplement:
97
141
        return message
98
 
    rt_data = generate_roundtripping_metadata(metadata, encoding)
 
142
    rt_data = generate_roundtripping_metadata(commit_supplement, encoding)
99
143
    if not rt_data:
100
144
        return message
101
145
    assert type(rt_data) == str