Show More
@@ -225,7 +225,6 b' class queue(object):' | |||||
225 | self.guards_path = "guards" |
|
225 | self.guards_path = "guards" | |
226 | self.active_guards = None |
|
226 | self.active_guards = None | |
227 | self.guards_dirty = False |
|
227 | self.guards_dirty = False | |
228 | self._diffopts = None |
|
|||
229 |
|
228 | |||
230 | @util.propertycache |
|
229 | @util.propertycache | |
231 | def applied(self): |
|
230 | def applied(self): | |
@@ -259,10 +258,26 b' class queue(object):' | |||||
259 | self.guards_dirty = False |
|
258 | self.guards_dirty = False | |
260 | self.active_guards = None |
|
259 | self.active_guards = None | |
261 |
|
260 | |||
262 | def diffopts(self): |
|
261 | def diffopts(self, opts={}, patchfn=None): | |
263 | if self._diffopts is None: |
|
262 | diffopts = patch.diffopts(self.ui, opts) | |
264 | self._diffopts = patch.diffopts(self.ui) |
|
263 | if patchfn: | |
265 | return self._diffopts |
|
264 | diffopts = self.patchopts(diffopts, patchfn) | |
|
265 | return diffopts | |||
|
266 | ||||
|
267 | def patchopts(self, diffopts, *patches): | |||
|
268 | """Return a copy of input diff options with git set to true if | |||
|
269 | referenced patch is a git patch. | |||
|
270 | """ | |||
|
271 | diffopts = diffopts.copy() | |||
|
272 | for patchfn in patches: | |||
|
273 | patchf = self.opener(patchfn, 'r') | |||
|
274 | # if the patch was a git patch, refresh it as a git patch | |||
|
275 | for line in patchf: | |||
|
276 | if line.startswith('diff --git'): | |||
|
277 | diffopts.git = True | |||
|
278 | break | |||
|
279 | patchf.close() | |||
|
280 | return diffopts | |||
266 |
|
281 | |||
267 | def join(self, *p): |
|
282 | def join(self, *p): | |
268 | return os.path.join(self.path, *p) |
|
283 | return os.path.join(self.path, *p) | |
@@ -418,24 +433,24 b' class queue(object):' | |||||
418 | except OSError, inst: |
|
433 | except OSError, inst: | |
419 | self.ui.warn(_('error removing undo: %s\n') % str(inst)) |
|
434 | self.ui.warn(_('error removing undo: %s\n') % str(inst)) | |
420 |
|
435 | |||
421 | def printdiff(self, repo, node1, node2=None, files=None, |
|
436 | def printdiff(self, repo, diffopts, node1, node2=None, files=None, | |
422 | fp=None, changes=None, opts={}): |
|
437 | fp=None, changes=None, opts={}): | |
423 | stat = opts.get('stat') |
|
438 | stat = opts.get('stat') | |
424 | if stat: |
|
439 | if stat: | |
425 | opts['unified'] = '0' |
|
440 | opts['unified'] = '0' | |
426 |
|
441 | |||
427 | m = cmdutil.match(repo, files, opts) |
|
442 | m = cmdutil.match(repo, files, opts) | |
428 |
chunks = patch.diff(repo, node1, node2, m, changes, |
|
443 | chunks = patch.diff(repo, node1, node2, m, changes, diffopts) | |
429 | write = fp is None and repo.ui.write or fp.write |
|
444 | write = fp is None and repo.ui.write or fp.write | |
430 | if stat: |
|
445 | if stat: | |
431 | width = self.ui.interactive() and util.termwidth() or 80 |
|
446 | width = self.ui.interactive() and util.termwidth() or 80 | |
432 | write(patch.diffstat(util.iterlines(chunks), width=width, |
|
447 | write(patch.diffstat(util.iterlines(chunks), width=width, | |
433 |
git= |
|
448 | git=diffopts.git)) | |
434 | else: |
|
449 | else: | |
435 | for chunk in chunks: |
|
450 | for chunk in chunks: | |
436 | write(chunk) |
|
451 | write(chunk) | |
437 |
|
452 | |||
438 | def mergeone(self, repo, mergeq, head, patch, rev): |
|
453 | def mergeone(self, repo, mergeq, head, patch, rev, diffopts): | |
439 | # first try just applying the patch |
|
454 | # first try just applying the patch | |
440 | (err, n) = self.apply(repo, [ patch ], update_status=False, |
|
455 | (err, n) = self.apply(repo, [ patch ], update_status=False, | |
441 | strict=True, merge=rev) |
|
456 | strict=True, merge=rev) | |
@@ -464,11 +479,12 b' class queue(object):' | |||||
464 | except: |
|
479 | except: | |
465 | raise util.Abort(_("unable to read %s") % patch) |
|
480 | raise util.Abort(_("unable to read %s") % patch) | |
466 |
|
481 | |||
|
482 | diffopts = self.patchopts(diffopts, patch) | |||
467 | patchf = self.opener(patch, "w") |
|
483 | patchf = self.opener(patch, "w") | |
468 | comments = str(ph) |
|
484 | comments = str(ph) | |
469 | if comments: |
|
485 | if comments: | |
470 | patchf.write(comments) |
|
486 | patchf.write(comments) | |
471 | self.printdiff(repo, head, n, fp=patchf) |
|
487 | self.printdiff(repo, diffopts, head, n, fp=patchf) | |
472 | patchf.close() |
|
488 | patchf.close() | |
473 | self.removeundo(repo) |
|
489 | self.removeundo(repo) | |
474 | return (0, n) |
|
490 | return (0, n) | |
@@ -492,7 +508,7 b' class queue(object):' | |||||
492 | return pp[1] |
|
508 | return pp[1] | |
493 | return pp[0] |
|
509 | return pp[0] | |
494 |
|
510 | |||
495 | def mergepatch(self, repo, mergeq, series): |
|
511 | def mergepatch(self, repo, mergeq, series, diffopts): | |
496 | if len(self.applied) == 0: |
|
512 | if len(self.applied) == 0: | |
497 | # each of the patches merged in will have two parents. This |
|
513 | # each of the patches merged in will have two parents. This | |
498 | # can confuse the qrefresh, qdiff, and strip code because it |
|
514 | # can confuse the qrefresh, qdiff, and strip code because it | |
@@ -522,7 +538,7 b' class queue(object):' | |||||
522 | self.ui.warn(_("patch %s is not applied\n") % patch) |
|
538 | self.ui.warn(_("patch %s is not applied\n") % patch) | |
523 | return (1, None) |
|
539 | return (1, None) | |
524 | rev = bin(info[1]) |
|
540 | rev = bin(info[1]) | |
525 |
|
|
541 | err, head = self.mergeone(repo, mergeq, head, patch, rev, diffopts) | |
526 | if head: |
|
542 | if head: | |
527 | self.applied.append(statusentry(hex(head), patch)) |
|
543 | self.applied.append(statusentry(hex(head), patch)) | |
528 | self.applied_dirty = 1 |
|
544 | self.applied_dirty = 1 | |
@@ -757,6 +773,7 b' class queue(object):' | |||||
757 | date = opts.get('date') |
|
773 | date = opts.get('date') | |
758 | if date: |
|
774 | if date: | |
759 | date = util.parsedate(date) |
|
775 | date = util.parsedate(date) | |
|
776 | diffopts = self.diffopts({'git': opts.get('git')}) | |||
760 | self.check_reserved_name(patchfn) |
|
777 | self.check_reserved_name(patchfn) | |
761 | if os.path.exists(self.join(patchfn)): |
|
778 | if os.path.exists(self.join(patchfn)): | |
762 | raise util.Abort(_('patch "%s" already exists') % patchfn) |
|
779 | raise util.Abort(_('patch "%s" already exists') % patchfn) | |
@@ -806,8 +823,6 b' class queue(object):' | |||||
806 | msg = msg + "\n\n" |
|
823 | msg = msg + "\n\n" | |
807 | p.write(msg) |
|
824 | p.write(msg) | |
808 | if commitfiles: |
|
825 | if commitfiles: | |
809 | diffopts = self.diffopts() |
|
|||
810 | if opts.get('git'): diffopts.git = True |
|
|||
811 | parent = self.qparents(repo, n) |
|
826 | parent = self.qparents(repo, n) | |
812 | chunks = patch.diff(repo, node1=parent, node2=n, |
|
827 | chunks = patch.diff(repo, node1=parent, node2=n, | |
813 | match=match, opts=diffopts) |
|
828 | match=match, opts=diffopts) | |
@@ -932,6 +947,7 b' class queue(object):' | |||||
932 |
|
947 | |||
933 | def push(self, repo, patch=None, force=False, list=False, |
|
948 | def push(self, repo, patch=None, force=False, list=False, | |
934 | mergeq=None, all=False): |
|
949 | mergeq=None, all=False): | |
|
950 | diffopts = self.diffopts() | |||
935 | wlock = repo.wlock() |
|
951 | wlock = repo.wlock() | |
936 | try: |
|
952 | try: | |
937 | if repo.dirstate.parents()[0] not in repo.heads(): |
|
953 | if repo.dirstate.parents()[0] not in repo.heads(): | |
@@ -994,7 +1010,7 b' class queue(object):' | |||||
994 | all_files = {} |
|
1010 | all_files = {} | |
995 | try: |
|
1011 | try: | |
996 | if mergeq: |
|
1012 | if mergeq: | |
997 | ret = self.mergepatch(repo, mergeq, s) |
|
1013 | ret = self.mergepatch(repo, mergeq, s, diffopts) | |
998 | else: |
|
1014 | else: | |
999 | ret = self.apply(repo, s, list, all_files=all_files) |
|
1015 | ret = self.apply(repo, s, list, all_files=all_files) | |
1000 | except: |
|
1016 | except: | |
@@ -1137,8 +1153,8 b' class queue(object):' | |||||
1137 | node1, node2 = None, qp |
|
1153 | node1, node2 = None, qp | |
1138 | else: |
|
1154 | else: | |
1139 | node1, node2 = qp, None |
|
1155 | node1, node2 = qp, None | |
1140 |
|
|
1156 | diffopts = self.diffopts(opts) | |
1141 | self.printdiff(repo, node1, node2, files=pats, opts=opts) |
|
1157 | self.printdiff(repo, diffopts, node1, node2, files=pats, opts=opts) | |
1142 |
|
1158 | |||
1143 | def refresh(self, repo, pats=None, **opts): |
|
1159 | def refresh(self, repo, pats=None, **opts): | |
1144 | if len(self.applied) == 0: |
|
1160 | if len(self.applied) == 0: | |
@@ -1159,6 +1175,7 b' class queue(object):' | |||||
1159 | cparents = repo.changelog.parents(top) |
|
1175 | cparents = repo.changelog.parents(top) | |
1160 | patchparent = self.qparents(repo, top) |
|
1176 | patchparent = self.qparents(repo, top) | |
1161 | ph = patchheader(self.join(patchfn)) |
|
1177 | ph = patchheader(self.join(patchfn)) | |
|
1178 | diffopts = self.diffopts({'git': opts.get('git')}, patchfn) | |||
1162 | if msg: |
|
1179 | if msg: | |
1163 | ph.setmessage(msg) |
|
1180 | ph.setmessage(msg) | |
1164 | if newuser: |
|
1181 | if newuser: | |
@@ -1166,14 +1183,6 b' class queue(object):' | |||||
1166 | if newdate: |
|
1183 | if newdate: | |
1167 | ph.setdate(newdate) |
|
1184 | ph.setdate(newdate) | |
1168 |
|
1185 | |||
1169 | # if the patch was a git patch, refresh it as a git patch |
|
|||
1170 | patchf = self.opener(patchfn, 'r') |
|
|||
1171 | for line in patchf: |
|
|||
1172 | if line.startswith('diff --git'): |
|
|||
1173 | self.diffopts().git = True |
|
|||
1174 | break |
|
|||
1175 | patchf.close() |
|
|||
1176 |
|
||||
1177 | # only commit new patch when write is complete |
|
1186 | # only commit new patch when write is complete | |
1178 | patchf = self.opener(patchfn, 'w', atomictemp=True) |
|
1187 | patchf = self.opener(patchfn, 'w', atomictemp=True) | |
1179 |
|
1188 | |||
@@ -1181,8 +1190,6 b' class queue(object):' | |||||
1181 | if comments: |
|
1190 | if comments: | |
1182 | patchf.write(comments) |
|
1191 | patchf.write(comments) | |
1183 |
|
1192 | |||
1184 | if opts.get('git'): |
|
|||
1185 | self.diffopts().git = True |
|
|||
1186 | tip = repo.changelog.tip() |
|
1193 | tip = repo.changelog.tip() | |
1187 | if top == tip: |
|
1194 | if top == tip: | |
1188 | # if the top of our patch queue is also the tip, there is an |
|
1195 | # if the top of our patch queue is also the tip, there is an | |
@@ -1248,12 +1255,12 b' class queue(object):' | |||||
1248 | c = [filter(matchfn, l) for l in (m, a, r)] |
|
1255 | c = [filter(matchfn, l) for l in (m, a, r)] | |
1249 | match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2])) |
|
1256 | match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2])) | |
1250 | chunks = patch.diff(repo, patchparent, match=match, |
|
1257 | chunks = patch.diff(repo, patchparent, match=match, | |
1251 |
changes=c, opts= |
|
1258 | changes=c, opts=diffopts) | |
1252 | for chunk in chunks: |
|
1259 | for chunk in chunks: | |
1253 | patchf.write(chunk) |
|
1260 | patchf.write(chunk) | |
1254 |
|
1261 | |||
1255 | try: |
|
1262 | try: | |
1256 |
if |
|
1263 | if diffopts.git: | |
1257 | copies = {} |
|
1264 | copies = {} | |
1258 | for dst in a: |
|
1265 | for dst in a: | |
1259 | src = repo.dirstate.copied(dst) |
|
1266 | src = repo.dirstate.copied(dst) | |
@@ -1332,7 +1339,7 b' class queue(object):' | |||||
1332 | '(revert --all, qpush to recover)\n')) |
|
1339 | '(revert --all, qpush to recover)\n')) | |
1333 | raise |
|
1340 | raise | |
1334 | else: |
|
1341 | else: | |
1335 | self.printdiff(repo, patchparent, fp=patchf) |
|
1342 | self.printdiff(repo, diffopts, patchparent, fp=patchf) | |
1336 | patchf.rename() |
|
1343 | patchf.rename() | |
1337 | added = repo.status()[1] |
|
1344 | added = repo.status()[1] | |
1338 | for a in added: |
|
1345 | for a in added: | |
@@ -1612,9 +1619,7 b' class queue(object):' | |||||
1612 | % rev[0]) |
|
1619 | % rev[0]) | |
1613 | lastparent = None |
|
1620 | lastparent = None | |
1614 |
|
1621 | |||
1615 | if git: |
|
1622 | diffopts = self.diffopts({'git': git}) | |
1616 | self.diffopts().git = True |
|
|||
1617 |
|
||||
1618 | for r in rev: |
|
1623 | for r in rev: | |
1619 | p1, p2 = repo.changelog.parentrevs(r) |
|
1624 | p1, p2 = repo.changelog.parentrevs(r) | |
1620 | n = repo.changelog.node(r) |
|
1625 | n = repo.changelog.node(r) | |
@@ -1633,7 +1638,7 b' class queue(object):' | |||||
1633 | self.full_series.insert(0, patchname) |
|
1638 | self.full_series.insert(0, patchname) | |
1634 |
|
1639 | |||
1635 | patchf = self.opener(patchname, "w") |
|
1640 | patchf = self.opener(patchname, "w") | |
1636 |
patch.export(repo, [n], fp=patchf, opts= |
|
1641 | patch.export(repo, [n], fp=patchf, opts=diffopts) | |
1637 | patchf.close() |
|
1642 | patchf.close() | |
1638 |
|
1643 | |||
1639 | se = statusentry(hex(n), patchname) |
|
1644 | se = statusentry(hex(n), patchname) | |
@@ -2065,7 +2070,8 b' def fold(ui, repo, *files, **opts):' | |||||
2065 | if opts['edit']: |
|
2070 | if opts['edit']: | |
2066 | message = ui.edit(message, user or ui.username()) |
|
2071 | message = ui.edit(message, user or ui.username()) | |
2067 |
|
2072 | |||
2068 | q.refresh(repo, msg=message) |
|
2073 | diffopts = q.patchopts(q.diffopts(), *patches) | |
|
2074 | q.refresh(repo, msg=message, git=diffopts.git) | |||
2069 | q.delete(repo, patches, opts) |
|
2075 | q.delete(repo, patches, opts) | |
2070 | q.save_dirty() |
|
2076 | q.save_dirty() | |
2071 |
|
2077 |
@@ -55,6 +55,11 b' class diffopts(object):' | |||||
55 | raise util.Abort(_('diff context lines count must be ' |
|
55 | raise util.Abort(_('diff context lines count must be ' | |
56 | 'an integer, not %r') % self.context) |
|
56 | 'an integer, not %r') % self.context) | |
57 |
|
57 | |||
|
58 | def copy(self, **kwargs): | |||
|
59 | opts = dict((k, getattr(self, k)) for k in self.defaults) | |||
|
60 | opts.update(kwargs) | |||
|
61 | return diffopts(**opts) | |||
|
62 | ||||
58 | defaultopts = diffopts() |
|
63 | defaultopts = diffopts() | |
59 |
|
64 | |||
60 | def wsclean(opts, text, blank=True): |
|
65 | def wsclean(opts, text, blank=True): |
@@ -56,18 +56,27 b' echo' | |||||
56 | echo % init t2 |
|
56 | echo % init t2 | |
57 | hg init t2 |
|
57 | hg init t2 | |
58 | cd t2 |
|
58 | cd t2 | |
|
59 | echo '[diff]' > .hg/hgrc | |||
|
60 | echo 'nodates = 1' >> .hg/hgrc | |||
59 | echo a > a |
|
61 | echo a > a | |
60 | hg ci -Am init |
|
62 | hg ci -Am init | |
61 |
echo b > |
|
63 | echo b > a | |
62 | hg ci -m changea |
|
64 | hg ci -m changea | |
63 | hg up -C 0 |
|
65 | hg up -C 0 | |
|
66 | hg cp a aa | |||
64 | echo c >> a |
|
67 | echo c >> a | |
65 | hg qnew -f -e patcha |
|
68 | hg qnew --git -f -e patcha | |
|
69 | echo d >> a | |||
|
70 | hg qnew -d '0 0' -f -e patcha2 | |||
66 | echo % create the reference queue |
|
71 | echo % create the reference queue | |
67 | hg qsave -c -e -n refqueue 2> /dev/null |
|
72 | hg qsave -c -e -n refqueue 2> /dev/null | |
68 | hg up -C 1 |
|
73 | hg up -C 1 | |
69 | echo % merge |
|
74 | echo % merge | |
70 | hg qpush -m -n refqueue 2>&1 | \ |
|
75 | HGMERGE=internal:other hg qpush -a -m -n refqueue 2>&1 | \ | |
71 | sed 's/merging with queue at.*refqueue/merging with queue at refqueue/' |
|
76 | sed 's/merging with queue at.*refqueue/merging with queue at refqueue/' | |
|
77 | echo % check patcha is still a git patch | |||
|
78 | cat .hg/patches/patcha | |||
|
79 | echo % check patcha2 is still a regular patch | |||
|
80 | grep git .hg/patches/patcha2 && echo 'git patch found!' | |||
72 | cd .. |
|
81 | cd .. | |
73 |
|
82 |
@@ -18,8 +18,35 b' patch queue now empty' | |||||
18 | adding a |
|
18 | adding a | |
19 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
19 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
20 | % create the reference queue |
|
20 | % create the reference queue | |
21 |
1 files updated, 0 files merged, |
|
21 | 1 files updated, 0 files merged, 1 files removed, 0 files unresolved | |
22 | % merge |
|
22 | % merge | |
23 | merging with queue at refqueue |
|
23 | merging with queue at refqueue | |
24 | applying patcha |
|
24 | applying patcha | |
25 | now at: patcha |
|
25 | patching file a | |
|
26 | Hunk #1 FAILED at 0 | |||
|
27 | 1 out of 1 hunks FAILED -- saving rejects to file a.rej | |||
|
28 | patch failed, unable to continue (try -v) | |||
|
29 | patch failed, rejects left in working dir | |||
|
30 | patch didn't work out, merging patcha | |||
|
31 | 1 files updated, 0 files merged, 1 files removed, 0 files unresolved | |||
|
32 | 0 files updated, 2 files merged, 0 files removed, 0 files unresolved | |||
|
33 | (branch merge, don't forget to commit) | |||
|
34 | applying patcha2 | |||
|
35 | now at: patcha2 | |||
|
36 | % check patcha is still a git patch | |||
|
37 | diff --git a/a b/a | |||
|
38 | --- a/a | |||
|
39 | +++ b/a | |||
|
40 | @@ -1,1 +1,2 @@ | |||
|
41 | -b | |||
|
42 | +a | |||
|
43 | +c | |||
|
44 | diff --git a/a b/aa | |||
|
45 | copy from a | |||
|
46 | copy to aa | |||
|
47 | --- a/a | |||
|
48 | +++ b/aa | |||
|
49 | @@ -1,1 +1,1 @@ | |||
|
50 | -b | |||
|
51 | +a | |||
|
52 | % check patcha2 is still a regular patch |
@@ -25,12 +25,35 b" echo '% fold in the middle of the queue'" | |||||
25 | hg qpop p1 |
|
25 | hg qpop p1 | |
26 | hg qdiff | filterdiff |
|
26 | hg qdiff | filterdiff | |
27 | hg qfold p2 |
|
27 | hg qfold p2 | |
|
28 | grep git .hg/patches/p1 && echo 'git patch found!' | |||
28 | hg qser |
|
29 | hg qser | |
29 | hg qdiff | filterdiff |
|
30 | hg qdiff | filterdiff | |
30 | echo '% fold with local changes' |
|
31 | echo '% fold with local changes' | |
31 | echo d >> a |
|
32 | echo d >> a | |
32 | hg qfold p3 |
|
33 | hg qfold p3 | |
33 | hg diff -c . | filterdiff |
|
34 | hg diff -c . | filterdiff | |
|
35 | hg revert -a --no-backup | |||
|
36 | ||||
|
37 | echo '% fold git patch into a regular patch, expect git patch' | |||
|
38 | echo a >> a | |||
|
39 | hg qnew -f regular | |||
|
40 | hg cp a aa | |||
|
41 | hg qnew --git -f git | |||
|
42 | hg qpop | |||
|
43 | hg qfold git | |||
|
44 | cat .hg/patches/regular | |||
|
45 | hg qpop | |||
|
46 | hg qdel regular | |||
|
47 | ||||
|
48 | echo '% fold regular patch into a git patch, expect git patch' | |||
|
49 | hg cp a aa | |||
|
50 | hg qnew --git -f git | |||
|
51 | echo b >> aa | |||
|
52 | hg qnew -f regular | |||
|
53 | hg qpop | |||
|
54 | hg qfold regular | |||
|
55 | cat .hg/patches/git | |||
|
56 | ||||
34 | cd .. |
|
57 | cd .. | |
35 |
|
58 | |||
36 |
|
59 |
@@ -25,3 +25,40 b' abort: local changes found, refresh firs' | |||||
25 | a |
|
25 | a | |
26 | +a |
|
26 | +a | |
27 | +b |
|
27 | +b | |
|
28 | reverting a | |||
|
29 | % fold git patch into a regular patch, expect git patch | |||
|
30 | popping git | |||
|
31 | now at: regular | |||
|
32 | diff --git a/a b/a | |||
|
33 | --- a/a | |||
|
34 | +++ b/a | |||
|
35 | @@ -1,3 +1,4 @@ | |||
|
36 | a | |||
|
37 | a | |||
|
38 | b | |||
|
39 | +a | |||
|
40 | diff --git a/a b/aa | |||
|
41 | copy from a | |||
|
42 | copy to aa | |||
|
43 | --- a/a | |||
|
44 | +++ b/aa | |||
|
45 | @@ -1,3 +1,4 @@ | |||
|
46 | a | |||
|
47 | a | |||
|
48 | b | |||
|
49 | +a | |||
|
50 | popping regular | |||
|
51 | now at: p1 | |||
|
52 | % fold regular patch into a git patch, expect git patch | |||
|
53 | popping regular | |||
|
54 | now at: git | |||
|
55 | diff --git a/a b/aa | |||
|
56 | copy from a | |||
|
57 | copy to aa | |||
|
58 | --- a/a | |||
|
59 | +++ b/aa | |||
|
60 | @@ -1,3 +1,4 @@ | |||
|
61 | a | |||
|
62 | a | |||
|
63 | b | |||
|
64 | +b |
General Comments 0
You need to be logged in to leave comments.
Login now