144 do3way = False |
144 do3way = False |
145 |
145 |
146 subrepos=opts.get('subrepos') |
146 subrepos=opts.get('subrepos') |
147 |
147 |
148 matcher = scmutil.match(repo[node2], pats, opts) |
148 matcher = scmutil.match(repo[node2], pats, opts) |
149 mod_a, add_a, rem_a = map(set, repo.status(node1a, node2, matcher, |
149 |
150 listsubrepos=subrepos)[:3]) |
150 if True: |
151 if do3way: |
151 mod_a, add_a, rem_a = map(set, repo.status(node1a, node2, matcher, |
152 mod_b, add_b, rem_b = map(set, repo.status(node1b, node2, matcher, |
|
153 listsubrepos=subrepos)[:3]) |
152 listsubrepos=subrepos)[:3]) |
154 else: |
153 if do3way: |
155 mod_b, add_b, rem_b = set(), set(), set() |
154 mod_b, add_b, rem_b = map(set, |
156 modadd = mod_a | add_a | mod_b | add_b |
155 repo.status(node1b, node2, matcher, |
157 common = modadd | rem_a | rem_b |
156 listsubrepos=subrepos)[:3]) |
158 if not common: |
157 else: |
159 return 0 |
158 mod_b, add_b, rem_b = set(), set(), set() |
|
159 modadd = mod_a | add_a | mod_b | add_b |
|
160 common = modadd | rem_a | rem_b |
|
161 if not common: |
|
162 return 0 |
160 |
163 |
161 tmproot = tempfile.mkdtemp(prefix='extdiff.') |
164 tmproot = tempfile.mkdtemp(prefix='extdiff.') |
162 try: |
165 try: |
163 # Always make a copy of node1a (and node1b, if applicable) |
166 if True: |
164 dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a) |
167 # Always make a copy of node1a (and node1b, if applicable) |
165 dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot, subrepos)[0] |
168 dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a) |
166 rev1a = '@%d' % repo[node1a].rev() |
169 dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot, |
167 if do3way: |
|
168 dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b) |
|
169 dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot, |
|
170 subrepos)[0] |
170 subrepos)[0] |
171 rev1b = '@%d' % repo[node1b].rev() |
171 rev1a = '@%d' % repo[node1a].rev() |
172 else: |
|
173 dir1b = None |
|
174 rev1b = '' |
|
175 |
|
176 fns_and_mtime = [] |
|
177 |
|
178 # If node2 in not the wc or there is >1 change, copy it |
|
179 dir2root = '' |
|
180 rev2 = '' |
|
181 if node2: |
|
182 dir2 = snapshot(ui, repo, modadd, node2, tmproot, subrepos)[0] |
|
183 rev2 = '@%d' % repo[node2].rev() |
|
184 elif len(common) > 1: |
|
185 #we only actually need to get the files to copy back to |
|
186 #the working dir in this case (because the other cases |
|
187 #are: diffing 2 revisions or single file -- in which case |
|
188 #the file is already directly passed to the diff tool). |
|
189 dir2, fns_and_mtime = snapshot(ui, repo, modadd, None, tmproot, |
|
190 subrepos) |
|
191 else: |
|
192 # This lets the diff tool open the changed file directly |
|
193 dir2 = '' |
|
194 dir2root = repo.root |
|
195 |
|
196 label1a = rev1a |
|
197 label1b = rev1b |
|
198 label2 = rev2 |
|
199 |
|
200 # If only one change, diff the files instead of the directories |
|
201 # Handle bogus modifies correctly by checking if the files exist |
|
202 if len(common) == 1: |
|
203 common_file = util.localpath(common.pop()) |
|
204 dir1a = os.path.join(tmproot, dir1a, common_file) |
|
205 label1a = common_file + rev1a |
|
206 if not os.path.isfile(dir1a): |
|
207 dir1a = os.devnull |
|
208 if do3way: |
172 if do3way: |
209 dir1b = os.path.join(tmproot, dir1b, common_file) |
173 dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b) |
210 label1b = common_file + rev1b |
174 dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot, |
211 if not os.path.isfile(dir1b): |
175 subrepos)[0] |
212 dir1b = os.devnull |
176 rev1b = '@%d' % repo[node1b].rev() |
213 dir2 = os.path.join(dir2root, dir2, common_file) |
177 else: |
214 label2 = common_file + rev2 |
178 dir1b = None |
|
179 rev1b = '' |
|
180 |
|
181 fns_and_mtime = [] |
|
182 |
|
183 # If node2 in not the wc or there is >1 change, copy it |
|
184 dir2root = '' |
|
185 rev2 = '' |
|
186 if node2: |
|
187 dir2 = snapshot(ui, repo, modadd, node2, tmproot, subrepos)[0] |
|
188 rev2 = '@%d' % repo[node2].rev() |
|
189 elif len(common) > 1: |
|
190 #we only actually need to get the files to copy back to |
|
191 #the working dir in this case (because the other cases |
|
192 #are: diffing 2 revisions or single file -- in which case |
|
193 #the file is already directly passed to the diff tool). |
|
194 dir2, fns_and_mtime = snapshot(ui, repo, modadd, None, tmproot, |
|
195 subrepos) |
|
196 else: |
|
197 # This lets the diff tool open the changed file directly |
|
198 dir2 = '' |
|
199 dir2root = repo.root |
|
200 |
|
201 label1a = rev1a |
|
202 label1b = rev1b |
|
203 label2 = rev2 |
|
204 |
|
205 # If only one change, diff the files instead of the directories |
|
206 # Handle bogus modifies correctly by checking if the files exist |
|
207 if len(common) == 1: |
|
208 common_file = util.localpath(common.pop()) |
|
209 dir1a = os.path.join(tmproot, dir1a, common_file) |
|
210 label1a = common_file + rev1a |
|
211 if not os.path.isfile(dir1a): |
|
212 dir1a = os.devnull |
|
213 if do3way: |
|
214 dir1b = os.path.join(tmproot, dir1b, common_file) |
|
215 label1b = common_file + rev1b |
|
216 if not os.path.isfile(dir1b): |
|
217 dir1b = os.devnull |
|
218 dir2 = os.path.join(dir2root, dir2, common_file) |
|
219 label2 = common_file + rev2 |
215 |
220 |
216 # Function to quote file/dir names in the argument string. |
221 # Function to quote file/dir names in the argument string. |
217 # When not operating in 3-way mode, an empty string is |
222 # When not operating in 3-way mode, an empty string is |
218 # returned for parent2 |
223 # returned for parent2 |
219 replace = {'parent': dir1a, 'parent1': dir1a, 'parent2': dir1b, |
224 replace = {'parent': dir1a, 'parent1': dir1a, 'parent2': dir1b, |