310 |
310 |
311 def __init__(self, ui, repo): |
311 def __init__(self, ui, repo): |
312 self.ui = ui |
312 self.ui = ui |
313 self.repo = repo |
313 self.repo = repo |
314 |
314 |
315 def show(self, rev=0, changenode=None, brinfo=None): |
315 def show(self, rev=0, changenode=None, brinfo=None, copies=None): |
316 '''show a single changeset or file revision''' |
316 '''show a single changeset or file revision''' |
317 log = self.repo.changelog |
317 log = self.repo.changelog |
318 if changenode is None: |
318 if changenode is None: |
319 changenode = log.node(rev) |
319 changenode = log.node(rev) |
320 elif not rev: |
320 elif not rev: |
357 files): |
357 files): |
358 if value: |
358 if value: |
359 self.ui.note("%-12s %s\n" % (key, " ".join(value))) |
359 self.ui.note("%-12s %s\n" % (key, " ".join(value))) |
360 else: |
360 else: |
361 self.ui.note(_("files: %s\n") % " ".join(changes[3])) |
361 self.ui.note(_("files: %s\n") % " ".join(changes[3])) |
|
362 if copies: |
|
363 copies = ['%s (%s)' % c for c in copies] |
|
364 self.ui.note(_("copies: %s\n") % ' '.join(copies)) |
362 |
365 |
363 description = changes[4].strip() |
366 description = changes[4].strip() |
364 if description: |
367 if description: |
365 if self.ui.verbose: |
368 if self.ui.verbose: |
366 self.ui.status(_("description:\n")) |
369 self.ui.status(_("description:\n")) |
1772 if limit <= 0: raise util.Abort(_('limit must be positive')) |
1775 if limit <= 0: raise util.Abort(_('limit must be positive')) |
1773 else: |
1776 else: |
1774 limit = sys.maxint |
1777 limit = sys.maxint |
1775 count = 0 |
1778 count = 0 |
1776 |
1779 |
|
1780 if opts['copies'] and opts['rev']: |
|
1781 endrev = max([int(i) |
|
1782 for i in cmdutil.revrange(ui, repo, opts['rev'])]) + 1 |
|
1783 else: |
|
1784 endrev = repo.changelog.count() |
|
1785 rcache = {} |
|
1786 ncache = {} |
|
1787 dcache = [] |
|
1788 def getrenamed(fn, rev, man): |
|
1789 '''looks up all renames for a file (up to endrev) the first |
|
1790 time the file is given. It indexes on the changerev and only |
|
1791 parses the manifest if linkrev != changerev. |
|
1792 Returns rename info for fn at changerev rev.''' |
|
1793 if fn not in rcache: |
|
1794 rcache[fn] = {} |
|
1795 ncache[fn] = {} |
|
1796 fl = repo.file(fn) |
|
1797 for i in xrange(fl.count()): |
|
1798 node = fl.node(i) |
|
1799 lr = fl.linkrev(node) |
|
1800 renamed = fl.renamed(node) |
|
1801 rcache[fn][lr] = renamed |
|
1802 if renamed: |
|
1803 ncache[fn][node] = renamed |
|
1804 if lr >= endrev: |
|
1805 break |
|
1806 if rev in rcache[fn]: |
|
1807 return rcache[fn][rev] |
|
1808 if not dcache or dcache[0] != man: |
|
1809 dcache[:] = [man, repo.manifest.readdelta(man)] |
|
1810 if fn in dcache[1]: |
|
1811 return ncache[fn].get(dcache[1][fn]) |
|
1812 return None |
|
1813 |
1777 displayer = show_changeset(ui, repo, opts) |
1814 displayer = show_changeset(ui, repo, opts) |
1778 for st, rev, fns in changeiter: |
1815 for st, rev, fns in changeiter: |
1779 if st == 'window': |
1816 if st == 'window': |
1780 du = dui(ui) |
1817 du = dui(ui) |
1781 displayer.ui = du |
1818 displayer.ui = du |
1803 |
1840 |
1804 br = None |
1841 br = None |
1805 if opts['branches']: |
1842 if opts['branches']: |
1806 br = repo.branchlookup([repo.changelog.node(rev)]) |
1843 br = repo.branchlookup([repo.changelog.node(rev)]) |
1807 |
1844 |
1808 displayer.show(rev, brinfo=br) |
1845 copies = [] |
|
1846 if opts.get('copies') and rev: |
|
1847 mf = getchange(rev)[0] |
|
1848 for fn in getchange(rev)[3]: |
|
1849 rename = getrenamed(fn, rev, mf) |
|
1850 if rename: |
|
1851 copies.append((fn, rename[0])) |
|
1852 displayer.show(rev, brinfo=br, copies=copies) |
1809 if opts['patch']: |
1853 if opts['patch']: |
1810 prev = (parents and parents[0]) or nullid |
1854 prev = (parents and parents[0]) or nullid |
1811 patch.diff(repo, prev, changenode, match=matchfn, fp=du) |
1855 patch.diff(repo, prev, changenode, match=matchfn, fp=du) |
1812 du.write("\n\n") |
1856 du.write("\n\n") |
1813 elif st == 'iter': |
1857 elif st == 'iter': |
2887 [('b', 'branches', None, _('show branches')), |
2931 [('b', 'branches', None, _('show branches')), |
2888 ('f', 'follow', None, |
2932 ('f', 'follow', None, |
2889 _('follow changeset history, or file history across copies and renames')), |
2933 _('follow changeset history, or file history across copies and renames')), |
2890 ('', 'follow-first', None, |
2934 ('', 'follow-first', None, |
2891 _('only follow the first parent of merge changesets')), |
2935 _('only follow the first parent of merge changesets')), |
|
2936 ('C', 'copies', None, _('show copied files')), |
2892 ('k', 'keyword', [], _('search for a keyword')), |
2937 ('k', 'keyword', [], _('search for a keyword')), |
2893 ('l', 'limit', '', _('limit number of changes displayed')), |
2938 ('l', 'limit', '', _('limit number of changes displayed')), |
2894 ('r', 'rev', [], _('show the specified revision or range')), |
2939 ('r', 'rev', [], _('show the specified revision or range')), |
2895 ('M', 'no-merges', None, _('do not show merges')), |
2940 ('M', 'no-merges', None, _('do not show merges')), |
2896 ('', 'style', '', _('display using template map file')), |
2941 ('', 'style', '', _('display using template map file')), |