# # # patch "monotone.py" # from [36343c9a6b03e403f7d39b3a305f0cad05a3fa43] # to [1f327cc8dba8cdc21ad01c2af0af1056f871390a] # # patch "revision.psp" # from [8302014474085a560142b4d1168d8c3324758efc] # to [3c04c7c1f4cd68543609eeeae29fb65a3a60294c] # # patch "wrapper.py" # from [7da9c82850b0b6a65f6c4f071e4289a48a34c2f8] # to [7ab61cfe51cc96ba24361b11936639131efe42de] # ============================================================ --- monotone.py 36343c9a6b03e403f7d39b3a305f0cad05a3fa43 +++ monotone.py 1f327cc8dba8cdc21ad01c2af0af1056f871390a @@ -102,6 +102,14 @@ raise Exception("Unable to retrieve file: %s" % (result['childerr'])) else: return result['fromchild'] + def diff(self, rev_from, rev_to, files=None): + command = self.base_command + " diff -r %s -r %s" % (pipes.quote(rev_from), pipes.quote(rev_to)) + if files != None: command += ' ' + ' '.join(map(pipes.quote, files)) + result = utility.run_command(command) + if result['exitcode'] != 0: + raise Exception("Unable to calculate diff: %s" % (result['childerr'])) + else: + return result['fromchild'] def ancestry(self, id, limit=0): rv = [] entry = None ============================================================ --- revision.psp 8302014474085a560142b4d1168d8c3324758efc +++ revision.psp 3c04c7c1f4cd68543609eeeae29fb65a3a60294c @@ -69,6 +69,7 @@ <% revision = mt.revision(id) +old_revision = None for key in revision.keys(): value = "" for stanza in revision[key]: @@ -78,10 +79,10 @@ if not from_id: value += 'Add file %s with revision %s
' % (hq(fname), urllib.quote(to_id), hq(to_id)) else: - value += 'Patch file %s from %s to %s (diff)
' % (hq(fname), urllib.quote(from_id), hq(from_id), urllib.quote(to_id), hq(to_id), urllib.quote(from_id), urllib.quote(to_id)) + value += 'Patch file %s from %s to %s (diff)
' % (hq(fname), urllib.quote(from_id), hq(from_id), urllib.quote(to_id), hq(to_id), urllib.quote(old_revision), urllib.quote(id), urllib.quote(fname)) elif type == "old_revision": old_revision, old_manifest = stanza[0][1], stanza[1][1] - value += 'Old revision is: %s
Old manifest: %s
' % (urllib.quote(old_revision), hq(old_revision), hq(old_manifest)) + value += 'Old revision is: %s (diff)
Old manifest: %s
' % (urllib.quote(old_revision), hq(old_revision), urllib.quote(old_revision), urllib.quote(id), hq(old_manifest)) elif type == "new_manifest": new_manifest = stanza[0][1] value += 'New manifest is: %s
' % (hq(old_manifest)) ============================================================ --- wrapper.py 7da9c82850b0b6a65f6c4f071e4289a48a34c2f8 +++ wrapper.py 7ab61cfe51cc96ba24361b11936639131efe42de @@ -17,10 +17,26 @@ if not form.has_key('id'): return apache.HTTP_BAD_REQUEST id = form['id'] + if not monotone.is_valid_id(id): + return apache.HTTP_BAD_REQUEST req.content_type = "text/plain" req.write(mt.file(id)) return apache.OK +def get_diff(req): + mt = Monotone(config.monotone, config.dbfile) + form = util.FieldStorage(req) + if not form.has_key('id1') or not form.has_key('id2'): + return apache.HTTP_BAD_REQUEST + if form.has_key('fname'): files = [form['fname']] + else: files = None + id1, id2 = form['id1'], form['id2'] + if not monotone.is_valid_id(id1) or not monotone.is_valid_id(id2): + return apache.HTTP_BAD_REQUEST + req.content_type = "text/plain" + req.write(mt.diff(id1, id2, files)) + return apache.OK + def get_tar(req): "make a tar file out of a given manifest ID" class DummyFile: @@ -61,6 +77,7 @@ handlers = { 'getfile.py' : get_file, + 'getdiff.py' : get_diff, 'gettar.py' : get_tar }