Show More
@@ -5278,12 +5278,13 b' def unbundle(ui, repo, fname1, *fnames, ' | |||
|
5278 | 5278 | @command('^update|up|checkout|co', |
|
5279 | 5279 | [('C', 'clean', None, _('discard uncommitted changes (no backup)')), |
|
5280 | 5280 | ('c', 'check', None, _('require clean working directory')), |
|
5281 | ('m', 'merge', None, _('merge uncommitted changes')), | |
|
5281 | 5282 | ('d', 'date', '', _('tipmost revision matching date'), _('DATE')), |
|
5282 | 5283 | ('r', 'rev', '', _('revision'), _('REV')) |
|
5283 | 5284 | ] + mergetoolopts, |
|
5284 | _('[-C|-c] [-d DATE] [[-r] REV]')) | |
|
5285 | _('[-C|-c|-m] [-d DATE] [[-r] REV]')) | |
|
5285 | 5286 | def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False, |
|
5286 | tool=None): | |
|
5287 | merge=None, tool=None): | |
|
5287 | 5288 | """update working directory (or switch revisions) |
|
5288 | 5289 | |
|
5289 | 5290 | Update the repository's working directory to the specified |
@@ -5302,8 +5303,8 b' def update(ui, repo, node=None, rev=None' | |||
|
5302 | 5303 | |
|
5303 | 5304 | .. container:: verbose |
|
5304 | 5305 | |
|
5305 |
The -C/--clean |
|
|
5306 | working directory contains uncommitted changes. | |
|
5306 | The -C/--clean, -c/--check, and -m/--merge options control what | |
|
5307 | happens if the working directory contains uncommitted changes. | |
|
5307 | 5308 | At most of one of them can be specified. |
|
5308 | 5309 | |
|
5309 | 5310 | 1. If no option is specified, and if |
@@ -5315,10 +5316,14 b' def update(ui, repo, node=None, rev=None' | |||
|
5315 | 5316 | branch), the update is aborted and the uncommitted changes |
|
5316 | 5317 | are preserved. |
|
5317 | 5318 | |
|
5318 |
2. With the - |
|
|
5319 | 2. With the -m/--merge option, the update is allowed even if the | |
|
5320 | requested changeset is not an ancestor or descendant of | |
|
5321 | the working directory's parent. | |
|
5322 | ||
|
5323 | 3. With the -c/--check option, the update is aborted and the | |
|
5319 | 5324 | uncommitted changes are preserved. |
|
5320 | 5325 | |
|
5321 |
|
|
|
5326 | 4. With the -C/--clean option, uncommitted changes are discarded and | |
|
5322 | 5327 | the working directory is updated to the requested changeset. |
|
5323 | 5328 | |
|
5324 | 5329 | To cancel an uncommitted merge (and lose your changes), use |
@@ -5343,8 +5348,15 b' def update(ui, repo, node=None, rev=None' | |||
|
5343 | 5348 | if date and rev is not None: |
|
5344 | 5349 | raise error.Abort(_("you can't specify a revision and a date")) |
|
5345 | 5350 | |
|
5346 | if check and clean: | |
|
5347 |
raise error.Abort(_("can |
|
|
5351 | if len([x for x in (clean, check, merge) if x]) > 1: | |
|
5352 | raise error.Abort(_("can only specify one of -C/--clean, -c/--check, " | |
|
5353 | "or -m/merge")) | |
|
5354 | ||
|
5355 | updatecheck = None | |
|
5356 | if check: | |
|
5357 | updatecheck = 'abort' | |
|
5358 | elif merge: | |
|
5359 | updatecheck = 'none' | |
|
5348 | 5360 | |
|
5349 | 5361 | with repo.wlock(): |
|
5350 | 5362 | cmdutil.clearunfinished(repo) |
@@ -5358,7 +5370,8 b' def update(ui, repo, node=None, rev=None' | |||
|
5358 | 5370 | |
|
5359 | 5371 | repo.ui.setconfig('ui', 'forcemerge', tool, 'update') |
|
5360 | 5372 | |
|
5361 |
return hg.updatetotally(ui, repo, rev, brev, clean=clean, |
|
|
5373 | return hg.updatetotally(ui, repo, rev, brev, clean=clean, | |
|
5374 | updatecheck=updatecheck) | |
|
5362 | 5375 | |
|
5363 | 5376 | @command('verify', []) |
|
5364 | 5377 | def verify(ui, repo): |
@@ -691,18 +691,19 b' def _showstats(repo, stats, quietempty=F' | |||
|
691 | 691 | repo.ui.status(_("%d files updated, %d files merged, " |
|
692 | 692 | "%d files removed, %d files unresolved\n") % stats) |
|
693 | 693 | |
|
694 | def updaterepo(repo, node, overwrite): | |
|
694 | def updaterepo(repo, node, overwrite, updatecheck=None): | |
|
695 | 695 | """Update the working directory to node. |
|
696 | 696 | |
|
697 | 697 | When overwrite is set, changes are clobbered, merged else |
|
698 | 698 | |
|
699 | 699 | returns stats (see pydoc mercurial.merge.applyupdates)""" |
|
700 | 700 | return mergemod.update(repo, node, False, overwrite, |
|
701 |
labels=['working copy', 'destination'] |
|
|
701 | labels=['working copy', 'destination'], | |
|
702 | updatecheck=updatecheck) | |
|
702 | 703 | |
|
703 | def update(repo, node, quietempty=False): | |
|
704 |
"""update the working directory to node |
|
|
705 | stats = updaterepo(repo, node, False) | |
|
704 | def update(repo, node, quietempty=False, updatecheck=None): | |
|
705 | """update the working directory to node""" | |
|
706 | stats = updaterepo(repo, node, False, updatecheck=updatecheck) | |
|
706 | 707 | _showstats(repo, stats, quietempty) |
|
707 | 708 | if stats[3]: |
|
708 | 709 | repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n")) |
@@ -722,7 +723,7 b' def clean(repo, node, show_stats=True, q' | |||
|
722 | 723 | # naming conflict in updatetotally() |
|
723 | 724 | _clean = clean |
|
724 | 725 | |
|
725 |
def updatetotally(ui, repo, checkout, brev, clean=False, check= |
|
|
726 | def updatetotally(ui, repo, checkout, brev, clean=False, updatecheck=None): | |
|
726 | 727 | """Update the working directory with extra care for non-file components |
|
727 | 728 | |
|
728 | 729 | This takes care of non-file components below: |
@@ -734,10 +735,19 b' def updatetotally(ui, repo, checkout, br' | |||
|
734 | 735 | :checkout: to which revision the working directory is updated |
|
735 | 736 | :brev: a name, which might be a bookmark to be activated after updating |
|
736 | 737 | :clean: whether changes in the working directory can be discarded |
|
737 | :check: whether changes in the working directory should be checked | |
|
738 | :updatecheck: how to deal with a dirty working directory | |
|
739 | ||
|
740 | Valid values for updatecheck are (None => linear): | |
|
741 | ||
|
742 | * abort: abort if the working directory is dirty | |
|
743 | * none: don't check (merge working directory changes into destination) | |
|
744 | * linear: check that update is linear before merging working directory | |
|
745 | changes into destination | |
|
738 | 746 | |
|
739 | 747 | This returns whether conflict is detected at updating or not. |
|
740 | 748 | """ |
|
749 | if updatecheck is None: | |
|
750 | updatecheck = 'linear' | |
|
741 | 751 | with repo.wlock(): |
|
742 | 752 | movemarkfrom = None |
|
743 | 753 | warndest = False |
@@ -749,9 +759,10 b' def updatetotally(ui, repo, checkout, br' | |||
|
749 | 759 | if clean: |
|
750 | 760 | ret = _clean(repo, checkout) |
|
751 | 761 | else: |
|
752 | if check: | |
|
762 | if updatecheck == 'abort': | |
|
753 | 763 | cmdutil.bailifchanged(repo, merge=False) |
|
754 |
|
|
|
764 | updatecheck = 'none' | |
|
765 | ret = _update(repo, checkout, updatecheck=updatecheck) | |
|
755 | 766 | |
|
756 | 767 | if not ret and movemarkfrom: |
|
757 | 768 | if movemarkfrom == repo['.'].node(): |
@@ -1444,7 +1444,8 b' def recordupdates(repo, actions, branchm' | |||
|
1444 | 1444 | repo.dirstate.normal(f) |
|
1445 | 1445 | |
|
1446 | 1446 | def update(repo, node, branchmerge, force, ancestor=None, |
|
1447 |
mergeancestor=False, labels=None, matcher=None, mergeforce=False |
|
|
1447 | mergeancestor=False, labels=None, matcher=None, mergeforce=False, | |
|
1448 | updatecheck=None): | |
|
1448 | 1449 | """ |
|
1449 | 1450 | Perform a merge between the working directory and the given node |
|
1450 | 1451 | |
@@ -1468,14 +1469,17 b' def update(repo, node, branchmerge, forc' | |||
|
1468 | 1469 | |
|
1469 | 1470 | This logic is tested by test-update-branches.t. |
|
1470 | 1471 | |
|
1471 | -c -C dirty rev linear | result | |
|
1472 | y y * * * | (1) | |
|
1473 |
|
|
|
1474 |
* |
|
|
1475 |
|
|
|
1476 |
|
|
|
1477 |
n |
|
|
1478 |
|
|
|
1472 | -c -C -m dirty rev linear | result | |
|
1473 | y y * * * * | (1) | |
|
1474 | y * y * * * | (1) | |
|
1475 | * y y * * * | (1) | |
|
1476 | * * * * n n | x | |
|
1477 | * * * n * * | ok | |
|
1478 | n n n y * y | merge | |
|
1479 | n n n y y n | (2) | |
|
1480 | n n y y * * | merge | |
|
1481 | n y n y * * | discard | |
|
1482 | y n n y * * | (3) | |
|
1479 | 1483 | |
|
1480 | 1484 | x = can't happen |
|
1481 | 1485 | * = don't-care |
@@ -1486,9 +1490,16 b' def update(repo, node, branchmerge, forc' | |||
|
1486 | 1490 | Return the same tuple as applyupdates(). |
|
1487 | 1491 | """ |
|
1488 | 1492 | |
|
1489 | # This functon used to find the default destination if node was None, but | |
|
1493 | # This function used to find the default destination if node was None, but | |
|
1490 | 1494 | # that's now in destutil.py. |
|
1491 | 1495 | assert node is not None |
|
1496 | if not branchmerge and not force: | |
|
1497 | # TODO: remove the default once all callers that pass branchmerge=False | |
|
1498 | # and force=False pass a value for updatecheck. We may want to allow | |
|
1499 | # updatecheck='abort' to better suppport some of these callers. | |
|
1500 | if updatecheck is None: | |
|
1501 | updatecheck = 'linear' | |
|
1502 | assert updatecheck in ('none', 'linear') | |
|
1492 | 1503 | # If we're doing a partial update, we need to skip updating |
|
1493 | 1504 | # the dirstate, so make a note of any partial-ness to the |
|
1494 | 1505 | # update here. |
@@ -1545,7 +1556,8 b' def update(repo, node, branchmerge, forc' | |||
|
1545 | 1556 | repo.hook('update', parent1=xp2, parent2='', error=0) |
|
1546 | 1557 | return 0, 0, 0, 0 |
|
1547 | 1558 | |
|
1548 | if pas not in ([p1], [p2]): # nonlinear | |
|
1559 | if (updatecheck == 'linear' and | |
|
1560 | pas not in ([p1], [p2])): # nonlinear | |
|
1549 | 1561 | dirty = wc.dirty(missing=True) |
|
1550 | 1562 | if dirty: |
|
1551 | 1563 | # Branching is a bit strange to ensure we do the minimal |
@@ -228,7 +228,7 b' Show all commands + options' | |||
|
228 | 228 | serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate |
|
229 | 229 | status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template |
|
230 | 230 | summary: remote |
|
231 | update: clean, check, date, rev, tool | |
|
231 | update: clean, check, merge, date, rev, tool | |
|
232 | 232 | addremove: similarity, subrepos, include, exclude, dry-run |
|
233 | 233 | archive: no-decode, prefix, rev, type, subrepos, include, exclude |
|
234 | 234 | backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user |
@@ -160,6 +160,16 b' Cases are run as shown in that table, ro' | |||
|
160 | 160 | parent=1 |
|
161 | 161 | M foo |
|
162 | 162 | |
|
163 | $ revtest '-m dirty linear' dirty 1 2 -m | |
|
164 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
165 | parent=2 | |
|
166 | M foo | |
|
167 | ||
|
168 | $ revtest '-m dirty cross' dirty 3 4 -m | |
|
169 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
170 | parent=4 | |
|
171 | M foo | |
|
172 | ||
|
163 | 173 | $ revtest '-c dirtysub linear' dirtysub 1 2 -c |
|
164 | 174 | abort: uncommitted changes in subrepository 'sub' |
|
165 | 175 | parent=1 |
@@ -171,7 +181,17 b' Cases are run as shown in that table, ro' | |||
|
171 | 181 | parent=2 |
|
172 | 182 | |
|
173 | 183 | $ revtest '-cC dirty linear' dirty 1 2 -cC |
|
174 |
abort: can |
|
|
184 | abort: can only specify one of -C/--clean, -c/--check, or -m/merge | |
|
185 | parent=1 | |
|
186 | M foo | |
|
187 | ||
|
188 | $ revtest '-mc dirty linear' dirty 1 2 -mc | |
|
189 | abort: can only specify one of -C/--clean, -c/--check, or -m/merge | |
|
190 | parent=1 | |
|
191 | M foo | |
|
192 | ||
|
193 | $ revtest '-mC dirty linear' dirty 1 2 -mC | |
|
194 | abort: can only specify one of -C/--clean, -c/--check, or -m/merge | |
|
175 | 195 | parent=1 |
|
176 | 196 | M foo |
|
177 | 197 |
General Comments 0
You need to be logged in to leave comments.
Login now