annotate hgext/extdiff.py @ 23680:4075f2f8ea53

extdiff: avoid unexpected quoting arguments for external tools (issue4463) Before this patch, all command line arguments for external tools are quoted by the combination of "shlex.split" and "util.shellquote". But this causes some problems. - some problematic commands can't work correctly with quoted arguments For example, 'WinMerge /r ....' is OK, but 'WinMerge "/r" ....' is NG. See also below for detail about this problem. https://bitbucket.org/tortoisehg/thg/issue/3978/ - quoting itself may change semantics of arguments For example, when the environment variable CONCAT="foo bar baz': - mydiff $CONCAT => mydiff foo bar baz (taking 3 arguments) - mydiff "$CONCAT" => mydiff "foo bar baz" (taking only 1 argument) For another example, single quoting (= "util.shellquote") on POSIX environment prevents shells from expanding environment variables, tilde, and so on: - mydiff "$HOME" => mydiff /home/foobar - mydiff '$HOME' => mydiff $HOME - "shlex.split" can't handle some special characters correctly It just splits specified command line by whitespaces. For example, "echo foo;echo bar" is split into ["echo", "foo;echo", "bar"]. On the other hand, if quoting itself is omitted, users can't specify options including space characters with "--option" at runtime. The root cause of this issue is that "shlex.split + util.shellquote" combination loses whether users really want to quote each command line elements or not, even though these can be quoted arbitrarily in configurations. To resolve this problem, this patch does: - prevent configurations from being processed by "shlex.split" and "util.shellquote" only (possibly) "findexe"-ed or "findexternaltool"-ed command path is "util.shellquote", because it may contain whitespaces. - quote options specified by "--option" via command line at runtime This patch also makes "dodiff()" take only one "args" argument instead of "diffcmd" and "diffopts. It also omits applying "util.shellquote" on "args", because "args" should be already stringified in "extdiff()" and "mydiff()". The last hunk for "test-extdiff.t" replaces two whitespaces by single whitespace, because change of "' '.join()" logic causes omitting redundant whitespaces.
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Thu, 25 Dec 2014 23:33:26 +0900
parents 41c03b7592ed
children 9476cb62298e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8076
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9956
diff changeset
6 # GNU General Public License version 2 or any later version.
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
7
8934
9dda4c73fc3b extensions: change descriptions for extensions providing a few commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8873
diff changeset
8 '''command to allow external programs to compare revisions
8873
e872ef2e6758 help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8866
diff changeset
9
9286
a8fdcec4ab34 doc: fix quotes mismatches affecting rst
Cédric Duval <cedricduval@free.fr>
parents: 9257
diff changeset
10 The extdiff Mercurial extension allows you to use external programs
9257
50ebe8845a1b extdiff: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9207
diff changeset
11 to compare revisions, or revision with working directory. The external
50ebe8845a1b extdiff: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9207
diff changeset
12 diff programs are called with a configurable set of options and two
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
13 non-option arguments: paths to directories containing snapshots of
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
14 files to compare.
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
15
14327
d943412e2fba extdiff: grammar "allows to" -> "allows one to"
Javi Merino <cibervicho@gmail.com>
parents: 14322
diff changeset
16 The extdiff extension also allows you to configure new diff commands, so
11191
c45a47bc4114 extdiff: fix reST syntax in module docstring
Martin Geisler <mg@lazybytes.net>
parents: 11184
diff changeset
17 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
18
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
19 [extdiff]
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
20 # 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
21 cdiff = gdiff -Nprc5
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
22 ## or the old way:
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
23 #cmd.cdiff = gdiff
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
24 #opts.cdiff = -Nprc5
3127
8e8deb8035a4 Update [extdiff] configuration sample for vimdiff,
Mathieu Clabaut <mathieu.clabaut@systerel.fr>
parents: 3090
diff changeset
25
23150
aff73c777b0b extdiff: allow a preconfigured merge-tool to be invoked
Matt Harbison <matt_harbison@yahoo.com>
parents: 23149
diff changeset
26 # add new command called meld, runs meld (no need to name twice). If
aff73c777b0b extdiff: allow a preconfigured merge-tool to be invoked
Matt Harbison <matt_harbison@yahoo.com>
parents: 23149
diff changeset
27 # the meld executable is not available, the meld tool in [merge-tools]
aff73c777b0b extdiff: allow a preconfigured merge-tool to be invoked
Matt Harbison <matt_harbison@yahoo.com>
parents: 23149
diff changeset
28 # will be used, if available
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
29 meld =
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
30
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
31 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
9257
50ebe8845a1b extdiff: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9207
diff changeset
32 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
50ebe8845a1b extdiff: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9207
diff changeset
33 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
34 # your .vimrc
16242
55174ab81973 extdiff: escape filenames with vim/DirDiff and make quoting work with Windows
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14739
diff changeset
35 vimdiff = gvim -f "+next" \\
55174ab81973 extdiff: escape filenames with vim/DirDiff and make quoting work with Windows
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14739
diff changeset
36 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
37
11191
c45a47bc4114 extdiff: fix reST syntax in module docstring
Martin Geisler <mg@lazybytes.net>
parents: 11184
diff changeset
38 Tool arguments can include variables that are expanded at runtime::
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
39
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
40 $parent1, $plabel1 - filename, descriptive label of first parent
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
41 $child, $clabel - filename, descriptive label of child revision
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
42 $parent2, $plabel2 - filename, descriptive label of second parent
14045
1c38777f7b8a extdiff: add repository root as a variable
Steven Stallion <sstallion@gmail.com>
parents: 14024
diff changeset
43 $root - repository root
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
44 $parent is an alias for $parent1.
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
45
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
46 The extdiff extension will look in your [diff-tools] and [merge-tools]
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
47 sections for diff tool arguments, when none are specified in [extdiff].
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
48
11191
c45a47bc4114 extdiff: fix reST syntax in module docstring
Martin Geisler <mg@lazybytes.net>
parents: 11184
diff changeset
49 ::
c45a47bc4114 extdiff: fix reST syntax in module docstring
Martin Geisler <mg@lazybytes.net>
parents: 11184
diff changeset
50
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
51 [extdiff]
11191
c45a47bc4114 extdiff: fix reST syntax in module docstring
Martin Geisler <mg@lazybytes.net>
parents: 11184
diff changeset
52 kdiff3 =
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
53
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
54 [diff-tools]
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
55 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
56
11191
c45a47bc4114 extdiff: fix reST syntax in module docstring
Martin Geisler <mg@lazybytes.net>
parents: 11184
diff changeset
57 You can use -I/-X and list of file or directory names like normal
c45a47bc4114 extdiff: fix reST syntax in module docstring
Martin Geisler <mg@lazybytes.net>
parents: 11184
diff changeset
58 :hg:`diff` command. The extdiff extension makes snapshots of only
c45a47bc4114 extdiff: fix reST syntax in module docstring
Martin Geisler <mg@lazybytes.net>
parents: 11184
diff changeset
59 needed files, so running the external diff program will actually be
c45a47bc4114 extdiff: fix reST syntax in module docstring
Martin Geisler <mg@lazybytes.net>
parents: 11184
diff changeset
60 pretty fast (at least faster than having to compare the entire tree).
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
61 '''
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
62
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
63 from mercurial.i18n import _
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
64 from mercurial.node import short, nullid
23150
aff73c777b0b extdiff: allow a preconfigured merge-tool to be invoked
Matt Harbison <matt_harbison@yahoo.com>
parents: 23149
diff changeset
65 from mercurial import cmdutil, scmutil, util, commands, encoding, filemerge
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
66 import os, shlex, shutil, tempfile, re
5135
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
67
21246
29eeaa6d662f extdiff: declare command using decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20674
diff changeset
68 cmdtable = {}
29eeaa6d662f extdiff: declare command using decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20674
diff changeset
69 command = cmdutil.command(cmdtable)
16743
38caf405d010 hgext: mark all first-party extensions as such
Augie Fackler <raf@durin42.com>
parents: 16686
diff changeset
70 testedwith = 'internal'
38caf405d010 hgext: mark all first-party extensions as such
Augie Fackler <raf@durin42.com>
parents: 16686
diff changeset
71
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
72 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
73 '''snapshot files as of some revision
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
74 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
75 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
76 dirname = os.path.basename(repo.root)
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
77 if dirname == "":
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
78 dirname = "root"
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
79 if node is not None:
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
80 dirname = '%s.%s' % (dirname, short(node))
5135
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
81 base = os.path.join(tmproot, dirname)
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
82 os.mkdir(base)
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
83 if node is not None:
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
84 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
85 (len(files), short(node)))
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
86 else:
8066
aece3c9e62f1 Merge with crew-stable
Patrick Mezard <pmezard@gmail.com>
parents: 8026 8065
diff changeset
87 ui.note(_('making snapshot of %d files from working directory\n') %
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
88 (len(files)))
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13878
diff changeset
89 wopener = scmutil.opener(base)
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
90 fns_and_mtime = []
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6603
diff changeset
91 ctx = repo[node]
23149
dc80a0ad7bf5 extdiff: sort files when snapshotting
Matt Mackall <mpm@selenic.com>
parents: 22202
diff changeset
92 for fn in sorted(files):
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6603
diff changeset
93 wfn = util.pconvert(fn)
16686
67964cda8701 cleanup: "not x in y" -> "x not in y"
Brodie Rao <brodie@sf.io>
parents: 16242
diff changeset
94 if wfn not in ctx:
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
95 # File doesn't exist; could be a bogus modify
5135
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
96 continue
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
97 ui.note(' %s\n' % wfn)
1830bc7676ee extdiff: un-nested two functions
Brad Schick <schickb@gmail.com>
parents: 4730
diff changeset
98 dest = os.path.join(base, wfn)
8065
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
99 fctx = ctx[wfn]
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
100 data = repo.wwritedata(wfn, fctx.data())
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
101 if 'l' in fctx.flags():
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
102 wopener.symlink(data, wfn)
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
103 else:
14168
135e244776f0 prevent transient leaks of file handle by using new helper functions
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14045
diff changeset
104 wopener.write(wfn, data)
8065
66d0a03d3afc extdiff: preserve execute-bit across copies (issue1562)
Patrick Mezard <pmezard@gmail.com>
parents: 8064
diff changeset
105 if 'x' in fctx.flags():
14232
df2399663392 rename util.set_flags to setflags
Adrian Buehlmann <adrian@cadifra.com>
parents: 14168
diff changeset
106 util.setflags(dest, False, True)
8064
5c7bc1aece9e extdiff: merge node and working dir snapshot modes
Patrick Mezard <pmezard@gmail.com>
parents: 7758
diff changeset
107 if node is None:
14021
3eb632d9cf42 extdiff: fix broken symlinks handling (issue1909)
Patrick Mezard <pmezard@gmail.com>
parents: 11321
diff changeset
108 fns_and_mtime.append((dest, repo.wjoin(fn),
3eb632d9cf42 extdiff: fix broken symlinks handling (issue1909)
Patrick Mezard <pmezard@gmail.com>
parents: 11321
diff changeset
109 os.lstat(dest).st_mtime))
6103
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
110 return dirname, fns_and_mtime
5143
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5137
diff changeset
111
23680
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
112 def dodiff(ui, repo, args, pats, opts):
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 16743
diff changeset
113 '''Do the actual diff:
6103
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
114
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
115 - 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
116 - 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
117 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
118 - 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
119 '''
7758
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
120
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
121 revs = opts.get('rev')
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
122 change = opts.get('change')
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
123 do3way = '$parent2' in args
7758
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
124
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
125 if revs and change:
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
126 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
127 raise util.Abort(msg)
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
128 elif change:
14319
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14232
diff changeset
129 node2 = scmutil.revsingle(repo, change, None).node()
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
130 node1a, node1b = repo.changelog.parents(node2)
7758
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
131 else:
14319
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14232
diff changeset
132 node1a, node2 = scmutil.revpair(repo, revs)
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
133 if not revs:
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 13758
diff changeset
134 node1b = repo.dirstate.p2()
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
135 else:
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
136 node1b = nullid
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
137
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
138 # Disable 3-way merge if there is only one parent
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
139 if do3way:
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
140 if node1b == nullid:
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
141 do3way = False
7758
e81e6c996e99 extdiff: add --change option to display single changeset diff
Gilles Moris <gilles.moris@free.fr>
parents: 7599
diff changeset
142
14671
35c2cc322ba8 scmutil: switch match users to supplying contexts
Matt Mackall <mpm@selenic.com>
parents: 14327
diff changeset
143 matcher = scmutil.match(repo[node2], pats, opts)
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
144 mod_a, add_a, rem_a = map(set, repo.status(node1a, node2, matcher)[:3])
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
145 if do3way:
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
146 mod_b, add_b, rem_b = map(set, repo.status(node1b, node2, matcher)[:3])
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
147 else:
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
148 mod_b, add_b, rem_b = set(), set(), set()
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
149 modadd = mod_a | add_a | mod_b | add_b
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
150 common = modadd | rem_a | rem_b
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
151 if not common:
10394
4612cded5176 fix coding style (reported by pylint)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
152 return 0
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
153
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
154 tmproot = tempfile.mkdtemp(prefix='extdiff.')
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
155 try:
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
156 # Always make a copy of node1a (and node1b, if applicable)
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
157 dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a)
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
158 dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot)[0]
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
159 rev1a = '@%d' % repo[node1a].rev()
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
160 if do3way:
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
161 dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b)
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
162 dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot)[0]
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
163 rev1b = '@%d' % repo[node1b].rev()
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
164 else:
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
165 dir1b = None
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
166 rev1b = ''
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
167
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
168 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
169
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
170 # If node2 in not the wc or there is >1 change, copy it
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
171 dir2root = ''
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
172 rev2 = ''
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
173 if node2:
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
174 dir2 = snapshot(ui, repo, modadd, node2, tmproot)[0]
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
175 rev2 = '@%d' % repo[node2].rev()
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
176 elif len(common) > 1:
9945
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
177 #we only actually need to get the files to copy back to
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
178 #the working dir in this case (because the other cases
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
179 #are: diffing 2 revisions or single file -- in which case
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
180 #the file is already directly passed to the diff tool).
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
181 dir2, fns_and_mtime = snapshot(ui, repo, modadd, None, tmproot)
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
182 else:
5137
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
183 # 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
184 dir2 = ''
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
185 dir2root = repo.root
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
186
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
187 label1a = rev1a
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
188 label1b = rev1b
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
189 label2 = rev2
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
190
5137
2be225ea5722 extdiff: do single file diffs from the wc with no copy
Brad Schick <schickb@gmail.com>
parents: 5136
diff changeset
191 # If only one change, diff the files instead of the directories
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
192 # Handle bogus modifies correctly by checking if the files exist
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
193 if len(common) == 1:
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
194 common_file = util.localpath(common.pop())
13758
5c0e1222e7c0 extdiff: use absolute paths for any temporary files
jfh <jason@jasonfharris.com>
parents: 13660
diff changeset
195 dir1a = os.path.join(tmproot, dir1a, common_file)
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
196 label1a = common_file + rev1a
13758
5c0e1222e7c0 extdiff: use absolute paths for any temporary files
jfh <jason@jasonfharris.com>
parents: 13660
diff changeset
197 if not os.path.isfile(dir1a):
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
198 dir1a = os.devnull
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
199 if do3way:
13758
5c0e1222e7c0 extdiff: use absolute paths for any temporary files
jfh <jason@jasonfharris.com>
parents: 13660
diff changeset
200 dir1b = os.path.join(tmproot, dir1b, common_file)
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
201 label1b = common_file + rev1b
13758
5c0e1222e7c0 extdiff: use absolute paths for any temporary files
jfh <jason@jasonfharris.com>
parents: 13660
diff changeset
202 if not os.path.isfile(dir1b):
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
203 dir1b = os.devnull
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
204 dir2 = os.path.join(dir2root, dir2, common_file)
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
205 label2 = common_file + rev2
5143
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5137
diff changeset
206
9945
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
207 # Function to quote file/dir names in the argument string.
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
208 # When not operating in 3-way mode, an empty string is
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
209 # returned for parent2
20674
2aafd5854243 extdiff: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents: 17773
diff changeset
210 replace = {'parent': dir1a, 'parent1': dir1a, 'parent2': dir1b,
2aafd5854243 extdiff: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents: 17773
diff changeset
211 'plabel1': label1a, 'plabel2': label1b,
2aafd5854243 extdiff: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents: 17773
diff changeset
212 'clabel': label2, 'child': dir2,
2aafd5854243 extdiff: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents: 17773
diff changeset
213 'root': repo.root}
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
214 def quote(match):
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
215 key = match.group()[1:]
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
216 if not do3way and key == 'parent2':
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
217 return ''
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
218 return util.shellquote(replace[key])
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
219
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
220 # Match parent2 first, so 'parent1?' will match both parent1 and parent
14045
1c38777f7b8a extdiff: add repository root as a variable
Steven Stallion <sstallion@gmail.com>
parents: 14024
diff changeset
221 regex = '\$(parent2|parent1?|child|plabel1|plabel2|clabel|root)'
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
222 if not do3way and not re.search(regex, args):
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
223 args += ' $parent1 $child'
23680
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
224 cmdline = re.sub(regex, quote, args)
9512
e7bde4680eec extdiff: add 3-way diff for merge changesets
Sune Foldager <cryo@cyanite.org>
parents: 9467
diff changeset
225
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9286
diff changeset
226 ui.debug('running %r in %s\n' % (cmdline, tmproot))
23270
41c03b7592ed util.system: use ui.system() in place of optional ui.fout parameter
Yuya Nishihara <yuya@tcha.org>
parents: 23152
diff changeset
227 ui.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
228
e668fd796b8b Propagating changes back to working dirs when changing files in external
Fabio Zadrozny <fabiofz at gmail dot com>
parents: 5293
diff changeset
229 for copy_fn, working_fn, mtime in fns_and_mtime:
14021
3eb632d9cf42 extdiff: fix broken symlinks handling (issue1909)
Patrick Mezard <pmezard@gmail.com>
parents: 11321
diff changeset
230 if os.lstat(copy_fn).st_mtime != mtime:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9286
diff changeset
231 ui.debug('file changed while diffing. '
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9286
diff changeset
232 '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
233 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
234
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
235 return 1
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
236 finally:
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
237 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
238 shutil.rmtree(tmproot)
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
239
21246
29eeaa6d662f extdiff: declare command using decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20674
diff changeset
240 @command('extdiff',
29eeaa6d662f extdiff: declare command using decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20674
diff changeset
241 [('p', 'program', '',
29eeaa6d662f extdiff: declare command using decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20674
diff changeset
242 _('comparison program to run'), _('CMD')),
29eeaa6d662f extdiff: declare command using decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20674
diff changeset
243 ('o', 'option', [],
29eeaa6d662f extdiff: declare command using decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20674
diff changeset
244 _('pass option to comparison program'), _('OPT')),
29eeaa6d662f extdiff: declare command using decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20674
diff changeset
245 ('r', 'rev', [], _('revision'), _('REV')),
29eeaa6d662f extdiff: declare command using decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20674
diff changeset
246 ('c', 'change', '', _('change made by revision'), _('REV')),
29eeaa6d662f extdiff: declare command using decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20674
diff changeset
247 ] + commands.walkopts,
21781
f0c3b95af47f extdiff: define inferrepo in command decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21246
diff changeset
248 _('hg extdiff [OPT]... [FILE]...'),
f0c3b95af47f extdiff: define inferrepo in command decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21246
diff changeset
249 inferrepo=True)
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
250 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
251 '''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
252
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
253 Show differences between revisions for the specified files, using
7983
7b813bdbd5d0 Change double spaces to single spaces in help texts.
Martin Geisler <mg@daimi.au.dk>
parents: 7758
diff changeset
254 an external program. The default program used is diff, with
2906
453097750fbf extdiff: fix bugs. add test.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2903
diff changeset
255 default options "-Npru".
453097750fbf extdiff: fix bugs. add test.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2903
diff changeset
256
8076
5ec526c1a32f help texts: write command line switches as -a/--abc
Martin Geisler <mg@lazybytes.net>
parents: 8066
diff changeset
257 To select a different program, use the -p/--program option. The
5ec526c1a32f help texts: write command line switches as -a/--abc
Martin Geisler <mg@lazybytes.net>
parents: 8066
diff changeset
258 program will be passed the names of two directories to compare. To
5ec526c1a32f help texts: write command line switches as -a/--abc
Martin Geisler <mg@lazybytes.net>
parents: 8066
diff changeset
259 pass additional options to the program, use -o/--option. These
5ec526c1a32f help texts: write command line switches as -a/--abc
Martin Geisler <mg@lazybytes.net>
parents: 8066
diff changeset
260 will be passed before the names of the directories to compare.
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
261
7990
cdb848e8c4b5 extdiff: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
262 When two revision arguments are given, then changes are shown
cdb848e8c4b5 extdiff: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
263 between those revisions. If only one revision is specified then
cdb848e8c4b5 extdiff: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
264 that revision is compared to the working directory, and, when no
cdb848e8c4b5 extdiff: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
265 revisions are specified, the working directory files are compared
cdb848e8c4b5 extdiff: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
266 to its parent.'''
9519
0d3c1aa9d5de extdiff: fix defaulting to "diff" if no --program is given
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8934
diff changeset
267 program = opts.get('program')
0d3c1aa9d5de extdiff: fix defaulting to "diff" if no --program is given
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8934
diff changeset
268 option = opts.get('option')
0d3c1aa9d5de extdiff: fix defaulting to "diff" if no --program is given
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8934
diff changeset
269 if not program:
0d3c1aa9d5de extdiff: fix defaulting to "diff" if no --program is given
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8934
diff changeset
270 program = 'diff'
0d3c1aa9d5de extdiff: fix defaulting to "diff" if no --program is given
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8934
diff changeset
271 option = option or ['-Npru']
23680
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
272 cmdline = ' '.join(map(util.shellquote, [program] + option))
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
273 return dodiff(ui, repo, cmdline, pats, opts)
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
274
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
275 def uisetup(ui):
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
276 for cmd, path in ui.configitems('extdiff'):
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
277 if cmd.startswith('cmd.'):
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
278 cmd = cmd[4:]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
279 if not path:
23150
aff73c777b0b extdiff: allow a preconfigured merge-tool to be invoked
Matt Harbison <matt_harbison@yahoo.com>
parents: 23149
diff changeset
280 path = util.findexe(cmd)
aff73c777b0b extdiff: allow a preconfigured merge-tool to be invoked
Matt Harbison <matt_harbison@yahoo.com>
parents: 23149
diff changeset
281 if path is None:
aff73c777b0b extdiff: allow a preconfigured merge-tool to be invoked
Matt Harbison <matt_harbison@yahoo.com>
parents: 23149
diff changeset
282 path = filemerge.findexternaltool(ui, cmd) or cmd
23680
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
283 diffopts = ui.config('extdiff', 'opts.' + cmd, '')
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
284 cmdline = util.shellquote(path)
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
285 if diffopts:
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
286 cmdline += ' ' + diffopts
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
287 elif cmd.startswith('opts.'):
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
288 continue
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
289 else:
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
290 if path:
23680
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
291 # case "cmd = path opts"
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
292 cmdline = path
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
293 diffopts = len(shlex.split(cmdline)) > 1
5245
a1efa71f3ece Improve extdiff configuration.
Brendan Cully <brendan@kublai.com>
parents: 5147
diff changeset
294 else:
23680
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
295 # case "cmd ="
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
296 path = util.findexe(cmd)
23150
aff73c777b0b extdiff: allow a preconfigured merge-tool to be invoked
Matt Harbison <matt_harbison@yahoo.com>
parents: 23149
diff changeset
297 if path is None:
aff73c777b0b extdiff: allow a preconfigured merge-tool to be invoked
Matt Harbison <matt_harbison@yahoo.com>
parents: 23149
diff changeset
298 path = filemerge.findexternaltool(ui, cmd) or cmd
23680
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
299 cmdline = util.shellquote(path)
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
300 diffopts = False
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
301 # look for diff arguments in [diff-tools] then [merge-tools]
23680
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
302 if not diffopts:
11184
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
303 args = ui.config('diff-tools', cmd+'.diffargs') or \
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
304 ui.config('merge-tools', cmd+'.diffargs')
7d99edddbaea extdiff: add labels, read diff arguments from [merge-tools]
Steve Borho <steve@borho.org>
parents: 10394
diff changeset
305 if args:
23680
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
306 cmdline += ' ' + args
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
307 def save(cmdline):
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
308 '''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
309 def mydiff(ui, repo, *pats, **opts):
23680
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
310 options = ' '.join(map(util.shellquote, opts['option']))
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
311 if options:
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
312 options = ' ' + options
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
313 return dodiff(ui, repo, cmdline + options, pats, opts)
9941
11d7ee94b56a extdiff: prevent exception on double-translation
Martin Geisler <mg@lazybytes.net>
parents: 9523
diff changeset
314 doc = _('''\
9050
77324df822e2 extdiff: fix indentation and use gettext
Martin Geisler <mg@lazybytes.net>
parents: 8934
diff changeset
315 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
316
9945
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
317 Show differences between revisions for the specified files, using
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
318 the %(path)s program.
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
319
9945
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
320 When two revision arguments are given, then changes are shown
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
321 between those revisions. If only one revision is specified then
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
322 that revision is compared to the working directory, and, when no
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
323 revisions are specified, the working directory files are compared
5e4ef56b4d42 extdiff: wrap long lines in docstring and comments
Martin Geisler <mg@lazybytes.net>
parents: 9941
diff changeset
324 to its parent.\
20674
2aafd5854243 extdiff: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents: 17773
diff changeset
325 ''') % {'path': util.uirepr(path)}
9941
11d7ee94b56a extdiff: prevent exception on double-translation
Martin Geisler <mg@lazybytes.net>
parents: 9523
diff changeset
326
11d7ee94b56a extdiff: prevent exception on double-translation
Martin Geisler <mg@lazybytes.net>
parents: 9523
diff changeset
327 # We must translate the docstring right away since it is
11d7ee94b56a extdiff: prevent exception on double-translation
Martin Geisler <mg@lazybytes.net>
parents: 9523
diff changeset
328 # used as a format string. The string will unfortunately
11d7ee94b56a extdiff: prevent exception on double-translation
Martin Geisler <mg@lazybytes.net>
parents: 9523
diff changeset
329 # be translated again in commands.helpcmd and this will
11d7ee94b56a extdiff: prevent exception on double-translation
Martin Geisler <mg@lazybytes.net>
parents: 9523
diff changeset
330 # fail when the docstring contains non-ASCII characters.
11d7ee94b56a extdiff: prevent exception on double-translation
Martin Geisler <mg@lazybytes.net>
parents: 9523
diff changeset
331 # Decoding the string to a Unicode string here (using the
11d7ee94b56a extdiff: prevent exception on double-translation
Martin Geisler <mg@lazybytes.net>
parents: 9523
diff changeset
332 # right encoding) prevents that.
11d7ee94b56a extdiff: prevent exception on double-translation
Martin Geisler <mg@lazybytes.net>
parents: 9523
diff changeset
333 mydiff.__doc__ = doc.decode(encoding.encoding)
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
334 return mydiff
23680
4075f2f8ea53 extdiff: avoid unexpected quoting arguments for external tools (issue4463)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23270
diff changeset
335 cmdtable[cmd] = (save(cmdline),
2333
de0c05afa511 new extension: extdiff. allows to use external diff program.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
336 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
337 _('hg %s [OPTION]... [FILE]...') % cmd)