[PATCH 1 of 4 V4] update: accept --merge to allow merging across topo branches (issue5125)
Martin von Zweigbergk
martinvonz at google.com
Tue Feb 21 17:27:02 EST 2017
Sure. I'm on vacation, so I can do that next week, or in a follow-up.
Whichever the person considering queuing prefers.
On Tue, Feb 21, 2017, 14:18 Jun Wu <quark at fb.com> wrote:
> I like the behavior change (didn't check the implementation details
> carefully).
>
> Could you also update the table in the docstring of merge.update? I think
> that's very helpful to explain the behavior cleanly. Thanks!
>
> Excerpts from Martin von Zweigbergk's message of 2017-02-16 08:59:12 -0800:
> > # HG changeset patch
> > # User Martin von Zweigbergk <martinvonz at google.com>
> > # Date 1487019517 28800
> > # Mon Feb 13 12:58:37 2017 -0800
> > # Node ID 19f471c814809099b5452b1174a2ecb0699cb76a
> > # Parent 1ee685defe80117cf6aafea1ede6c33c478abceb
> > update: accept --merge to allow merging across topo branches (issue5125)
> >
> > diff -r 1ee685defe80 -r 19f471c81480 mercurial/commands.py
> > --- a/mercurial/commands.py Wed Feb 15 16:29:58 2017 -0800
> > +++ b/mercurial/commands.py Mon Feb 13 12:58:37 2017 -0800
> > @@ -5286,12 +5286,13 @@
> > @command('^update|up|checkout|co',
> > [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
> > ('c', 'check', None, _('require clean working directory')),
> > + ('m', 'merge', None, _('merge local changes')),
> > ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
> > ('r', 'rev', '', _('revision'), _('REV'))
> > ] + mergetoolopts,
> > - _('[-C|-c] [-d DATE] [[-r] REV]'))
> > + _('[-C|-c|-m] [-d DATE] [[-r] REV]'))
> > def update(ui, repo, node=None, rev=None, clean=False, date=None,
> check=False,
> > - tool=None):
> > + merge=None, tool=None):
> > """update working directory (or switch revisions)
> >
> > Update the repository's working directory to the specified
> > @@ -5310,8 +5311,8 @@
> >
> > .. container:: verbose
> >
> > - The -C/--clean and -c/--check options control what happens if the
> > - working directory contains uncommitted changes.
> > + The -C/--clean, -c/--check, and -m/--merge options control what
> > + happens if the working directory contains uncommitted changes.
> > At most of one of them can be specified.
> >
> > 1. If no option is specified, and if
> > @@ -5323,10 +5324,14 @@
> > branch), the update is aborted and the uncommitted changes
> > are preserved.
> >
> > - 2. With the -c/--check option, the update is aborted and the
> > + 2. With the -m/--merge option, the update is allowed even if the
> > + requested changeset is not an ancestor or descendant of
> > + the working directory's parent.
> > +
> > + 3. With the -c/--check option, the update is aborted and the
> > uncommitted changes are preserved.
> >
> > - 3. With the -C/--clean option, uncommitted changes are discarded
> and
> > + 4. With the -C/--clean option, uncommitted changes are discarded
> and
> > the working directory is updated to the requested changeset.
> >
> > To cancel an uncommitted merge (and lose your changes), use
> > @@ -5351,8 +5356,15 @@
> > if date and rev is not None:
> > raise error.Abort(_("you can't specify a revision and a date"))
> >
> > - if check and clean:
> > - raise error.Abort(_("cannot specify both -c/--check and
> -C/--clean"))
> > + if len([x for x in (clean, check, merge) if x]) > 1:
> > + raise error.Abort(_("can only specify one of -C/--clean,
> -c/--check, "
> > + "or -m/merge"))
> > +
> > + updatecheck = None
> > + if check:
> > + updatecheck = 'abort'
> > + elif merge:
> > + updatecheck = 'none'
> >
> > with repo.wlock():
> > cmdutil.clearunfinished(repo)
> > @@ -5366,7 +5378,8 @@
> >
> > repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
> >
> > - return hg.updatetotally(ui, repo, rev, brev, clean=clean,
> check=check)
> > + return hg.updatetotally(ui, repo, rev, brev, clean=clean,
> > + updatecheck=updatecheck)
> >
> > @command('verify', [])
> > def verify(ui, repo):
> > diff -r 1ee685defe80 -r 19f471c81480 mercurial/hg.py
> > --- a/mercurial/hg.py Wed Feb 15 16:29:58 2017 -0800
> > +++ b/mercurial/hg.py Mon Feb 13 12:58:37 2017 -0800
> > @@ -681,18 +681,19 @@
> > repo.ui.status(_("%d files updated, %d files merged, "
> > "%d files removed, %d files unresolved\n") % stats)
> >
> > -def updaterepo(repo, node, overwrite):
> > +def updaterepo(repo, node, overwrite, updatecheck=None):
> > """Update the working directory to node.
> >
> > When overwrite is set, changes are clobbered, merged else
> >
> > returns stats (see pydoc mercurial.merge.applyupdates)"""
> > return mergemod.update(repo, node, False, overwrite,
> > - labels=['working copy', 'destination'])
> > + labels=['working copy', 'destination'],
> > + updatecheck=updatecheck)
> >
> > -def update(repo, node, quietempty=False):
> > - """update the working directory to node, merging linear changes"""
> > - stats = updaterepo(repo, node, False)
> > +def update(repo, node, quietempty=False, updatecheck=None):
> > + """update the working directory to node"""
> > + stats = updaterepo(repo, node, False, updatecheck=updatecheck)
> > _showstats(repo, stats, quietempty)
> > if stats[3]:
> > repo.ui.status(_("use 'hg resolve' to retry unresolved file
> merges\n"))
> > @@ -712,7 +713,7 @@
> > # naming conflict in updatetotally()
> > _clean = clean
> >
> > -def updatetotally(ui, repo, checkout, brev, clean=False, check=False):
> > +def updatetotally(ui, repo, checkout, brev, clean=False,
> updatecheck=None):
> > """Update the working directory with extra care for non-file
> components
> >
> > This takes care of non-file components below:
> > @@ -724,10 +725,19 @@
> > :checkout: to which revision the working directory is updated
> > :brev: a name, which might be a bookmark to be activated after
> updating
> > :clean: whether changes in the working directory can be discarded
> > - :check: whether changes in the working directory should be checked
> > + :updatecheck: how to deal with a dirty working directory
> > +
> > + Valid values for updatecheck are (None => linear):
> > +
> > + * abort: abort if the working directory is dirty
> > + * none: don't check (merge working directory changes into
> destination)
> > + * linear: check that update is linear before merging working
> directory
> > + changes into destination
> >
> > This returns whether conflict is detected at updating or not.
> > """
> > + if updatecheck is None:
> > + updatecheck = 'linear'
> > with repo.wlock():
> > movemarkfrom = None
> > warndest = False
> > @@ -739,9 +749,10 @@
> > if clean:
> > ret = _clean(repo, checkout)
> > else:
> > - if check:
> > + if updatecheck == 'abort':
> > cmdutil.bailifchanged(repo, merge=False)
> > - ret = _update(repo, checkout)
> > + updatecheck = 'none'
> > + ret = _update(repo, checkout, updatecheck=updatecheck)
> >
> > if not ret and movemarkfrom:
> > if movemarkfrom == repo['.'].node():
> > diff -r 1ee685defe80 -r 19f471c81480 mercurial/merge.py
> > --- a/mercurial/merge.py Wed Feb 15 16:29:58 2017 -0800
> > +++ b/mercurial/merge.py Mon Feb 13 12:58:37 2017 -0800
> > @@ -1444,7 +1444,8 @@
> > repo.dirstate.normal(f)
> >
> > def update(repo, node, branchmerge, force, ancestor=None,
> > - mergeancestor=False, labels=None, matcher=None,
> mergeforce=False):
> > + mergeancestor=False, labels=None, matcher=None,
> mergeforce=False,
> > + updatecheck=None):
> > """
> > Perform a merge between the working directory and the given node
> >
> > @@ -1491,9 +1492,16 @@
> > Return the same tuple as applyupdates().
> > """
> >
> > - # This functon used to find the default destination if node was
> None, but
> > + # This function used to find the default destination if node was
> None, but
> > # that's now in destutil.py.
> > assert node is not None
> > + if not branchmerge and not force:
> > + # TODO: remove the default once all callers that pass
> branchmerge=False
> > + # and force=False pass a value for updatecheck. We may want to
> allow
> > + # updatecheck='abort' to better suppport some of these callers.
> > + if updatecheck is None:
> > + updatecheck = 'linear'
> > + assert updatecheck in ('none', 'linear')
> > # If we're doing a partial update, we need to skip updating
> > # the dirstate, so make a note of any partial-ness to the
> > # update here.
> > @@ -1550,7 +1558,8 @@
> > repo.hook('update', parent1=xp2, parent2='', error=0)
> > return 0, 0, 0, 0
> >
> > - if pas not in ([p1], [p2]): # nonlinear
> > + if (updatecheck == 'linear' and
> > + pas not in ([p1], [p2])): # nonlinear
> > dirty = wc.dirty(missing=True)
> > if dirty:
> > # Branching is a bit strange to ensure we do the
> minimal
> > diff -r 1ee685defe80 -r 19f471c81480 tests/test-completion.t
> > --- a/tests/test-completion.t Wed Feb 15 16:29:58 2017 -0800
> > +++ b/tests/test-completion.t Mon Feb 13 12:58:37 2017 -0800
> > @@ -223,7 +223,7 @@
> > serve: accesslog, daemon, daemon-postexec, errorlog, port, address,
> prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates,
> style, ipv6, certificate
> > status: all, modified, added, removed, deleted, clean, unknown,
> ignored, no-status, copies, print0, rev, change, include, exclude,
> subrepos, template
> > summary: remote
> > - update: clean, check, date, rev, tool
> > + update: clean, check, merge, date, rev, tool
> > addremove: similarity, subrepos, include, exclude, dry-run
> > archive: no-decode, prefix, rev, type, subrepos, include, exclude
> > backout: merge, commit, no-commit, parent, rev, edit, tool, include,
> exclude, message, logfile, date, user
> > diff -r 1ee685defe80 -r 19f471c81480 tests/test-update-branches.t
> > --- a/tests/test-update-branches.t Wed Feb 15 16:29:58 2017 -0800
> > +++ b/tests/test-update-branches.t Mon Feb 13 12:58:37 2017 -0800
> > @@ -160,6 +160,16 @@
> > parent=1
> > M foo
> >
> > + $ revtest '-m dirty linear' dirty 1 2 -m
> > + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> > + parent=2
> > + M foo
> > +
> > + $ revtest '-m dirty cross' dirty 3 4 -m
> > + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> > + parent=4
> > + M foo
> > +
> > $ revtest '-c dirtysub linear' dirtysub 1 2 -c
> > abort: uncommitted changes in subrepository 'sub'
> > parent=1
> > @@ -171,7 +181,17 @@
> > parent=2
> >
> > $ revtest '-cC dirty linear' dirty 1 2 -cC
> > - abort: cannot specify both -c/--check and -C/--clean
> > + abort: can only specify one of -C/--clean, -c/--check, or -m/merge
> > + parent=1
> > + M foo
> > +
> > + $ revtest '-mc dirty linear' dirty 1 2 -mc
> > + abort: can only specify one of -C/--clean, -c/--check, or -m/merge
> > + parent=1
> > + M foo
> > +
> > + $ revtest '-mC dirty linear' dirty 1 2 -mC
> > + abort: can only specify one of -C/--clean, -c/--check, or -m/merge
> > parent=1
> > M foo
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.mercurial-scm.org/pipermail/mercurial-devel/attachments/20170221/219db0e0/attachment.html>
More information about the Mercurial-devel
mailing list