diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -361,9 +361,10 @@ def overridecheckunknownfile(origfn, rep # writing the files into the working copy and lfcommands.updatelfiles # will update the largefiles. def overridemanifestmerge(origfn, repo, p1, p2, pa, branchmerge, force, - partial): + partial, acceptremote=False): overwrite = force and not branchmerge - actions = origfn(repo, p1, p2, pa, branchmerge, force, partial) + actions = origfn(repo, p1, p2, pa, branchmerge, force, partial, + acceptremote) processed = [] for action in actions: diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -2972,7 +2972,7 @@ def grep(ui, repo, pattern, *pats, **opt if opts.get('ignore_case'): reflags |= re.I try: - regexp = re.compile(pattern, reflags) + regexp = util.compilere(pattern, reflags) except re.error, inst: ui.warn(_("grep: invalid match pattern: %s\n") % inst) return 1 diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -185,12 +185,14 @@ def _forgetremoved(wctx, mctx, branchmer return actions -def manifestmerge(repo, wctx, p2, pa, branchmerge, force, partial): +def manifestmerge(repo, wctx, p2, pa, branchmerge, force, partial, + acceptremote=False): """ Merge p1 and p2 with ancestor pa and generate merge action list branchmerge and force are as passed in to update partial = function to filter file lists + acceptremote = accept the incoming changes without prompting """ overwrite = force and not branchmerge @@ -331,7 +333,9 @@ def manifestmerge(repo, wctx, p2, pa, br for f, m in sorted(prompts): if m == "cd": - if repo.ui.promptchoice( + if acceptremote: + actions.append((f, "r", None, "remote delete")) + elif repo.ui.promptchoice( _("local changed %s which remote deleted\n" "use (c)hanged version or (d)elete?") % f, (_("&Changed"), _("&Delete")), 0): @@ -339,7 +343,9 @@ def manifestmerge(repo, wctx, p2, pa, br else: actions.append((f, "a", None, "prompt keep")) elif m == "dc": - if repo.ui.promptchoice( + if acceptremote: + actions.append((f, "g", (m2.flags(f),), "remote recreating")) + elif repo.ui.promptchoice( _("remote changed %s which local deleted\n" "use (c)hanged version or leave (d)eleted?") % f, (_("&Changed"), _("&Deleted")), 0) == 0: @@ -465,11 +471,11 @@ def applyupdates(repo, actions, wctx, mc f, m, args, msg = a progress(_updating, z + i + 1, item=f, total=numupdates, unit=_files) if m == "m": # merge + f2, fd, move = args if fd == '.hgsubstate': # subrepo states need updating subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), overwrite) continue - f2, fd, move = args audit(fd) r = ms.resolve(fd, wctx, mctx) if r is not None and r > 0: @@ -512,7 +518,8 @@ def applyupdates(repo, actions, wctx, mc return updated, merged, removed, unresolved -def calculateupdates(repo, tctx, mctx, ancestor, branchmerge, force, partial): +def calculateupdates(repo, tctx, mctx, ancestor, branchmerge, force, partial, + acceptremote=False): "Calculate the actions needed to merge mctx into tctx" actions = [] folding = not util.checkcase(repo.path) @@ -526,7 +533,7 @@ def calculateupdates(repo, tctx, mctx, a actions += manifestmerge(repo, tctx, mctx, ancestor, branchmerge, force, - partial) + partial, acceptremote) if tctx.rev() is None: actions += _forgetremoved(tctx, mctx, branchmerge) return actions @@ -602,10 +609,11 @@ def update(repo, node, branchmerge, forc branchmerge = whether to merge between branches force = whether to force branch merging or file overwriting partial = a function to filter file lists (dirstate not updated) - mergeancestor = if false, merging with an ancestor (fast-forward) - is only allowed between different named branches. This flag - is used by rebase extension as a temporary fix and should be - avoided in general. + mergeancestor = whether it is merging with an ancestor. If true, + we should accept the incoming changes for any prompts that occur. + If false, merging with an ancestor (fast-forward) is only allowed + between different named branches. This flag is used by rebase extension + as a temporary fix and should be avoided in general. The table below shows all the behaviors of the update command given the -c and -C or no options, whether the working directory @@ -693,7 +701,7 @@ def update(repo, node, branchmerge, forc ### calculate phase actions = calculateupdates(repo, wc, p2, pa, - branchmerge, force, partial) + branchmerge, force, partial, mergeancestor) ### apply phase if not branchmerge: # just jump to the new rev diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -1496,8 +1496,6 @@ def tag(repo, subset, x): s = set([repo[tn].rev()]) else: s = set([cl.rev(n) for t, n in repo.tagslist() if matcher(t)]) - if not s: - raise util.Abort(_("no tags exist that match '%s'") % pattern) else: s = set([cl.rev(n) for t, n in repo.tagslist() if t != 'tip']) return [r for r in subset if r in s] diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -662,10 +662,12 @@ try: except ImportError: _re2 = False -def compilere(pat): +def compilere(pat, flags=0): '''Compile a regular expression, using re2 if possible - For best performance, use only re2-compatible regexp features.''' + For best performance, use only re2-compatible regexp features. The + only flags from the re module that are re2-compatible are + IGNORECASE and MULTILINE.''' global _re2 if _re2 is None: try: @@ -673,12 +675,16 @@ def compilere(pat): _re2 = True except ImportError: _re2 = False - if _re2: + if _re2 and (flags & ~(re.IGNORECASE | re.MULTILINE)) == 0: + if flags & re.IGNORECASE: + pat = '(?i)' + pat + if flags & re.MULTILINE: + pat = '(?m)' + pat try: return re2.compile(pat) except re2.error: pass - return re.compile(pat) + return re.compile(pat, flags) _fspathcache = {} def fspath(name, root): diff --git a/tests/test-rebase-collapse.t b/tests/test-rebase-collapse.t --- a/tests/test-rebase-collapse.t +++ b/tests/test-rebase-collapse.t @@ -719,6 +719,30 @@ Test stripping a revision with another c $ cd .. +Test collapsing changes that add then remove a file + $ hg init collapseaddremove + $ cd collapseaddremove + $ touch base + $ hg commit -Am base + adding base + $ touch a + $ hg commit -Am a + adding a + $ hg rm a + $ touch b + $ hg commit -Am b + adding b + $ hg rebase -d 0 -r "1::2" --collapse -m collapsed + saved backup bundle to $TESTTMP/collapseaddremove/.hg/strip-backup/*-backup.hg (glob) + $ hg tglog + @ 1: 'collapsed' + | + o 0: 'base' + + $ hg manifest + b + base + $ cd .. diff --git a/tests/test-rebase-detach.t b/tests/test-rebase-detach.t --- a/tests/test-rebase-detach.t +++ b/tests/test-rebase-detach.t @@ -326,8 +326,6 @@ Verify that target is not selected as ex $ hg ci -m "J" $ hg rebase -s 8 -d 7 --collapse --config ui.merge=internal:other - remote changed E which local deleted - use (c)hanged version or leave (d)eleted? c saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob) $ hg tglog diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -437,8 +437,6 @@ we can use patterns when searching for t $ log 'tag("literal:1.0")' 6 $ log 'tag("re:0..*")' - abort: no tags exist that match '0..*' - [255] $ log 'tag(unknown)' abort: tag 'unknown' does not exist