[PATCH V2 1/2] diff: add the --output option

Augie Fackler raf at durin42.com
Tue Jul 9 16:52:23 CDT 2013


On Jul 1, 2013, at 12:25 PM, Ahmed S. Darwish <darwish.07 at gmail.com> wrote:

> # HG changeset patch
> # User Ahmed S. Darwish <a.darwish at vireton.com>
> # Date 1372695210 -7200
> # Node ID c1aa2fdfc7b7a8fff58b192259dcdf4f74f7ada7
> # Parent  648d1974b3f328947ee6cf2d00c66815a33cd208
> diff: add the --output option
> 
> For all shells which cannot save a command standard output correctly,
> this option is now introduced.
> 
> The most common example is Microsoft PowerShell, where the piped
> output gets corrupted if saved using the standard, unix-like, stdout
> rediction, '>' operator. By transforming the piped output to a
> different encoding, PowerShell saves 'hg diff' patch output to a
> format __not understandable__ by GNU patch and 'hg patch' commands.
> 
> Windows PowerShell is installed by default on all Windows 7+
> machines (Windows 7, 8, Server 2008, and Server 2012). An easily
> invokable 'hg diff > temp.patch' command should thus be available
> on these systems.
> 
> For a similar real-world scenario, please check:
> 
> http://www.webcitation.org/6Hiiqf425 - Archived from the original
> post at http://nbevans.wordpress.com/2011/02/22/lightweight-shelving-of-your-work-in-progress-with-mercurial/
> 
> diff -r 648d1974b3f3 -r c1aa2fdfc7b7 mercurial/cmdutil.py
> --- a/mercurial/cmdutil.py	Sun Jun 30 15:19:39 2013 -0500
> +++ b/mercurial/cmdutil.py	Mon Jul 01 18:13:30 2013 +0200
> @@ -7,6 +7,7 @@
> 
> from node import hex, nullid, nullrev, short
> from i18n import _
> +from datetime import datetime
> import os, sys, errno, re, tempfile
> import util, scmutil, templater, patch, error, templatekw, revlog, copies
> import match as matchmod
> @@ -123,6 +124,16 @@
>         limit = None
>     return limit
> 
> +def fsfriendly(user):
> +    """return committer's username in a short and filesystem-friendly
> +    manner.  This basically implies removing email info, white spaces,
> +    and other problematic characters for common filesystems.
> +    reference: MSDN - Naming Files, Paths, and Namespaces.
> +    """
> +    user = re.sub('\<[^<]*@[^>]*\>', '', user)
> +    user = re.sub("[\W]", '', user)
> +    return user.lower()
> +

This function could really stand to be its own patch.

> def makefilename(repo, pat, node, desc=None,
>                   total=None, seqno=None, revwidth=None, pathname=None):
>     node_expander = {
> @@ -134,6 +145,8 @@
>     expander = {
>         '%': lambda: '%',
>         'b': lambda: os.path.basename(repo.root),
> +        'u': lambda: fsfriendly(repo.ui.username()),
> +        'd': lambda: datetime.now().strftime("%Y_%m_%d-%H_%M_%S")
>         }
> 
>     try:
> diff -r 648d1974b3f3 -r c1aa2fdfc7b7 mercurial/commands.py
> --- a/mercurial/commands.py	Sun Jun 30 15:19:39 2013 -0500
> +++ b/mercurial/commands.py	Mon Jul 01 18:13:30 2013 +0200
> @@ -2676,7 +2676,9 @@
>         ui.warn("%s\n" % res2)
> 
> @command('^diff',
> -    [('r', 'rev', [], _('revision'), _('REV')),
> +    [('o', 'output', '',
> +     _('print output to file with formatted name'), _('FORMAT')),
> +    ('r', 'rev', [], _('revision'), _('REV')),
>     ('c', 'change', '', _('change made by revision'), _('REV'))
>     ] + diffopts + diffopts2 + walkopts + subrepoopts,
>     _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
> @@ -2692,6 +2694,21 @@
>        default to comparing against the working directory's first
>        parent changeset if no revisions are specified.
> 
> +    Output may be to a file, in which case the name of the file is
> +    given using a format string. The formatting rules are as follows:
> +
> +    :``%%``: literal "%" character
> +    :``%b``: basename of the exporting repository
> +    :``%u``: committer username, in a filesystem-friendly manner
> +    :``%d``: current local date and time
> +
> +    .. note::
> +       Do not save diff output using Windows PowerShell (R) pipeline
> +       `|` or standard output redirection `>` facilities. They change
> +       the resulting diffs encoding, making them unappliable by
> +       :hg:`patch` or GNU patch afterwards. Use the
> +       :hg:`diff --output` option instead.
> +
>     When two revision arguments are given, then changes are shown
>     between those revisions. If only one revision is specified then
>     that revision is compared to the working directory, and, when no
> @@ -2737,6 +2754,7 @@
>     Returns 0 on success.
>     """
> 
> +    fname = opts.get('output')
>     revs = opts.get('rev')
>     change = opts.get('change')
>     stat = opts.get('stat')
> @@ -2754,10 +2772,14 @@
>     if reverse:
>         node1, node2 = node2, node1
> 
> +    fp = None
> +    if fname:
> +        fp = cmdutil.makefileobj(repo, fname)
> +
>     diffopts = patch.diffopts(ui, opts)
>     m = scmutil.match(repo[node2], pats, opts)
>     cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
> -                           listsubrepos=opts.get('subrepos'))
> +                           fp=fp, listsubrepos=opts.get('subrepos'))
> 
> @command('^export',
>     [('o', 'output', '',
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel



More information about the Mercurial-devel mailing list