comparison hgext/extdiff.py @ 25813:18bae5eb58c5

extdiff: add support for subrepos Git and svn subrepo support is incomplete, because they don't support archiving the working copy.
author Matt Harbison <matt_harbison@yahoo.com>
date Sun, 15 Jul 2012 12:43:10 -0400
parents 68822b7cdd01
children 415709a43e54
comparison
equal deleted inserted replaced
25812:68822b7cdd01 25813:18bae5eb58c5
72 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should 72 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
73 # be specifying the version(s) of Mercurial they are tested with, or 73 # be specifying the version(s) of Mercurial they are tested with, or
74 # leave the attribute unspecified. 74 # leave the attribute unspecified.
75 testedwith = 'internal' 75 testedwith = 'internal'
76 76
77 def snapshot(ui, repo, files, node, tmproot): 77 def snapshot(ui, repo, files, node, tmproot, listsubrepos):
78 '''snapshot files as of some revision 78 '''snapshot files as of some revision
79 if not using snapshot, -I/-X does not work and recursive diff 79 if not using snapshot, -I/-X does not work and recursive diff
80 in tools like kdiff3 and meld displays too many files.''' 80 in tools like kdiff3 and meld displays too many files.'''
81 dirname = os.path.basename(repo.root) 81 dirname = os.path.basename(repo.root)
82 if dirname == "": 82 if dirname == "":
96 96
97 if files: 97 if files:
98 repo.ui.setconfig("ui", "archivemeta", False) 98 repo.ui.setconfig("ui", "archivemeta", False)
99 99
100 archival.archive(repo, base, node, 'files', 100 archival.archive(repo, base, node, 'files',
101 matchfn=scmutil.matchfiles(repo, files)) 101 matchfn=scmutil.matchfiles(repo, files),
102 subrepos=listsubrepos)
102 103
103 ctx = repo[node] 104 ctx = repo[node]
104 for fn in sorted(files): 105 for fn in sorted(files):
105 wfn = util.pconvert(fn) 106 wfn = util.pconvert(fn)
106 if wfn not in ctx: 107 if wfn not in ctx:
144 # Disable 3-way merge if there is only one parent 145 # Disable 3-way merge if there is only one parent
145 if do3way: 146 if do3way:
146 if node1b == nullid: 147 if node1b == nullid:
147 do3way = False 148 do3way = False
148 149
150 subrepos=opts.get('subrepos')
151
149 matcher = scmutil.match(repo[node2], pats, opts) 152 matcher = scmutil.match(repo[node2], pats, opts)
150 mod_a, add_a, rem_a = map(set, repo.status(node1a, node2, matcher)[:3]) 153 mod_a, add_a, rem_a = map(set, repo.status(node1a, node2, matcher,
154 listsubrepos=subrepos)[:3])
151 if do3way: 155 if do3way:
152 mod_b, add_b, rem_b = map(set, repo.status(node1b, node2, matcher)[:3]) 156 mod_b, add_b, rem_b = map(set, repo.status(node1b, node2, matcher,
157 listsubrepos=subrepos)[:3])
153 else: 158 else:
154 mod_b, add_b, rem_b = set(), set(), set() 159 mod_b, add_b, rem_b = set(), set(), set()
155 modadd = mod_a | add_a | mod_b | add_b 160 modadd = mod_a | add_a | mod_b | add_b
156 common = modadd | rem_a | rem_b 161 common = modadd | rem_a | rem_b
157 if not common: 162 if not common:
159 164
160 tmproot = tempfile.mkdtemp(prefix='extdiff.') 165 tmproot = tempfile.mkdtemp(prefix='extdiff.')
161 try: 166 try:
162 # Always make a copy of node1a (and node1b, if applicable) 167 # Always make a copy of node1a (and node1b, if applicable)
163 dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a) 168 dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a)
164 dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot)[0] 169 dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot, subrepos)[0]
165 rev1a = '@%d' % repo[node1a].rev() 170 rev1a = '@%d' % repo[node1a].rev()
166 if do3way: 171 if do3way:
167 dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b) 172 dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b)
168 dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot)[0] 173 dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot,
174 subrepos)[0]
169 rev1b = '@%d' % repo[node1b].rev() 175 rev1b = '@%d' % repo[node1b].rev()
170 else: 176 else:
171 dir1b = None 177 dir1b = None
172 rev1b = '' 178 rev1b = ''
173 179
175 181
176 # If node2 in not the wc or there is >1 change, copy it 182 # If node2 in not the wc or there is >1 change, copy it
177 dir2root = '' 183 dir2root = ''
178 rev2 = '' 184 rev2 = ''
179 if node2: 185 if node2:
180 dir2 = snapshot(ui, repo, modadd, node2, tmproot)[0] 186 dir2 = snapshot(ui, repo, modadd, node2, tmproot, subrepos)[0]
181 rev2 = '@%d' % repo[node2].rev() 187 rev2 = '@%d' % repo[node2].rev()
182 elif len(common) > 1: 188 elif len(common) > 1:
183 #we only actually need to get the files to copy back to 189 #we only actually need to get the files to copy back to
184 #the working dir in this case (because the other cases 190 #the working dir in this case (because the other cases
185 #are: diffing 2 revisions or single file -- in which case 191 #are: diffing 2 revisions or single file -- in which case
186 #the file is already directly passed to the diff tool). 192 #the file is already directly passed to the diff tool).
187 dir2, fns_and_mtime = snapshot(ui, repo, modadd, None, tmproot) 193 dir2, fns_and_mtime = snapshot(ui, repo, modadd, None, tmproot,
194 subrepos)
188 else: 195 else:
189 # This lets the diff tool open the changed file directly 196 # This lets the diff tool open the changed file directly
190 dir2 = '' 197 dir2 = ''
191 dir2root = repo.root 198 dir2root = repo.root
192 199
250 _('comparison program to run'), _('CMD')), 257 _('comparison program to run'), _('CMD')),
251 ('o', 'option', [], 258 ('o', 'option', [],
252 _('pass option to comparison program'), _('OPT')), 259 _('pass option to comparison program'), _('OPT')),
253 ('r', 'rev', [], _('revision'), _('REV')), 260 ('r', 'rev', [], _('revision'), _('REV')),
254 ('c', 'change', '', _('change made by revision'), _('REV')), 261 ('c', 'change', '', _('change made by revision'), _('REV')),
255 ] + commands.walkopts, 262 ] + commands.walkopts + commands.subrepoopts,
256 _('hg extdiff [OPT]... [FILE]...'), 263 _('hg extdiff [OPT]... [FILE]...'),
257 inferrepo=True) 264 inferrepo=True)
258 def extdiff(ui, repo, *pats, **opts): 265 def extdiff(ui, repo, *pats, **opts):
259 '''use external program to diff repository (or selected files) 266 '''use external program to diff repository (or selected files)
260 267