hgext/extdiff.py
author Patrick Mezard <pmezard@gmail.com>
Thu, 09 Apr 2009 14:32:44 +0200
changeset 8065 66d0a03d3afc
parent 8064 5c7bc1aece9e
child 8066 aece3c9e62f1
permissions -rw-r--r--
extdiff: preserve execute-bit across copies (issue1562) Bug report and test by Mads Kiilerich <mads@kiilerich.com>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     1
# extdiff.py - external diff program support for mercurial
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     2
#
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     3
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     4
#
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
     7
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
     8
'''
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
     9
The `extdiff' Mercurial extension allows you to use external programs
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    10
to compare revisions, or revision with working dir.  The external diff
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    11
programs are called with a configurable set of options and two
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    12
non-option arguments: paths to directories containing snapshots of
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    13
files to compare.
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    14
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    15
To enable this extension:
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    16
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    17
  [extensions]
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    18
  hgext.extdiff =
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    19
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    20
The `extdiff' extension also allows to configure new diff commands, so
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    21
you do not need to type "hg extdiff -p kdiff3" always.
3127
8e8deb8035a4 Update [extdiff] configuration sample for vimdiff,
Mathieu Clabaut <mathieu.clabaut@systerel.fr>
parents: 3090
diff changeset
    22
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    23
  [extdiff]
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    24
  # add new command that runs GNU diff(1) in 'context diff' mode
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    25
  cdiff = gdiff -Nprc5
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    26
  ## or the old way:
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    27
  #cmd.cdiff = gdiff
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    28
  #opts.cdiff = -Nprc5
3127
8e8deb8035a4 Update [extdiff] configuration sample for vimdiff,
Mathieu Clabaut <mathieu.clabaut@systerel.fr>
parents: 3090
diff changeset
    29
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    30
  # add new command called vdiff, runs kdiff3
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    31
  vdiff = kdiff3
3127
8e8deb8035a4 Update [extdiff] configuration sample for vimdiff,
Mathieu Clabaut <mathieu.clabaut@systerel.fr>
parents: 3090
diff changeset
    32
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    33
  # add new command called meld, runs meld (no need to name twice)
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    34
  meld =
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    35
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    36
  # add new command called vimdiff, runs gvimdiff with DirDiff plugin
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    37
  #(see http://www.vim.org/scripts/script.php?script_id=102)
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    38
  # Non english user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    39
  # your .vimrc
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    40
  vimdiff = gvim -f '+next' '+execute "DirDiff" argv(0) argv(1)'
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    41
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    42
You can use -I/-X and list of file or directory names like normal
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    43
"hg diff" command.  The `extdiff' extension makes snapshots of only
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    44
needed files, so running the external diff program will actually be
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    45
pretty fast (at least faster than having to compare the entire tree).
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    46
'''
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    47
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
    48
from mercurial.i18n import _
6211
f89fd07fc51d Expand import * to allow Pyflakes to find problems
Joel Rosdahl <joel@rosdahl.net>
parents: 6103
diff changeset
    49
from mercurial.node import short
5147
c80af96943aa refactor options from cmdtable
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 5143
diff changeset
    50
from mercurial import cmdutil, util, commands
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
    51
import os, shlex, shutil, tempfile
5135
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
    52
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    53
def snapshot(ui, repo, files, node, tmproot):
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    54
    '''snapshot files as of some revision
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    55
    if not using snapshot, -I/-X does not work and recursive diff
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    56
    in tools like kdiff3 and meld displays too many files.'''
5135
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
    57
    dirname = os.path.basename(repo.root)
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
    58
    if dirname == "":
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
    59
        dirname = "root"
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    60
    if node is not None:
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    61
        dirname = '%s.%s' % (dirname, short(node))
5135
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
    62
    base = os.path.join(tmproot, dirname)
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
    63
    os.mkdir(base)
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    64
    if node is not None:
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    65
        ui.note(_('making snapshot of %d files from rev %s\n') %
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    66
                (len(files), short(node)))
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    67
    else:
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    68
        ui.note(_('making snapshot of %d files from working dir\n') %
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    69
            (len(files)))
8065
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
    70
    wopener = util.opener(base)
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    71
    fns_and_mtime = []
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6603
diff changeset
    72
    ctx = repo[node]
5135
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
    73
    for fn in files:
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6603
diff changeset
    74
        wfn = util.pconvert(fn)
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6603
diff changeset
    75
        if not wfn in ctx:
5135
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
    76
            # skipping new file after a merge ?
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
    77
            continue
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
    78
        ui.note('  %s\n' % wfn)
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
    79
        dest = os.path.join(base, wfn)
8065
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
    80
        fctx = ctx[wfn]
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
    81
        data = repo.wwritedata(wfn, fctx.data())
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
    82
        if 'l' in fctx.flags():
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
    83
            wopener.symlink(data, wfn)
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
    84
        else:
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
    85
            wopener(wfn, 'w').write(data)
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
    86
            if 'x' in fctx.flags():
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
    87
                util.set_flags(dest, False, True)
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    88
        if node is None:
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
    89
            fns_and_mtime.append((dest, repo.wjoin(fn), os.path.getmtime(dest)))
6103
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
    90
    return dirname, fns_and_mtime
5143
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5137
diff changeset
    91
2906
453097750fbf extdiff: fix bugs. add test.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2903
diff changeset
    92
def dodiff(ui, repo, diffcmd, diffopts, pats, opts):
6103
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
    93
    '''Do the actuall diff:
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
    94
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
    95
    - copy to a temp structure if diffing 2 internal revisions
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
    96
    - copy to a temp structure if diffing working revision with
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
    97
      another one and more than 1 file is changed
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
    98
    - just invoke the diff for a single file in the working dir
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
    99
    '''
7758
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   100
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   101
    revs = opts.get('rev')
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   102
    change = opts.get('change')
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   103
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   104
    if revs and change:
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   105
        msg = _('cannot specify --rev and --change at the same time')
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   106
        raise util.Abort(msg)
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   107
    elif change:
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   108
        node2 = repo.lookup(change)
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   109
        node1 = repo[node2].parents()[0].node()
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   110
    else:
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   111
        node1, node2 = cmdutil.revpair(repo, revs)
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   112
6582
5acbdd3941c4 walk: remove remaining users of cmdutils.matchpats
Matt Mackall <mpm@selenic.com>
parents: 6211
diff changeset
   113
    matcher = cmdutil.match(repo, pats, opts)
6760
4faaa0535ea7 status: clean up all users for unknown files
Matt Mackall <mpm@selenic.com>
parents: 6747
diff changeset
   114
    modified, added, removed = repo.status(node1, node2, matcher)[:3]
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   115
    if not (modified or added or removed):
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   116
        return 0
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   117
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   118
    tmproot = tempfile.mkdtemp(prefix='extdiff.')
5137
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   119
    dir2root = ''
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   120
    try:
5137
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   121
        # Always make a copy of node1
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
   122
        dir1 = snapshot(ui, repo, modified + removed, node1, tmproot)[0]
5137
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   123
        changes = len(modified) + len(removed) + len(added)
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   124
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   125
        # If node2 in not the wc or there is >1 change, copy it
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
   126
        if node2 or changes > 1:
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
   127
            dir2, fns_and_mtime = snapshot(ui, repo, modified + added, node2, tmproot)
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   128
        else:
5137
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   129
            # This lets the diff tool open the changed file directly
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   130
            dir2 = ''
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   131
            dir2root = repo.root
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
   132
            fns_and_mtime = []
5137
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   133
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   134
        # If only one change, diff the files instead of the directories
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   135
        if changes == 1 :
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   136
            if len(modified):
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   137
                dir1 = os.path.join(dir1, util.localpath(modified[0]))
5143
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5137
diff changeset
   138
                dir2 = os.path.join(dir2root, dir2, util.localpath(modified[0]))
5137
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   139
            elif len(removed) :
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   140
                dir1 = os.path.join(dir1, util.localpath(removed[0]))
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   141
                dir2 = os.devnull
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   142
            else:
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
   143
                dir1 = os.devnull
5143
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5137
diff changeset
   144
                dir2 = os.path.join(dir2root, dir2, util.localpath(added[0]))
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5137
diff changeset
   145
2906
453097750fbf extdiff: fix bugs. add test.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2903
diff changeset
   146
        cmdline = ('%s %s %s %s' %
3074
be98c5ce4022 extdiff: do not shell-quote options to new commands
TK Soh <teekaysoh@yahoo.com>
parents: 2959
diff changeset
   147
                   (util.shellquote(diffcmd), ' '.join(diffopts),
2906
453097750fbf extdiff: fix bugs. add test.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2903
diff changeset
   148
                    util.shellquote(dir1), util.shellquote(dir2)))
6957
bd979854a388 i18n: mark strings for translation in extdiff extension
Martin Geisler <mg@daimi.au.dk>
parents: 6760
diff changeset
   149
        ui.debug(_('running %r in %s\n') % (cmdline, tmproot))
2906
453097750fbf extdiff: fix bugs. add test.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2903
diff changeset
   150
        util.system(cmdline, cwd=tmproot)
6103
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
   151
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
   152
        for copy_fn, working_fn, mtime in fns_and_mtime:
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
   153
            if os.path.getmtime(copy_fn) != mtime:
7599
7bf7c073375e lowercase ui.debug and assert output
Martin Geisler <mg@daimi.au.dk>
parents: 7570
diff changeset
   154
                ui.debug(_('file changed while diffing. '
6957
bd979854a388 i18n: mark strings for translation in extdiff extension
Martin Geisler <mg@daimi.au.dk>
parents: 6760
diff changeset
   155
                         'Overwriting: %s (src: %s)\n') % (working_fn, copy_fn))
6103
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
   156
                util.copyfile(copy_fn, working_fn)
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
   157
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   158
        return 1
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   159
    finally:
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   160
        ui.note(_('cleaning up temp directory\n'))
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   161
        shutil.rmtree(tmproot)
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   162
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   163
def extdiff(ui, repo, *pats, **opts):
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   164
    '''use external program to diff repository (or selected files)
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   165
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   166
    Show differences between revisions for the specified files, using
2906
453097750fbf extdiff: fix bugs. add test.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2903
diff changeset
   167
    an external program.  The default program used is diff, with
453097750fbf extdiff: fix bugs. add test.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2903
diff changeset
   168
    default options "-Npru".
453097750fbf extdiff: fix bugs. add test.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2903
diff changeset
   169
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   170
    To select a different program, use the -p option.  The program
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   171
    will be passed the names of two directories to compare.  To pass
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   172
    additional options to the program, use the -o option.  These will
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   173
    be passed before the names of the directories to compare.
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   174
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   175
    When two revision arguments are given, then changes are
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   176
    shown between those revisions. If only one revision is
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   177
    specified then that revision is compared to the working
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   178
    directory, and, when no revisions are specified, the
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   179
    working directory files are compared to its parent.'''
3129
f145d04899d2 extdiff: use the default option only if the default program is used
TK Soh <teekaysoh@yahoo.com>
parents: 3127
diff changeset
   180
    program = opts['program'] or 'diff'
f145d04899d2 extdiff: use the default option only if the default program is used
TK Soh <teekaysoh@yahoo.com>
parents: 3127
diff changeset
   181
    if opts['program']:
f145d04899d2 extdiff: use the default option only if the default program is used
TK Soh <teekaysoh@yahoo.com>
parents: 3127
diff changeset
   182
        option = opts['option']
f145d04899d2 extdiff: use the default option only if the default program is used
TK Soh <teekaysoh@yahoo.com>
parents: 3127
diff changeset
   183
    else:
f145d04899d2 extdiff: use the default option only if the default program is used
TK Soh <teekaysoh@yahoo.com>
parents: 3127
diff changeset
   184
        option = opts['option'] or ['-Npru']
f145d04899d2 extdiff: use the default option only if the default program is used
TK Soh <teekaysoh@yahoo.com>
parents: 3127
diff changeset
   185
    return dodiff(ui, repo, program, option, pats, opts)
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   186
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   187
cmdtable = {
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   188
    "extdiff":
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   189
    (extdiff,
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   190
     [('p', 'program', '', _('comparison program to run')),
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   191
      ('o', 'option', [], _('pass option to comparison program')),
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   192
      ('r', 'rev', [], _('revision')),
7758
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
   193
      ('c', 'change', '', _('change made by revision')),
5147
c80af96943aa refactor options from cmdtable
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 5143
diff changeset
   194
     ] + commands.walkopts,
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   195
     _('hg extdiff [OPT]... [FILE]...')),
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   196
    }
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   197
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   198
def uisetup(ui):
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   199
    for cmd, path in ui.configitems('extdiff'):
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   200
        if cmd.startswith('cmd.'):
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   201
            cmd = cmd[4:]
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   202
            if not path: path = cmd
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   203
            diffopts = ui.config('extdiff', 'opts.' + cmd, '')
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   204
            diffopts = diffopts and [diffopts] or []
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   205
        elif cmd.startswith('opts.'):
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   206
            continue
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   207
        else:
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   208
            # command = path opts
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   209
            if path:
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   210
                diffopts = shlex.split(path)
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   211
                path = diffopts.pop(0)
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   212
            else:
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
   213
                path, diffopts = cmd, []
2959
7f5fc4b347de extdiff: make new diff commands pick up their options correctly
TK Soh <teekaysoh@yahoo.com>
parents: 2913
diff changeset
   214
        def save(cmd, path, diffopts):
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   215
            '''use closure to save diff command to use'''
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   216
            def mydiff(ui, repo, *pats, **opts):
2906
453097750fbf extdiff: fix bugs. add test.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2903
diff changeset
   217
                return dodiff(ui, repo, path, diffopts, pats, opts)
5291
23651848d638 extdiff: avoid repr() doubling paths backslashes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 4730
diff changeset
   218
            mydiff.__doc__ = '''use %(path)s to diff repository (or selected files)
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   219
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   220
            Show differences between revisions for the specified
5291
23651848d638 extdiff: avoid repr() doubling paths backslashes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 4730
diff changeset
   221
            files, using the %(path)s program.
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   222
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   223
            When two revision arguments are given, then changes are
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   224
            shown between those revisions. If only one revision is
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   225
            specified then that revision is compared to the working
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   226
            directory, and, when no revisions are specified, the
2906
453097750fbf extdiff: fix bugs. add test.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2903
diff changeset
   227
            working directory files are compared to its parent.''' % {
5291
23651848d638 extdiff: avoid repr() doubling paths backslashes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 4730
diff changeset
   228
                'path': util.uirepr(path),
2906
453097750fbf extdiff: fix bugs. add test.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2903
diff changeset
   229
                }
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   230
            return mydiff
2959
7f5fc4b347de extdiff: make new diff commands pick up their options correctly
TK Soh <teekaysoh@yahoo.com>
parents: 2913
diff changeset
   231
        cmdtable[cmd] = (save(cmd, path, diffopts),
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   232
                         cmdtable['extdiff'][1][1:],
4730
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4096
diff changeset
   233
                         _('hg %s [OPTION]... [FILE]...') % cmd)