Show More
@@ -201,30 +201,55 b' def clone(ui, source, dest=None, pull=Fa' | |||||
201 | dest_lock.release() |
|
201 | dest_lock.release() | |
202 |
|
202 | |||
203 | if update: |
|
203 | if update: | |
204 |
_ |
|
204 | _update(dest_repo, dest_repo.changelog.tip()) | |
205 | if dir_cleanup: |
|
205 | if dir_cleanup: | |
206 | dir_cleanup.close() |
|
206 | dir_cleanup.close() | |
207 |
|
207 | |||
208 | return src_repo, dest_repo |
|
208 | return src_repo, dest_repo | |
209 |
|
209 | |||
|
210 | def _showstats(repo, stats): | |||
|
211 | stats = ((stats[0], _("updated")), | |||
|
212 | (stats[1], _("merged")), | |||
|
213 | (stats[2], _("removed")), | |||
|
214 | (stats[3], _("unresolved"))) | |||
|
215 | note = ", ".join([_("%d files %s") % s for s in stats]) | |||
|
216 | repo.ui.status("%s\n" % note) | |||
|
217 | ||||
|
218 | def _update(repo, node): return update(repo, node) | |||
|
219 | ||||
210 | def update(repo, node): |
|
220 | def update(repo, node): | |
211 | """update the working directory to node, merging linear changes""" |
|
221 | """update the working directory to node, merging linear changes""" | |
212 |
|
|
222 | stats = _merge.update(repo, node, False, False, None, None) | |
|
223 | _showstats(repo, stats) | |||
|
224 | if stats[3]: | |||
|
225 | repo.ui.status(_("There are unresolved merges with" | |||
|
226 | " locally modified files.\n")) | |||
|
227 | return stats[3] | |||
213 |
|
228 | |||
214 | def clean(repo, node, wlock=None, show_stats=True): |
|
229 | def clean(repo, node, wlock=None, show_stats=True): | |
215 | """forcibly switch the working directory to node, clobbering changes""" |
|
230 | """forcibly switch the working directory to node, clobbering changes""" | |
216 |
|
|
231 | stats = _merge.update(repo, node, False, True, None, wlock) | |
217 | show_stats=show_stats) |
|
232 | if show_stats: _showstats(repo, stats) | |
|
233 | return stats[3] | |||
218 |
|
234 | |||
219 | def merge(repo, node, force=None, remind=True, wlock=None): |
|
235 | def merge(repo, node, force=None, remind=True, wlock=None): | |
220 | """branch merge with node, resolving changes""" |
|
236 | """branch merge with node, resolving changes""" | |
221 |
|
|
237 | stats = _merge.update(repo, node, True, force, False, wlock) | |
222 | remind=remind, wlock=wlock) |
|
238 | _showstats(repo, stats) | |
|
239 | if stats[3]: | |||
|
240 | pl = repo.parents() | |||
|
241 | repo.ui.status(_("There are unresolved merges," | |||
|
242 | " you can redo the full merge using:\n" | |||
|
243 | " hg update -C %s\n" | |||
|
244 | " hg merge %s\n" | |||
|
245 | % (pl[0].rev(), pl[1].rev()))) | |||
|
246 | elif remind: | |||
|
247 | repo.ui.status(_("(branch merge, don't forget to commit)\n")) | |||
|
248 | return stats[3] | |||
223 |
|
249 | |||
224 | def revert(repo, node, choose, wlock): |
|
250 | def revert(repo, node, choose, wlock): | |
225 | """revert changes to revision in node without updating dirstate""" |
|
251 | """revert changes to revision in node without updating dirstate""" | |
226 |
return _merge.update(repo, node, |
|
252 | return _merge.update(repo, node, False, True, choose, wlock)[3] | |
227 | show_stats=False, wlock=wlock) |
|
|||
228 |
|
253 | |||
229 | def verify(repo): |
|
254 | def verify(repo): | |
230 | """verify the consistency of a repository""" |
|
255 | """verify the consistency of a repository""" |
@@ -13,13 +13,9 b' demandload(globals(), "errno util os tem' | |||||
13 | def filemerge(repo, fw, fo, wctx, mctx): |
|
13 | def filemerge(repo, fw, fo, wctx, mctx): | |
14 | """perform a 3-way merge in the working directory |
|
14 | """perform a 3-way merge in the working directory | |
15 |
|
15 | |||
16 |
fw = filename in the working directory |
|
16 | fw = filename in the working directory | |
17 | fo = filename in other parent |
|
17 | fo = filename in other parent | |
18 | wctx, mctx = working and merge changecontexts |
|
18 | wctx, mctx = working and merge changecontexts | |
19 |
|
||||
20 | TODO: |
|
|||
21 | if fw is copied in the working directory, we get confused |
|
|||
22 | implement move and fd |
|
|||
23 | """ |
|
19 | """ | |
24 |
|
20 | |||
25 | def temp(prefix, ctx): |
|
21 | def temp(prefix, ctx): | |
@@ -64,9 +60,7 b' def filemerge(repo, fw, fo, wctx, mctx):' | |||||
64 | return r |
|
60 | return r | |
65 |
|
61 | |||
66 | def checkunknown(wctx, mctx): |
|
62 | def checkunknown(wctx, mctx): | |
67 | """ |
|
63 | "check for collisions between unknown files and files in mctx" | |
68 | check for collisions between unknown files and files in m2 |
|
|||
69 | """ |
|
|||
70 | man = mctx.manifest() |
|
64 | man = mctx.manifest() | |
71 | for f in wctx.unknown(): |
|
65 | for f in wctx.unknown(): | |
72 | if f in man: |
|
66 | if f in man: | |
@@ -94,9 +88,7 b' def forgetremoved(wctx, mctx):' | |||||
94 | return action |
|
88 | return action | |
95 |
|
89 | |||
96 | def nonoverlap(d1, d2): |
|
90 | def nonoverlap(d1, d2): | |
97 | """ |
|
91 | "Return list of elements in d1 not in d2" | |
98 | Return list of elements in d1 not in d2 |
|
|||
99 | """ |
|
|||
100 |
|
92 | |||
101 | l = [] |
|
93 | l = [] | |
102 | for d in d1: |
|
94 | for d in d1: | |
@@ -107,9 +99,7 b' def nonoverlap(d1, d2):' | |||||
107 | return l |
|
99 | return l | |
108 |
|
100 | |||
109 | def findold(fctx, limit): |
|
101 | def findold(fctx, limit): | |
110 | """ |
|
102 | "find files that path was copied from, back to linkrev limit" | |
111 | find files that path was copied from, back to linkrev limit |
|
|||
112 | """ |
|
|||
113 |
|
103 | |||
114 | old = {} |
|
104 | old = {} | |
115 | orig = fctx.path() |
|
105 | orig = fctx.path() | |
@@ -174,7 +164,10 b' def findcopies(repo, m1, m2, limit):' | |||||
174 |
|
164 | |||
175 | def manifestmerge(repo, p1, p2, pa, overwrite, partial): |
|
165 | def manifestmerge(repo, p1, p2, pa, overwrite, partial): | |
176 | """ |
|
166 | """ | |
177 |
Merge |
|
167 | Merge p1 and p2 with ancestor ma and generate merge action list | |
|
168 | ||||
|
169 | overwrite = whether we clobber working files | |||
|
170 | partial = function to filter file lists | |||
178 | """ |
|
171 | """ | |
179 |
|
172 | |||
180 | repo.ui.note(_("resolving manifests\n")) |
|
173 | repo.ui.note(_("resolving manifests\n")) | |
@@ -275,6 +268,8 b' def manifestmerge(repo, p1, p2, pa, over' | |||||
275 | return action |
|
268 | return action | |
276 |
|
269 | |||
277 | def applyupdates(repo, action, wctx, mctx): |
|
270 | def applyupdates(repo, action, wctx, mctx): | |
|
271 | "apply the merge action list to the working directory" | |||
|
272 | ||||
278 | updated, merged, removed, unresolved = 0, 0, 0, 0 |
|
273 | updated, merged, removed, unresolved = 0, 0, 0, 0 | |
279 | action.sort() |
|
274 | action.sort() | |
280 | for a in action: |
|
275 | for a in action: | |
@@ -296,15 +291,14 b' def applyupdates(repo, action, wctx, mct' | |||||
296 | if filemerge(repo, f, f2, wctx, mctx): |
|
291 | if filemerge(repo, f, f2, wctx, mctx): | |
297 | unresolved += 1 |
|
292 | unresolved += 1 | |
298 | else: |
|
293 | else: | |
|
294 | merged += 1 | |||
299 | if f != fd: |
|
295 | if f != fd: | |
300 | repo.ui.debug(_("copying %s to %s\n") % (f, fd)) |
|
296 | repo.ui.debug(_("copying %s to %s\n") % (f, fd)) | |
301 | repo.wwrite(fd, repo.wread(f)) |
|
297 | repo.wwrite(fd, repo.wread(f)) | |
302 | if move: |
|
298 | if move: | |
303 | repo.ui.debug(_("removing %s\n") % f) |
|
299 | repo.ui.debug(_("removing %s\n") % f) | |
304 | os.unlink(repo.wjoin(f)) |
|
300 | os.unlink(repo.wjoin(f)) | |
305 |
|
||||
306 | util.set_exec(repo.wjoin(fd), flag) |
|
301 | util.set_exec(repo.wjoin(fd), flag) | |
307 | merged += 1 |
|
|||
308 | elif m == "g": # get |
|
302 | elif m == "g": # get | |
309 | flag = a[2] |
|
303 | flag = a[2] | |
310 | repo.ui.note(_("getting %s\n") % f) |
|
304 | repo.ui.note(_("getting %s\n") % f) | |
@@ -319,6 +313,8 b' def applyupdates(repo, action, wctx, mct' | |||||
319 | return updated, merged, removed, unresolved |
|
313 | return updated, merged, removed, unresolved | |
320 |
|
314 | |||
321 | def recordupdates(repo, action, branchmerge, mctx): |
|
315 | def recordupdates(repo, action, branchmerge, mctx): | |
|
316 | "record merge actions to the dirstate" | |||
|
317 | ||||
322 | for a in action: |
|
318 | for a in action: | |
323 | f, m = a[:2] |
|
319 | f, m = a[:2] | |
324 | if m == "r": # remove |
|
320 | if m == "r": # remove | |
@@ -355,8 +351,15 b' def recordupdates(repo, action, branchme' | |||||
355 | else: |
|
351 | else: | |
356 | repo.dirstate.copy(f2, fd) |
|
352 | repo.dirstate.copy(f2, fd) | |
357 |
|
353 | |||
358 |
def update(repo, node, branchmerge |
|
354 | def update(repo, node, branchmerge, force, partial, wlock): | |
359 | wlock=None, show_stats=True, remind=True): |
|
355 | """ | |
|
356 | Perform a merge between the working directory and the given node | |||
|
357 | ||||
|
358 | branchmerge = whether to merge between branches | |||
|
359 | force = whether to force branch merging or file overwriting | |||
|
360 | partial = a function to filter file lists (dirstate not updated) | |||
|
361 | wlock = working dir lock, if already held | |||
|
362 | """ | |||
360 |
|
363 | |||
361 | if not wlock: |
|
364 | if not wlock: | |
362 | wlock = repo.wlock() |
|
365 | wlock = repo.wlock() | |
@@ -397,32 +400,12 b' def update(repo, node, branchmerge=False' | |||||
397 | if not partial: |
|
400 | if not partial: | |
398 | repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2) |
|
401 | repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2) | |
399 |
|
402 | |||
400 |
|
|
403 | stats = applyupdates(repo, action, wc, p2) | |
401 |
|
404 | |||
402 | if show_stats: |
|
|||
403 | stats = ((updated, _("updated")), |
|
|||
404 | (merged - unresolved, _("merged")), |
|
|||
405 | (removed, _("removed")), |
|
|||
406 | (unresolved, _("unresolved"))) |
|
|||
407 | note = ", ".join([_("%d files %s") % s for s in stats]) |
|
|||
408 | repo.ui.status("%s\n" % note) |
|
|||
409 | if not partial: |
|
405 | if not partial: | |
410 | recordupdates(repo, action, branchmerge, p2) |
|
406 | recordupdates(repo, action, branchmerge, p2) | |
411 | repo.dirstate.setparents(fp1, fp2) |
|
407 | repo.dirstate.setparents(fp1, fp2) | |
412 |
repo.hook('update', parent1=xp1, parent2=xp2, error= |
|
408 | repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3]) | |
413 |
|
409 | |||
414 | if branchmerge: |
|
410 | return stats | |
415 | if unresolved: |
|
|||
416 | repo.ui.status(_("There are unresolved merges," |
|
|||
417 | " you can redo the full merge using:\n" |
|
|||
418 | " hg update -C %s\n" |
|
|||
419 | " hg merge %s\n" |
|
|||
420 | % (p1.rev(), p2.rev()))) |
|
|||
421 | elif remind: |
|
|||
422 | repo.ui.status(_("(branch merge, don't forget to commit)\n")) |
|
|||
423 | elif unresolved: |
|
|||
424 | repo.ui.status(_("There are unresolved merges with" |
|
|||
425 | " locally modified files.\n")) |
|
|||
426 |
|
411 | |||
427 | return unresolved |
|
|||
428 |
|
General Comments 0
You need to be logged in to leave comments.
Login now