diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -9,7 +9,7 @@
import os, mimetypes
from mercurial.node import hex, nullid
from mercurial.repo import RepoError
-from mercurial import mdiff, ui, hg, util, patch, hook
+from mercurial import ui, hg, util, patch, hook, match
from mercurial import revlog, templater, templatefilters
from common import get_mtime, style_map, paritygen, countgen, ErrorResponse
from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
@@ -277,27 +277,11 @@ class hgweb(object):
yield tmpl("fileellipses")
def diff(self, tmpl, node1, node2, files):
- def filterfiles(filters, files):
- l = [x for x in files if x in filters]
-
- for t in filters:
- if t and t[-1] != os.sep:
- t += os.sep
- l += [x for x in files if x.startswith(t)]
- return l
-
- parity = paritygen(self.stripecount)
- def diffblock(diff, f, fn):
- yield tmpl("diffblock",
- lines=prettyprintlines(diff),
- parity=parity.next(),
- file=f,
- filenode=hex(fn or nullid))
blockcount = countgen()
def prettyprintlines(diff):
blockno = blockcount.next()
- for lineno, l in enumerate(diff.splitlines(1)):
+ for lineno, l in enumerate(diff.splitlines(True)):
if blockno == 0:
lineno = lineno + 1
else:
@@ -315,33 +299,24 @@ class hgweb(object):
lineid="l%s" % lineno,
linenumber="% 8s" % lineno)
- r = self.repo
- c1 = r[node1]
- c2 = r[node2]
- date1 = util.datestr(c1.date())
- date2 = util.datestr(c2.date())
+ if files:
+ m = match.exact(self.repo.root, self.repo.getcwd(), files)
+ else:
+ m = match.always(self.repo.root, self.repo.getcwd())
- modified, added, removed, deleted, unknown = r.status(node1, node2)[:5]
- if files:
- modified, added, removed = map(lambda x: filterfiles(files, x),
- (modified, added, removed))
-
+ block = []
+ parity = paritygen(self.stripecount)
diffopts = patch.diffopts(self.repo.ui, untrusted=True)
- for f in modified:
- to = c1.filectx(f).data()
- tn = c2.filectx(f).data()
- yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f,
- opts=diffopts), f, tn)
- for f in added:
- to = None
- tn = c2.filectx(f).data()
- yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f,
- opts=diffopts), f, tn)
- for f in removed:
- to = c1.filectx(f).data()
- tn = None
- yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f,
- opts=diffopts), f, tn)
+ for chunk in patch.diff(self.repo, node1, node2, m, opts=diffopts):
+ if chunk.startswith('diff') and block:
+ yield tmpl('diffblock', parity=parity.next(),
+ lines=prettyprintlines(''.join(block)))
+ block = []
+ if chunk.startswith('diff'):
+ chunk = ''.join(chunk.splitlines(True)[1:])
+ block.append(chunk)
+ yield tmpl('diffblock', parity=parity.next(),
+ lines=prettyprintlines(''.join(block)))
archive_specs = {
'bz2': ('application/x-tar', 'tbz2', '.tar.bz2', None),
diff --git a/tests/test-hgweb-diffs b/tests/test-hgweb-diffs
new file mode 100755
--- /dev/null
+++ b/tests/test-hgweb-diffs
@@ -0,0 +1,34 @@
+echo % setting up repo
+hg init test
+cd test
+echo a > a
+echo b > b
+hg ci -Ama
+
+echo % change permissions for git diffs
+chmod 755 a
+hg ci -Amb
+
+echo % set up hgweb
+hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+cat hg.pid >> $DAEMON_PIDS
+
+echo % revision
+"$TESTDIR/get-with-headers.py" localhost:$HGPORT '/rev/0'
+
+echo % diff removed file
+"$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/tip/a'
+
+echo % set up hgweb with git diffs
+kill `cat hg.pid`
+hg serve --config 'diff.git=1' -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+cat hg.pid >> $DAEMON_PIDS
+
+echo % revision
+"$TESTDIR/get-with-headers.py" localhost:$HGPORT '/rev/0'
+
+echo % diff removed file
+"$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/tip/a'
+
+echo % errors
+cat errors.log
diff --git a/tests/test-hgweb-diffs.out b/tests/test-hgweb-diffs.out
new file mode 100644
--- /dev/null
+++ b/tests/test-hgweb-diffs.out
@@ -0,0 +1,272 @@
+% setting up repo
+adding a
+adding b
+% change permissions for git diffs
+% set up hgweb
+% revision
+200 Script output follows
+
+
+
+
+
+
+
+
+test: changeset 0cd96de13884
+
+
+
+
+
+changeset: a
+
+
+
+ changeset 0: |
+ 0cd96de13884 |
+
+
+child 1: | 78e4ebad7cdf |
+
+
+ author: |
+ test |
+
+
+ date: |
+ Thu Jan 01 00:00:00 1970 +0000 (38 years ago) |
+
+
+ files: |
+ a b |
+
+
+ description: |
+ a |
+
+
+
+
+
1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+ 2+++ b/a Thu Jan 01 00:00:00 1970 +0000
+ 3@@ -0,0 +1,1 @@
+ 4+a
+
1.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+ 1.2+++ b/b Thu Jan 01 00:00:00 1970 +0000
+ 1.3@@ -0,0 +1,1 @@
+ 1.4+b
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+% diff removed file
+200 Script output follows
+
+
+
+
+
+
+
+
+test: a diff
+
+
+
+
+
+a
+
+
+
+ revision 1: |
+ 78e4ebad7cdf |
+
+
+
+
+
+
+
1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+ 2+++ b/a Thu Jan 01 00:00:00 1970 +0000
+ 3@@ -0,0 +1,1 @@
+ 4+a
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+% set up hgweb with git diffs
+% revision
+200 Script output follows
+
+
+
+
+
+
+
+
+test: changeset 0cd96de13884
+
+
+
+
+
+changeset: a
+
+
+
+ changeset 0: |
+ 0cd96de13884 |
+
+
+child 1: | 78e4ebad7cdf |
+
+
+ author: |
+ test |
+
+
+ date: |
+ Thu Jan 01 00:00:00 1970 +0000 (38 years ago) |
+
+
+ files: |
+ a b |
+
+
+ description: |
+ a |
+
+
+
+
+
1new file mode 100644
+ 2--- /dev/null
+ 3+++ b/a
+ 4@@ -0,0 +1,1 @@
+ 5+a
+
1.1new file mode 100644
+ 1.2--- /dev/null
+ 1.3+++ b/b
+ 1.4@@ -0,0 +1,1 @@
+ 1.5+b
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+% diff removed file
+200 Script output follows
+
+
+
+
+
+
+
+
+test: a diff
+
+
+
+
+
+a
+
+
+
+ revision 1: |
+ 78e4ebad7cdf |
+
+
+
+
+
+
+
1new file mode 100755
+ 2--- /dev/null
+ 3+++ b/a
+ 4@@ -0,0 +1,1 @@
+ 5+a
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+% errors