comparison mercurial/merge.py @ 3006:87a0332ab58b

merge: combine merge and get lists
author Matt Mackall <mpm@selenic.com>
date Tue, 22 Aug 2006 18:06:17 -0500
parents c67920d78248
children 962b9c7df641
comparison
equal deleted inserted replaced
3005:c67920d78248 3006:87a0332ab58b
108 repo.ui.debug(_(" overwrite %s branchmerge %s partial %s linear %s\n") % 108 repo.ui.debug(_(" overwrite %s branchmerge %s partial %s linear %s\n") %
109 (overwrite, branchmerge, bool(partial), linear_path)) 109 (overwrite, branchmerge, bool(partial), linear_path))
110 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % 110 repo.ui.debug(_(" ancestor %s local %s remote %s\n") %
111 (short(man), short(m1n), short(m2n))) 111 (short(man), short(m1n), short(m2n)))
112 112
113 merge = {} 113 action = {}
114 get = {}
115 remove = [] 114 remove = []
116 forget = [] 115 forget = []
117 116
118 # update m1 from working dir 117 # update m1 from working dir
119 umap = dict.fromkeys(unknown) 118 umap = dict.fromkeys(unknown)
148 if n != m2[f]: 147 if n != m2[f]:
149 a = ma.get(f, nullid) 148 a = ma.get(f, nullid)
150 # are both different from the ancestor? 149 # are both different from the ancestor?
151 if not overwrite and n != a and m2[f] != a: 150 if not overwrite and n != a and m2[f] != a:
152 repo.ui.debug(_(" %s versions differ, resolve\n") % f) 151 repo.ui.debug(_(" %s versions differ, resolve\n") % f)
153 merge[f] = (fmerge(f, m1, m2, ma), n[:20], m2[f]) 152 action[f] = (fmerge(f, m1, m2, ma), n[:20], m2[f])
154 queued = 1 153 queued = 1
155 # are we clobbering? 154 # are we clobbering?
156 # is remote's version newer? 155 # is remote's version newer?
157 # or are we going back in time and clean? 156 # or are we going back in time and clean?
158 elif overwrite or m2[f] != a or (backwards and not n[20:]): 157 elif overwrite or m2[f] != a or (backwards and not n[20:]):
159 repo.ui.debug(_(" remote %s is newer, get\n") % f) 158 repo.ui.debug(_(" remote %s is newer, get\n") % f)
160 get[f] = (m2.execf(f), m2[f]) 159 action[f] = (m2.execf(f), m2[f], None)
161 queued = 1 160 queued = 1
162 elif f in umap or f in added: 161 elif f in umap or f in added:
163 # this unknown file is the same as the checkout 162 # this unknown file is the same as the checkout
164 # we need to reset the dirstate if the file was added 163 # we need to reset the dirstate if the file was added
165 get[f] = (m2.execf(f), m2[f]) 164 action[f] = (m2.execf(f), m2[f], None)
166 165
167 # do we still need to look at mode bits? 166 # do we still need to look at mode bits?
168 if not queued and m1.execf(f) != m2.execf(f): 167 if not queued and m1.execf(f) != m2.execf(f):
169 if overwrite: 168 if overwrite:
170 repo.ui.debug(_(" updating permissions for %s\n") % f) 169 repo.ui.debug(_(" updating permissions for %s\n") % f)
209 if not overwrite: 208 if not overwrite:
210 r = repo.ui.prompt( 209 r = repo.ui.prompt(
211 (_("remote changed %s which local deleted\n") % f) + 210 (_("remote changed %s which local deleted\n") % f) +
212 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) 211 _("(k)eep or (d)elete?"), _("[kd]"), _("k"))
213 if r == _("k"): 212 if r == _("k"):
214 get[f] = (m2.execf(f), n) 213 action[f] = (m2.execf(f), n, None)
215 elif f not in ma: 214 elif f not in ma:
216 repo.ui.debug(_("remote created %s\n") % f) 215 repo.ui.debug(_("remote created %s\n") % f)
217 get[f] = (m2.execf(f), n) 216 action[f] = (m2.execf(f), n, None)
218 else: 217 else:
219 if overwrite or backwards: 218 if overwrite or backwards:
220 repo.ui.debug(_("local deleted %s, recreating\n") % f) 219 repo.ui.debug(_("local deleted %s, recreating\n") % f)
221 get[f] = (m2.execf(f), n) 220 action[f] = (m2.execf(f), n, None)
222 else: 221 else:
223 repo.ui.debug(_("local deleted %s\n") % f) 222 repo.ui.debug(_("local deleted %s\n") % f)
224 223
225 del m1, m2, ma 224 del m1, m2, ma
226 225
235 if p2 == nullid: xxp2 = '' 234 if p2 == nullid: xxp2 = ''
236 else: xxp2 = xp2 235 else: xxp2 = xp2
237 236
238 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xxp2) 237 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xxp2)
239 238
240 # get the files we don't need to change 239 # update files
241 files = get.keys() 240 unresolved = []
241 updated = 0
242 merged = 0
243 files = action.keys()
242 files.sort() 244 files.sort()
243 for f in files: 245 for f in files:
244 flag, node = get[f] 246 flag, my, other = action[f]
245 if f[0] == "/": 247 if f[0] == "/":
246 continue 248 continue
247 repo.ui.note(_("getting %s\n") % f) 249 if other:
248 t = repo.file(f).read(node) 250 repo.ui.status(_("merging %s\n") % f)
249 repo.wwrite(f, t) 251 if merge3(repo, f, my, other, xp1, xp2):
250 util.set_exec(repo.wjoin(f), flag) 252 unresolved.append(f)
251 253 merged += 1
252 # merge the tricky bits 254 else:
253 unresolved = [] 255 repo.ui.note(_("getting %s\n") % f)
254 files = merge.keys() 256 t = repo.file(f).read(my)
255 files.sort() 257 repo.wwrite(f, t)
256 for f in files: 258 updated += 1
257 repo.ui.status(_("merging %s\n") % f)
258 flag, my, other = merge[f]
259 ret = merge3(repo, f, my, other, xp1, xp2)
260 if ret:
261 unresolved.append(f)
262 util.set_exec(repo.wjoin(f), flag) 259 util.set_exec(repo.wjoin(f), flag)
263 260
264 remove.sort() 261 remove.sort()
265 for f in remove: 262 for f in remove:
266 repo.ui.note(_("removing %s\n") % f) 263 repo.ui.note(_("removing %s\n") % f)
279 if branchmerge: 276 if branchmerge:
280 repo.dirstate.update(remove, 'r') 277 repo.dirstate.update(remove, 'r')
281 else: 278 else:
282 repo.dirstate.forget(remove) 279 repo.dirstate.forget(remove)
283 280
284 files = get.keys() 281 files = action.keys()
285 files.sort() 282 files.sort()
286 for f in files: 283 for f in files:
287 if branchmerge: 284 flag, my, other = action[f]
288 repo.dirstate.update([f], 'n', st_mtime=-1) 285 if not other:
286 if branchmerge:
287 repo.dirstate.update([f], 'n', st_mtime=-1)
288 else:
289 repo.dirstate.update([f], 'n')
289 else: 290 else:
290 repo.dirstate.update([f], 'n') 291 if branchmerge:
291 292 # We've done a branch merge, mark this file as merged
292 files = merge.keys() 293 # so that we properly record the merger later
293 files.sort() 294 repo.dirstate.update([f], 'm')
294 for f in files: 295 else:
295 if branchmerge: 296 # We've update-merged a locally modified file, so
296 # We've done a branch merge, mark this file as merged 297 # we set the dirstate to emulate a normal checkout
297 # so that we properly record the merger later 298 # of that file some time in the past. Thus our
298 repo.dirstate.update([f], 'm') 299 # merge will appear as a normal local file
299 else: 300 # modification.
300 # We've update-merged a locally modified file, so 301 fl = repo.file(f)
301 # we set the dirstate to emulate a normal checkout 302 f_len = fl.size(fl.rev(other))
302 # of that file some time in the past. Thus our 303 repo.dirstate.update([f], 'n', st_size=f_len, st_mtime=-1)
303 # merge will appear as a normal local file
304 # modification.
305 fl = repo.file(f)
306 f_len = fl.size(fl.rev(other))
307 repo.dirstate.update([f], 'n', st_size=f_len, st_mtime=-1)
308 304
309 if show_stats: 305 if show_stats:
310 stats = ((len(get), _("updated")), 306 stats = ((updated, _("updated")),
311 (len(merge) - len(unresolved), _("merged")), 307 (merged - len(unresolved), _("merged")),
312 (len(remove), _("removed")), 308 (len(remove), _("removed")),
313 (len(unresolved), _("unresolved"))) 309 (len(unresolved), _("unresolved")))
314 note = ", ".join([_("%d files %s") % s for s in stats]) 310 note = ", ".join([_("%d files %s") % s for s in stats])
315 repo.ui.status("%s\n" % note) 311 repo.ui.status("%s\n" % note)
316 if not partial: 312 if not partial: