Clean up file headers.
[jelmer/dulwich-libgit2.git] / dulwich / fastexport.py
1 # __init__.py -- Fast export/import functionality
2 # Copyright (C) 2010 Jelmer Vernooij <jelmer@samba.org>
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; version 2
7 # of the License or (at your option) any later version of
8 # the License.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # MA  02110-1301, USA.
19
20
21 """Fast export/import functionality."""
22
23 from dulwich.objects import (
24     Tree,
25     format_timezone,
26     )
27
28 import stat
29
30 class FastExporter(object):
31     """Generate a fast-export output stream for Git objects."""
32
33     def __init__(self, outf, store):
34         self.outf = outf
35         self.store = store
36         self.markers = {}
37         self._marker_idx = 0
38
39     def _allocate_marker(self):
40         self._marker_idx+=1
41         return self._marker_idx
42
43     def _dump_blob(self, blob, marker):
44         self.outf.write("blob\nmark :%s\n" % marker)
45         self.outf.write("data %s\n" % blob.raw_length())
46         for chunk in blob.as_raw_chunks():
47             self.outf.write(chunk)
48         self.outf.write("\n")
49
50     def export_blob(self, blob):
51         i = self._allocate_marker()
52         self.markers[i] = blob.id
53         self._dump_blob(blob, i)
54         return i
55
56     def _dump_commit(self, commit, marker, ref, file_changes):
57         self.outf.write("commit %s\n" % ref)
58         self.outf.write("mark :%s\n" % marker)
59         self.outf.write("author %s %s %s\n" % (commit.author,
60             commit.author_time, format_timezone(commit.author_timezone)))
61         self.outf.write("committer %s %s %s\n" % (commit.committer,
62             commit.commit_time, format_timezone(commit.commit_timezone)))
63         self.outf.write("data %s\n" % len(commit.message))
64         self.outf.write(commit.message)
65         self.outf.write("\n")
66         self.outf.write('\n'.join(file_changes))
67         self.outf.write("\n\n")
68
69     def export_commit(self, commit, ref, base_tree=None):
70         file_changes = []
71         for (old_path, new_path), (old_mode, new_mode), (old_hexsha, new_hexsha) in \
72                 self.store.tree_changes(base_tree, commit.tree):
73             if new_path is None:
74                 file_changes.append("D %s" % old_path)
75                 continue
76             if not stat.S_ISDIR(new_mode):
77                 marker = self.export_blob(self.store[new_hexsha])
78             file_changes.append("M %o :%s %s" % (new_mode, marker, new_path))
79
80         i = self._allocate_marker()
81         self._dump_commit(commit, i, ref, file_changes)
82         return i