Show More
@@ -511,14 +511,14 b' def reposetup(ui, repo):' | |||||
511 | self.lines = kwt.shrinklines(self.fname, self.lines) |
|
511 | self.lines = kwt.shrinklines(self.fname, self.lines) | |
512 |
|
512 | |||
513 | def kw_diff(orig, repo, node1=None, node2=None, match=None, changes=None, |
|
513 | def kw_diff(orig, repo, node1=None, node2=None, match=None, changes=None, | |
514 | opts=None): |
|
514 | opts=None, prefix=''): | |
515 | '''Monkeypatch patch.diff to avoid expansion except when |
|
515 | '''Monkeypatch patch.diff to avoid expansion except when | |
516 | comparing against working dir.''' |
|
516 | comparing against working dir.''' | |
517 | if node2 is not None: |
|
517 | if node2 is not None: | |
518 | kwt.match = util.never |
|
518 | kwt.match = util.never | |
519 | elif node1 is not None and node1 != repo['.'].node(): |
|
519 | elif node1 is not None and node1 != repo['.'].node(): | |
520 | kwt.restrict = True |
|
520 | kwt.restrict = True | |
521 | return orig(repo, node1, node2, match, changes, opts) |
|
521 | return orig(repo, node1, node2, match, changes, opts, prefix) | |
522 |
|
522 | |||
523 | def kwweb_skip(orig, web, req, tmpl): |
|
523 | def kwweb_skip(orig, web, req, tmpl): | |
524 | '''Wraps webcommands.x turning off keyword expansion.''' |
|
524 | '''Wraps webcommands.x turning off keyword expansion.''' |
@@ -5,7 +5,7 b'' | |||||
5 | # This software may be used and distributed according to the terms of the |
|
5 | # This software may be used and distributed according to the terms of the | |
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | from node import hex, nullid, nullrev, short |
|
8 | from node import hex, bin, nullid, nullrev, short | |
9 | from i18n import _ |
|
9 | from i18n import _ | |
10 | import os, sys, errno, re, glob, tempfile |
|
10 | import os, sys, errno, re, glob, tempfile | |
11 | import util, templater, patch, error, encoding, templatekw |
|
11 | import util, templater, patch, error, encoding, templatekw | |
@@ -655,7 +655,8 b" def export(repo, revs, template='hg-%h.p" | |||||
655 | single(rev, seqno + 1, fp) |
|
655 | single(rev, seqno + 1, fp) | |
656 |
|
656 | |||
657 | def diffordiffstat(ui, repo, diffopts, node1, node2, match, |
|
657 | def diffordiffstat(ui, repo, diffopts, node1, node2, match, | |
658 |
changes=None, stat=False, fp=None |
|
658 | changes=None, stat=False, fp=None, prefix='', | |
|
659 | listsubrepos=False): | |||
659 | '''show diff or diffstat.''' |
|
660 | '''show diff or diffstat.''' | |
660 | if fp is None: |
|
661 | if fp is None: | |
661 | write = ui.write |
|
662 | write = ui.write | |
@@ -668,16 +669,27 b' def diffordiffstat(ui, repo, diffopts, n' | |||||
668 | width = 80 |
|
669 | width = 80 | |
669 | if not ui.plain(): |
|
670 | if not ui.plain(): | |
670 | width = util.termwidth() |
|
671 | width = util.termwidth() | |
671 |
chunks = patch.diff(repo, node1, node2, match, changes, diffopts |
|
672 | chunks = patch.diff(repo, node1, node2, match, changes, diffopts, | |
|
673 | prefix=prefix) | |||
672 | for chunk, label in patch.diffstatui(util.iterlines(chunks), |
|
674 | for chunk, label in patch.diffstatui(util.iterlines(chunks), | |
673 | width=width, |
|
675 | width=width, | |
674 | git=diffopts.git): |
|
676 | git=diffopts.git): | |
675 | write(chunk, label=label) |
|
677 | write(chunk, label=label) | |
676 | else: |
|
678 | else: | |
677 | for chunk, label in patch.diffui(repo, node1, node2, match, |
|
679 | for chunk, label in patch.diffui(repo, node1, node2, match, | |
678 | changes, diffopts): |
|
680 | changes, diffopts, prefix=prefix): | |
679 | write(chunk, label=label) |
|
681 | write(chunk, label=label) | |
680 |
|
682 | |||
|
683 | if listsubrepos: | |||
|
684 | ctx1 = repo[node1] | |||
|
685 | for subpath in ctx1.substate: | |||
|
686 | sub = ctx1.sub(subpath) | |||
|
687 | if node2 is not None: | |||
|
688 | node2 = bin(repo[node2].substate[subpath][1]) | |||
|
689 | submatch = matchmod.narrowmatcher(subpath, match) | |||
|
690 | sub.diff(diffopts, node2, submatch, changes=changes, | |||
|
691 | stat=stat, fp=fp, prefix=prefix) | |||
|
692 | ||||
681 | class changeset_printer(object): |
|
693 | class changeset_printer(object): | |
682 | '''show changeset information when templating not requested.''' |
|
694 | '''show changeset information when templating not requested.''' | |
683 |
|
695 |
@@ -1471,7 +1471,8 b' def diff(ui, repo, *pats, **opts):' | |||||
1471 |
|
1471 | |||
1472 | diffopts = patch.diffopts(ui, opts) |
|
1472 | diffopts = patch.diffopts(ui, opts) | |
1473 | m = cmdutil.match(repo, pats, opts) |
|
1473 | m = cmdutil.match(repo, pats, opts) | |
1474 |
cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat |
|
1474 | cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat, | |
|
1475 | listsubrepos=opts.get('subrepos')) | |||
1475 |
|
1476 | |||
1476 | def export(ui, repo, *changesets, **opts): |
|
1477 | def export(ui, repo, *changesets, **opts): | |
1477 | """dump the header and diffs for one or more changesets |
|
1478 | """dump the header and diffs for one or more changesets | |
@@ -4183,7 +4184,7 b' table = {' | |||||
4183 | _('revision'), _('REV')), |
|
4184 | _('revision'), _('REV')), | |
4184 | ('c', 'change', '', |
|
4185 | ('c', 'change', '', | |
4185 | _('change made by revision'), _('REV')) |
|
4186 | _('change made by revision'), _('REV')) | |
4186 | ] + diffopts + diffopts2 + walkopts, |
|
4187 | ] + diffopts + diffopts2 + walkopts + subrepoopts, | |
4187 | _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')), |
|
4188 | _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')), | |
4188 | "^export": |
|
4189 | "^export": | |
4189 | (export, |
|
4190 | (export, |
@@ -1404,7 +1404,7 b' def diffopts(ui, opts=None, untrusted=Fa' | |||||
1404 | context=get('unified', getter=ui.config)) |
|
1404 | context=get('unified', getter=ui.config)) | |
1405 |
|
1405 | |||
1406 | def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None, |
|
1406 | def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None, | |
1407 | losedatafn=None): |
|
1407 | losedatafn=None, prefix=''): | |
1408 | '''yields diff of changes to files between two nodes, or node and |
|
1408 | '''yields diff of changes to files between two nodes, or node and | |
1409 | working directory. |
|
1409 | working directory. | |
1410 |
|
1410 | |||
@@ -1418,6 +1418,9 b' def diff(repo, node1=None, node2=None, m' | |||||
1418 | called with the name of current file being diffed as 'fn'. If set |
|
1418 | called with the name of current file being diffed as 'fn'. If set | |
1419 | to None, patches will always be upgraded to git format when |
|
1419 | to None, patches will always be upgraded to git format when | |
1420 | necessary. |
|
1420 | necessary. | |
|
1421 | ||||
|
1422 | prefix is a filename prefix that is prepended to all filenames on | |||
|
1423 | display (used for subrepos). | |||
1421 | ''' |
|
1424 | ''' | |
1422 |
|
1425 | |||
1423 | if opts is None: |
|
1426 | if opts is None: | |
@@ -1462,7 +1465,7 b' def diff(repo, node1=None, node2=None, m' | |||||
1462 | copy = copies.copies(repo, ctx1, ctx2, repo[nullid])[0] |
|
1465 | copy = copies.copies(repo, ctx1, ctx2, repo[nullid])[0] | |
1463 |
|
1466 | |||
1464 | difffn = lambda opts, losedata: trydiff(repo, revs, ctx1, ctx2, |
|
1467 | difffn = lambda opts, losedata: trydiff(repo, revs, ctx1, ctx2, | |
1465 | modified, added, removed, copy, getfilectx, opts, losedata) |
|
1468 | modified, added, removed, copy, getfilectx, opts, losedata, prefix) | |
1466 | if opts.upgrade and not opts.git: |
|
1469 | if opts.upgrade and not opts.git: | |
1467 | try: |
|
1470 | try: | |
1468 | def losedata(fn): |
|
1471 | def losedata(fn): | |
@@ -1518,7 +1521,10 b' def _addmodehdr(header, omode, nmode):' | |||||
1518 | header.append('new mode %s\n' % nmode) |
|
1521 | header.append('new mode %s\n' % nmode) | |
1519 |
|
1522 | |||
1520 | def trydiff(repo, revs, ctx1, ctx2, modified, added, removed, |
|
1523 | def trydiff(repo, revs, ctx1, ctx2, modified, added, removed, | |
1521 | copy, getfilectx, opts, losedatafn): |
|
1524 | copy, getfilectx, opts, losedatafn, prefix): | |
|
1525 | ||||
|
1526 | def join(f): | |||
|
1527 | return os.path.join(prefix, f) | |||
1522 |
|
1528 | |||
1523 | date1 = util.datestr(ctx1.date()) |
|
1529 | date1 = util.datestr(ctx1.date()) | |
1524 | man1 = ctx1.manifest() |
|
1530 | man1 = ctx1.manifest() | |
@@ -1557,8 +1563,8 b' def trydiff(repo, revs, ctx1, ctx2, modi' | |||||
1557 | gone.add(a) |
|
1563 | gone.add(a) | |
1558 | else: |
|
1564 | else: | |
1559 | op = 'copy' |
|
1565 | op = 'copy' | |
1560 | header.append('%s from %s\n' % (op, a)) |
|
1566 | header.append('%s from %s\n' % (op, join(a))) | |
1561 | header.append('%s to %s\n' % (op, f)) |
|
1567 | header.append('%s to %s\n' % (op, join(f))) | |
1562 | to = getfilectx(a, ctx1).data() |
|
1568 | to = getfilectx(a, ctx1).data() | |
1563 | else: |
|
1569 | else: | |
1564 | losedatafn(f) |
|
1570 | losedatafn(f) | |
@@ -1600,7 +1606,7 b' def trydiff(repo, revs, ctx1, ctx2, modi' | |||||
1600 | elif binary or nflag != oflag: |
|
1606 | elif binary or nflag != oflag: | |
1601 | losedatafn(f) |
|
1607 | losedatafn(f) | |
1602 | if opts.git: |
|
1608 | if opts.git: | |
1603 | header.insert(0, mdiff.diffline(revs, a, b, opts)) |
|
1609 | header.insert(0, mdiff.diffline(revs, join(a), join(b), opts)) | |
1604 |
|
1610 | |||
1605 | if dodiff: |
|
1611 | if dodiff: | |
1606 | if dodiff == 'binary': |
|
1612 | if dodiff == 'binary': | |
@@ -1609,7 +1615,7 b' def trydiff(repo, revs, ctx1, ctx2, modi' | |||||
1609 | text = mdiff.unidiff(to, date1, |
|
1615 | text = mdiff.unidiff(to, date1, | |
1610 | # ctx2 date may be dynamic |
|
1616 | # ctx2 date may be dynamic | |
1611 | tn, util.datestr(ctx2.date()), |
|
1617 | tn, util.datestr(ctx2.date()), | |
1612 | a, b, revs, opts=opts) |
|
1618 | join(a), join(b), revs, opts=opts) | |
1613 | if header and (text or len(header) > 1): |
|
1619 | if header and (text or len(header) > 1): | |
1614 | yield ''.join(header) |
|
1620 | yield ''.join(header) | |
1615 | if text: |
|
1621 | if text: |
@@ -7,7 +7,7 b'' | |||||
7 |
|
7 | |||
8 | import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath |
|
8 | import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath | |
9 | from i18n import _ |
|
9 | from i18n import _ | |
10 | import config, util, node, error |
|
10 | import config, util, node, error, cmdutil | |
11 | hg = None |
|
11 | hg = None | |
12 |
|
12 | |||
13 | nullstate = ('', '', 'empty') |
|
13 | nullstate = ('', '', 'empty') | |
@@ -249,6 +249,9 b' class abstractsubrepo(object):' | |||||
249 | def status(self, rev2, **opts): |
|
249 | def status(self, rev2, **opts): | |
250 | return [], [], [], [], [], [], [] |
|
250 | return [], [], [], [], [], [], [] | |
251 |
|
251 | |||
|
252 | def diff(self, diffopts, node2, match, prefix, **opts): | |||
|
253 | pass | |||
|
254 | ||||
252 | class hgsubrepo(abstractsubrepo): |
|
255 | class hgsubrepo(abstractsubrepo): | |
253 | def __init__(self, ctx, path, state): |
|
256 | def __init__(self, ctx, path, state): | |
254 | self._path = path |
|
257 | self._path = path | |
@@ -289,6 +292,17 b' class hgsubrepo(abstractsubrepo):' | |||||
289 | % (inst, relpath(self))) |
|
292 | % (inst, relpath(self))) | |
290 | return [], [], [], [], [], [], [] |
|
293 | return [], [], [], [], [], [], [] | |
291 |
|
294 | |||
|
295 | def diff(self, diffopts, node2, match, prefix, **opts): | |||
|
296 | try: | |||
|
297 | node1 = node.bin(self._state[1]) | |||
|
298 | cmdutil.diffordiffstat(self._repo.ui, self._repo, diffopts, | |||
|
299 | node1, node2, match, | |||
|
300 | prefix=os.path.join(prefix, self._path), | |||
|
301 | listsubrepos=True, **opts) | |||
|
302 | except error.RepoLookupError, inst: | |||
|
303 | self._repo.ui.warn(_("warning: %s in %s\n") | |||
|
304 | % (inst, relpath(self))) | |||
|
305 | ||||
292 | def dirty(self): |
|
306 | def dirty(self): | |
293 | r = self._state[1] |
|
307 | r = self._state[1] | |
294 | if r == '': |
|
308 | if r == '': |
@@ -180,7 +180,7 b' Show all commands + options' | |||||
180 | annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude |
|
180 | annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude | |
181 | clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd |
|
181 | clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd | |
182 | commit: addremove, close-branch, include, exclude, message, logfile, date, user |
|
182 | commit: addremove, close-branch, include, exclude, message, logfile, date, user | |
183 | diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude |
|
183 | diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos | |
184 | export: output, switch-parent, rev, text, git, nodates |
|
184 | export: output, switch-parent, rev, text, git, nodates | |
185 | forget: include, exclude |
|
185 | forget: include, exclude | |
186 | init: ssh, remotecmd |
|
186 | init: ssh, remotecmd |
@@ -471,6 +471,7 b' Test command without options' | |||||
471 | --stat output diffstat-style summary of changes |
|
471 | --stat output diffstat-style summary of changes | |
472 | -I --include PATTERN [+] include names matching the given patterns |
|
472 | -I --include PATTERN [+] include names matching the given patterns | |
473 | -X --exclude PATTERN [+] exclude names matching the given patterns |
|
473 | -X --exclude PATTERN [+] exclude names matching the given patterns | |
|
474 | -S --subrepos recurse into subrepositories | |||
474 |
|
475 | |||
475 | [+] marked option can be specified multiple times |
|
476 | [+] marked option can be specified multiple times | |
476 |
|
477 |
@@ -2,6 +2,7 b' Make status look into subrepositories by' | |||||
2 |
|
2 | |||
3 | $ echo '[defaults]' >> $HGRCPATH |
|
3 | $ echo '[defaults]' >> $HGRCPATH | |
4 | $ echo 'status = -S' >> $HGRCPATH |
|
4 | $ echo 'status = -S' >> $HGRCPATH | |
|
5 | $ echo 'diff = --nodates -S' >> $HGRCPATH | |||
5 |
|
6 | |||
6 | Create test repository: |
|
7 | Create test repository: | |
7 |
|
8 | |||
@@ -54,6 +55,21 b' Change working directory:' | |||||
54 | $ hg status |
|
55 | $ hg status | |
55 | M foo/bar/z.txt |
|
56 | M foo/bar/z.txt | |
56 | M foo/y.txt |
|
57 | M foo/y.txt | |
|
58 | $ hg diff | |||
|
59 | diff -r d254738c5f5e foo/y.txt | |||
|
60 | --- a/foo/y.txt | |||
|
61 | +++ b/foo/y.txt | |||
|
62 | @@ -1,2 +1,3 @@ | |||
|
63 | y1 | |||
|
64 | y2 | |||
|
65 | +y3 | |||
|
66 | diff -r 9647f22de499 foo/bar/z.txt | |||
|
67 | --- a/foo/bar/z.txt | |||
|
68 | +++ b/foo/bar/z.txt | |||
|
69 | @@ -1,2 +1,3 @@ | |||
|
70 | z1 | |||
|
71 | z2 | |||
|
72 | +z3 | |||
57 |
|
73 | |||
58 | Status call crossing repository boundaries: |
|
74 | Status call crossing repository boundaries: | |
59 |
|
75 | |||
@@ -64,6 +80,21 b' Status call crossing repository boundari' | |||||
64 | $ hg status -I '**/?.txt' |
|
80 | $ hg status -I '**/?.txt' | |
65 | M foo/bar/z.txt |
|
81 | M foo/bar/z.txt | |
66 | M foo/y.txt |
|
82 | M foo/y.txt | |
|
83 | $ hg diff -I '**/?.txt' | |||
|
84 | diff -r d254738c5f5e foo/y.txt | |||
|
85 | --- a/foo/y.txt | |||
|
86 | +++ b/foo/y.txt | |||
|
87 | @@ -1,2 +1,3 @@ | |||
|
88 | y1 | |||
|
89 | y2 | |||
|
90 | +y3 | |||
|
91 | diff -r 9647f22de499 foo/bar/z.txt | |||
|
92 | --- a/foo/bar/z.txt | |||
|
93 | +++ b/foo/bar/z.txt | |||
|
94 | @@ -1,2 +1,3 @@ | |||
|
95 | z1 | |||
|
96 | z2 | |||
|
97 | +z3 | |||
67 |
|
98 | |||
68 | Status from within a subdirectory: |
|
99 | Status from within a subdirectory: | |
69 |
|
100 | |||
@@ -74,6 +105,21 b' Status from within a subdirectory:' | |||||
74 | M foo/bar/z.txt |
|
105 | M foo/bar/z.txt | |
75 | M foo/y.txt |
|
106 | M foo/y.txt | |
76 | ? dir/a.txt |
|
107 | ? dir/a.txt | |
|
108 | $ hg diff | |||
|
109 | diff -r d254738c5f5e foo/y.txt | |||
|
110 | --- a/foo/y.txt | |||
|
111 | +++ b/foo/y.txt | |||
|
112 | @@ -1,2 +1,3 @@ | |||
|
113 | y1 | |||
|
114 | y2 | |||
|
115 | +y3 | |||
|
116 | diff -r 9647f22de499 foo/bar/z.txt | |||
|
117 | --- a/foo/bar/z.txt | |||
|
118 | +++ b/foo/bar/z.txt | |||
|
119 | @@ -1,2 +1,3 @@ | |||
|
120 | z1 | |||
|
121 | z2 | |||
|
122 | +z3 | |||
77 |
|
123 | |||
78 | Status with relative path: |
|
124 | Status with relative path: | |
79 |
|
125 | |||
@@ -81,17 +127,66 b' Status with relative path:' | |||||
81 | M ../foo/bar/z.txt |
|
127 | M ../foo/bar/z.txt | |
82 | M ../foo/y.txt |
|
128 | M ../foo/y.txt | |
83 | ? a.txt |
|
129 | ? a.txt | |
|
130 | $ hg diff .. | |||
|
131 | diff -r d254738c5f5e foo/y.txt | |||
|
132 | --- a/foo/y.txt | |||
|
133 | +++ b/foo/y.txt | |||
|
134 | @@ -1,2 +1,3 @@ | |||
|
135 | y1 | |||
|
136 | y2 | |||
|
137 | +y3 | |||
|
138 | diff -r 9647f22de499 foo/bar/z.txt | |||
|
139 | --- a/foo/bar/z.txt | |||
|
140 | +++ b/foo/bar/z.txt | |||
|
141 | @@ -1,2 +1,3 @@ | |||
|
142 | z1 | |||
|
143 | z2 | |||
|
144 | +z3 | |||
84 | $ cd .. |
|
145 | $ cd .. | |
85 |
|
146 | |||
|
147 | Cleanup and final commit: | |||
|
148 | ||||
|
149 | $ rm -r dir | |||
|
150 | $ hg commit -m 2-3-2 | |||
|
151 | committing subrepository foo | |||
|
152 | committing subrepository foo/bar | |||
|
153 | ||||
|
154 | Log with the relationships between repo and its subrepo: | |||
|
155 | ||||
|
156 | $ hg log --template '{rev}:{node|short} {desc}\n' | |||
|
157 | 2:1326fa26d0c0 2-3-2 | |||
|
158 | 1:4b3c9ff4f66b 1-2-1 | |||
|
159 | 0:23376cbba0d8 0-0-0 | |||
|
160 | ||||
|
161 | $ hg -R foo log --template '{rev}:{node|short} {desc}\n' | |||
|
162 | 3:65903cebad86 2-3-2 | |||
|
163 | 2:d254738c5f5e 0-2-1 | |||
|
164 | 1:8629ce7dcc39 0-1-0 | |||
|
165 | 0:af048e97ade2 0-0-0 | |||
|
166 | ||||
|
167 | $ hg -R foo/bar log --template '{rev}:{node|short} {desc}\n' | |||
|
168 | 2:31ecbdafd357 2-3-2 | |||
|
169 | 1:9647f22de499 0-1-1 | |||
|
170 | 0:4904098473f9 0-0-0 | |||
|
171 | ||||
86 | Status between revisions: |
|
172 | Status between revisions: | |
87 |
|
173 | |||
88 | $ rm -r dir |
|
|||
89 | $ hg commit -m 2-2-1 |
|
|||
90 | committing subrepository foo |
|
|||
91 | committing subrepository foo/bar |
|
|||
92 | $ hg status |
|
174 | $ hg status | |
93 | $ hg status --rev 0:1 |
|
175 | $ hg status --rev 0:1 | |
94 | M .hgsubstate |
|
176 | M .hgsubstate | |
95 | M foo/.hgsubstate |
|
177 | M foo/.hgsubstate | |
96 | M foo/bar/z.txt |
|
178 | M foo/bar/z.txt | |
97 | M foo/y.txt |
|
179 | M foo/y.txt | |
|
180 | $ hg diff -I '**/?.txt' --rev 0:1 | |||
|
181 | diff -r af048e97ade2 -r d254738c5f5e foo/y.txt | |||
|
182 | --- a/foo/y.txt | |||
|
183 | +++ b/foo/y.txt | |||
|
184 | @@ -1,1 +1,2 @@ | |||
|
185 | y1 | |||
|
186 | +y2 | |||
|
187 | diff -r 4904098473f9 -r 9647f22de499 foo/bar/z.txt | |||
|
188 | --- a/foo/bar/z.txt | |||
|
189 | +++ b/foo/bar/z.txt | |||
|
190 | @@ -1,1 +1,2 @@ | |||
|
191 | z1 | |||
|
192 | +z2 |
General Comments 0
You need to be logged in to leave comments.
Login now