mercurial/logcmdutil.py
changeset 51139 204af2aa4931
parent 49622 dcb2581e33be
child 51140 d6e5bec550f1
equal deleted inserted replaced
51138:c845479fc64d 51139:204af2aa4931
    96         return wctx
    96         return wctx
    97     else:
    97     else:
    98         return ctx.p1()
    98         return ctx.p1()
    99 
    99 
   100 
   100 
       
   101 def get_diff_chunks(
       
   102     ui,
       
   103     repo,
       
   104     diffopts,
       
   105     ctx1,
       
   106     ctx2,
       
   107     match,
       
   108     changes=None,
       
   109     stat=False,
       
   110     prefix=b'',
       
   111     root=b'',
       
   112     hunksfilterfn=None,
       
   113 ):
       
   114     if root:
       
   115         relroot = pathutil.canonpath(repo.root, repo.getcwd(), root)
       
   116     else:
       
   117         relroot = b''
       
   118     copysourcematch = None
       
   119 
       
   120     def compose(f, g):
       
   121         return lambda x: f(g(x))
       
   122 
       
   123     def pathfn(f):
       
   124         return posixpath.join(prefix, f)
       
   125 
       
   126     if relroot != b'':
       
   127         # XXX relative roots currently don't work if the root is within a
       
   128         # subrepo
       
   129         uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
       
   130         uirelroot = uipathfn(pathfn(relroot))
       
   131         relroot += b'/'
       
   132         for matchroot in match.files():
       
   133             if not matchroot.startswith(relroot):
       
   134                 ui.warn(
       
   135                     _(b'warning: %s not inside relative root %s\n')
       
   136                     % (uipathfn(pathfn(matchroot)), uirelroot)
       
   137                 )
       
   138 
       
   139         relrootmatch = scmutil.match(ctx2, pats=[relroot], default=b'path')
       
   140         match = matchmod.intersectmatchers(match, relrootmatch)
       
   141         copysourcematch = relrootmatch
       
   142 
       
   143         checkroot = repo.ui.configbool(
       
   144             b'devel', b'all-warnings'
       
   145         ) or repo.ui.configbool(b'devel', b'check-relroot')
       
   146 
       
   147         def relrootpathfn(f):
       
   148             if checkroot and not f.startswith(relroot):
       
   149                 raise AssertionError(
       
   150                     b"file %s doesn't start with relroot %s" % (f, relroot)
       
   151                 )
       
   152             return f[len(relroot) :]
       
   153 
       
   154         pathfn = compose(relrootpathfn, pathfn)
       
   155 
       
   156     if stat:
       
   157         diffopts = diffopts.copy(context=0, noprefix=False)
       
   158         # If an explicit --root was given, don't respect ui.relative-paths
       
   159         if not relroot:
       
   160             pathfn = compose(scmutil.getuipathfn(repo), pathfn)
       
   161 
       
   162     return ctx2.diff(
       
   163         ctx1,
       
   164         match,
       
   165         changes,
       
   166         opts=diffopts,
       
   167         pathfn=pathfn,
       
   168         copysourcematch=copysourcematch,
       
   169         hunksfilterfn=hunksfilterfn,
       
   170     )
       
   171 
       
   172 
   101 def diffordiffstat(
   173 def diffordiffstat(
   102     ui,
   174     ui,
   103     repo,
   175     repo,
   104     diffopts,
   176     diffopts,
   105     ctx1,
   177     ctx1,
   113     root=b'',
   185     root=b'',
   114     listsubrepos=False,
   186     listsubrepos=False,
   115     hunksfilterfn=None,
   187     hunksfilterfn=None,
   116 ):
   188 ):
   117     '''show diff or diffstat.'''
   189     '''show diff or diffstat.'''
   118     if root:
   190 
   119         relroot = pathutil.canonpath(repo.root, repo.getcwd(), root)
   191     chunks = get_diff_chunks(
   120     else:
   192         ui,
   121         relroot = b''
   193         repo,
   122     copysourcematch = None
   194         diffopts,
   123 
   195         ctx1,
   124     def compose(f, g):
   196         ctx2,
   125         return lambda x: f(g(x))
   197         match,
   126 
   198         changes=changes,
   127     def pathfn(f):
   199         stat=stat,
   128         return posixpath.join(prefix, f)
   200         prefix=prefix,
   129 
   201         root=root,
   130     if relroot != b'':
   202         hunksfilterfn=hunksfilterfn,
   131         # XXX relative roots currently don't work if the root is within a
   203     )
   132         # subrepo
       
   133         uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
       
   134         uirelroot = uipathfn(pathfn(relroot))
       
   135         relroot += b'/'
       
   136         for matchroot in match.files():
       
   137             if not matchroot.startswith(relroot):
       
   138                 ui.warn(
       
   139                     _(b'warning: %s not inside relative root %s\n')
       
   140                     % (uipathfn(pathfn(matchroot)), uirelroot)
       
   141                 )
       
   142 
       
   143         relrootmatch = scmutil.match(ctx2, pats=[relroot], default=b'path')
       
   144         match = matchmod.intersectmatchers(match, relrootmatch)
       
   145         copysourcematch = relrootmatch
       
   146 
       
   147         checkroot = repo.ui.configbool(
       
   148             b'devel', b'all-warnings'
       
   149         ) or repo.ui.configbool(b'devel', b'check-relroot')
       
   150 
       
   151         def relrootpathfn(f):
       
   152             if checkroot and not f.startswith(relroot):
       
   153                 raise AssertionError(
       
   154                     b"file %s doesn't start with relroot %s" % (f, relroot)
       
   155                 )
       
   156             return f[len(relroot) :]
       
   157 
       
   158         pathfn = compose(relrootpathfn, pathfn)
       
   159 
   204 
   160     if stat:
   205     if stat:
   161         diffopts = diffopts.copy(context=0, noprefix=False)
   206         diffopts = diffopts.copy(context=0, noprefix=False)
   162         width = 80
   207         width = 80
   163         if not ui.plain():
   208         if not ui.plain():
   164             width = ui.termwidth() - graphwidth
   209             width = ui.termwidth() - graphwidth
   165         # If an explicit --root was given, don't respect ui.relative-paths
       
   166         if not relroot:
       
   167             pathfn = compose(scmutil.getuipathfn(repo), pathfn)
       
   168 
       
   169     chunks = ctx2.diff(
       
   170         ctx1,
       
   171         match,
       
   172         changes,
       
   173         opts=diffopts,
       
   174         pathfn=pathfn,
       
   175         copysourcematch=copysourcematch,
       
   176         hunksfilterfn=hunksfilterfn,
       
   177     )
       
   178 
   210 
   179     if fp is not None or ui.canwritewithoutlabels():
   211     if fp is not None or ui.canwritewithoutlabels():
   180         out = fp or ui
   212         out = fp or ui
   181         if stat:
   213         if stat:
   182             chunks = [patch.diffstat(util.iterlines(chunks), width=width)]
   214             chunks = [patch.diffstat(util.iterlines(chunks), width=width)]
   247             stat=stat,
   279             stat=stat,
   248             graphwidth=graphwidth,
   280             graphwidth=graphwidth,
   249             hunksfilterfn=self._makehunksfilter(ctx),
   281             hunksfilterfn=self._makehunksfilter(ctx),
   250         )
   282         )
   251 
   283 
       
   284     def getdiffstats(self, ui, ctx, diffopts, stat=False):
       
   285         chunks = get_diff_chunks(
       
   286             ui,
       
   287             ctx.repo(),
       
   288             diffopts,
       
   289             diff_parent(ctx),
       
   290             ctx,
       
   291             match=self._makefilematcher(ctx),
       
   292             stat=stat,
       
   293             hunksfilterfn=self._makehunksfilter(ctx),
       
   294         )
       
   295 
       
   296         diffdata = []
       
   297         for filename, additions, removals, binary in patch.diffstatdata(
       
   298             util.iterlines(chunks)
       
   299         ):
       
   300             diffdata.append(
       
   301                 {
       
   302                     b"name": filename,
       
   303                     b"additions": additions,
       
   304                     b"removals": removals,
       
   305                     b"binary": binary,
       
   306                 }
       
   307             )
       
   308 
       
   309         return diffdata
       
   310 
   252 
   311 
   253 def changesetlabels(ctx):
   312 def changesetlabels(ctx):
   254     labels = [b'log.changeset', b'changeset.%s' % ctx.phasestr()]
   313     labels = [b'log.changeset', b'changeset.%s' % ctx.phasestr()]
   255     if ctx.obsolete():
   314     if ctx.obsolete():
   256         labels.append(b'changeset.obsolete')
   315         labels.append(b'changeset.obsolete')
   523             fm.data(
   582             fm.data(
   524                 copies=fm.formatdict(copies or {}, key=b'name', value=b'source')
   583                 copies=fm.formatdict(copies or {}, key=b'name', value=b'source')
   525             )
   584             )
   526 
   585 
   527         if self._includestat or b'diffstat' in datahint:
   586         if self._includestat or b'diffstat' in datahint:
   528             self.ui.pushbuffer()
   587             data = self._differ.getdiffstats(
   529             self._differ.showdiff(self.ui, ctx, self._diffopts, stat=True)
   588                 self.ui, ctx, self._diffopts, stat=True
   530             fm.data(diffstat=self.ui.popbuffer())
   589             )
       
   590             fm.data(diffstat=fm.formatlist(data, name=b'diffstat'))
   531         if self._includediff or b'diff' in datahint:
   591         if self._includediff or b'diff' in datahint:
   532             self.ui.pushbuffer()
   592             self.ui.pushbuffer()
   533             self._differ.showdiff(self.ui, ctx, self._diffopts, stat=False)
   593             self._differ.showdiff(self.ui, ctx, self._diffopts, stat=False)
   534             fm.data(diff=self.ui.popbuffer())
   594             fm.data(diff=self.ui.popbuffer())
   535 
   595