14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
from cStringIO import StringIO
20
from io import BytesIO
22
from breezy.diff import show_diff_trees
23
from breezy.revision import NULL_REVISION
24
from paste.request import parse_querystring, path_info_pop
26
from ..controllers import TemplatedBranchView
23
from paste.request import path_info_pop
25
from bzrlib.diff import show_diff_trees
27
from loggerhead.controllers import TemplatedBranchView
29
log = logging.getLogger("loggerhead.controllers")
29
32
class DiffUI(TemplatedBranchView):
30
33
"""Class to output a diff for a single file or revisions."""
32
35
def __call__(self, environ, start_response):
33
# End of URL is now /diff/<rev_id>?context=<context_lines>
34
# or /diff/<rev_id>/<rev_id>?context=<context_lines>
35
# This allows users to choose how much context they want to see.
36
# Old format was /diff/<rev_id>/<rev_id> or /diff/<rev_id>
36
# /diff/<rev_id>/<rev_id>
37
37
"""Default method called from /diff URL."""
47
numlines = 3 # This is the default.
49
opts = parse_querystring(environ)
51
if opt[0] == 'context':
53
numlines = int(opt[1])
57
47
revid_from = args[0]
58
# Convert a revno to a revid if we get a revno.
48
# Convert a revno to a revid if we get a revno
59
49
revid_from = self._history.fix_revid(revid_from)
60
50
change = self._history.get_changes([revid_from])[0]
63
53
revid_to = self._history.fix_revid(args[1])
64
elif len(change.parents) == 0:
65
revid_to = NULL_REVISION
67
55
revid_to = change.parents[0].revid
70
58
revtree1 = repo.revision_tree(revid_to)
71
59
revtree2 = repo.revision_tree(revid_from)
73
diff_content_stream = BytesIO()
61
diff_content_stream = StringIO()
74
62
show_diff_trees(revtree1, revtree2, diff_content_stream,
75
old_label='', new_label='', context=numlines)
63
old_label='', new_label='')
77
65
content = diff_content_stream.getvalue()
79
self.log.info('/diff %r:%r in %r secs with %r context' % (revid_from, revid_to,
80
time.time() - z, numlines))
67
self.log.info('/diff %r:%r in %r secs' % (revid_from, revid_to,
82
70
revno1 = self._history.get_revno(revid_from)
83
71
revno2 = self._history.get_revno(revid_to)
84
72
filename = '%s_%s.diff' % (revno1, revno2)
86
74
('Content-Type', 'application/octet-stream'),
87
('Content-Length', str(len(content))),
75
('Content-Length', len(content)),
88
76
('Content-Disposition', 'attachment; filename=%s' % (filename,)),
90
78
start_response('200 OK', headers)