# HG changeset patch # User Matt Mackall # Date 1155149718 18000 # Node ID 49988d9f07586e55b65175a00626e9a20db094f7 # Parent 4870f795f6810ba2a02428d750bbe52ac8076b89# Parent 05316bb57d011277cae04019d9bd151e01a1b42d Merge with crew, fix most tests diff -r 4870f795f681 -r 49988d9f0758 hgext/fetch.py --- a/hgext/fetch.py Tue Aug 08 10:56:48 2006 -0500 +++ b/hgext/fetch.py Wed Aug 09 13:55:18 2006 -0500 @@ -24,29 +24,29 @@ if modheads == 0: return 0 if modheads == 1: - return hg.update(repo, repo.changelog.tip()) + return hg.update(repo, repo.changelog.tip(), wlock=wlock) newheads = repo.heads(parent) newchildren = [n for n in repo.heads(parent) if n != parent] newparent = parent if newchildren: - hg.update(repo, newchildren[0]) newparent = newchildren[0] + hg.update(repo, newparent, wlock=wlock) newheads = [n for n in repo.heads() if n != newparent] err = False if newheads: ui.status(_('merging with new head %d:%s\n') % (repo.changelog.rev(newheads[0]), short(newheads[0]))) - err = hg.merge(repo, newheads[0], remind=False) + err = hg.merge(repo, newheads[0], remind=False, wlock=wlock) if not err and len(newheads) > 1: ui.status(_('not merging with %d other new heads ' '(use "hg heads" and "hg merge" to merge them)') % (len(newheads) - 1)) if not err: - mod, add, rem = repo.status()[:3] + mod, add, rem = repo.status(wlock=wlock)[:3] message = (commands.logmessage(opts) or (_('Automated merge with %s') % other.url())) n = repo.commit(mod + add + rem, message, - opts['user'], opts['date'], + opts['user'], opts['date'], lock=lock, wlock=wlock, force_editor=opts.get('force_editor')) ui.status(_('new changeset %d:%s merges remote changes ' 'with local\n') % (repo.changelog.rev(n), @@ -55,13 +55,13 @@ commands.setremoteconfig(ui, opts) other = hg.repository(ui, ui.expandpath(source)) - ui.status(_('pulling from %s\n') % source) + ui.status(_('pulling from %s\n') % ui.expandpath(source)) revs = None if opts['rev'] and not other.local(): raise util.Abort(_("fetch -r doesn't work for remote repositories yet")) elif opts['rev']: revs = [other.lookup(rev) for rev in opts['rev']] - modheads = repo.pull(other, heads=revs) + modheads = repo.pull(other, heads=revs, lock=lock) return postincoming(other, modheads) parent, p2 = repo.dirstate.parents() @@ -70,13 +70,19 @@ '(use "hg update" to check out tip)')) if p2 != nullid: raise util.Abort(_('outstanding uncommitted merge')) - mod, add, rem = repo.status()[:3] - if mod or add or rem: - raise util.Abort(_('outstanding uncommitted changes')) - if len(repo.heads()) > 1: - raise util.Abort(_('multiple heads in this repository ' - '(use "hg heads" and "hg merge" to merge them)')) - return pull() + wlock = repo.wlock() + lock = repo.lock() + try: + mod, add, rem = repo.status(wlock=wlock)[:3] + if mod or add or rem: + raise util.Abort(_('outstanding uncommitted changes')) + if len(repo.heads()) > 1: + raise util.Abort(_('multiple heads in this repository ' + '(use "hg heads" and "hg merge" to merge)')) + return pull() + finally: + lock.release() + wlock.release() cmdtable = { 'fetch': diff -r 4870f795f681 -r 49988d9f0758 hgext/mq.py --- a/hgext/mq.py Tue Aug 08 10:56:48 2006 -0500 +++ b/hgext/mq.py Wed Aug 09 13:55:18 2006 -0500 @@ -35,14 +35,16 @@ from mercurial.i18n import gettext as _ from mercurial import ui, hg, revlog, commands, util -versionstr = "0.45" - commands.norepo += " qclone qversion" -class StatusEntry: +class statusentry: def __init__(self, rev, name=None): if not name: - self.rev, self.name = rev.split(':') + fields = rev.split(':') + if len(fields) == 2: + self.rev, self.name = fields + else: + self.rev, self.name = None, None else: self.rev, self.name = rev, name @@ -52,10 +54,7 @@ class queue: def __init__(self, ui, path, patchdir=None): self.basepath = path - if patchdir: - self.path = patchdir - else: - self.path = os.path.join(path, "patches") + self.path = patchdir or os.path.join(path, "patches") self.opener = util.opener(self.path) self.ui = ui self.applied = [] @@ -64,14 +63,20 @@ self.series_dirty = 0 self.series_path = "series" self.status_path = "status" + self.guards_path = "guards" + self.active_guards = None + self.guards_dirty = False - if os.path.exists(os.path.join(self.path, self.series_path)): + if os.path.exists(self.join(self.series_path)): self.full_series = self.opener(self.series_path).read().splitlines() self.parse_series() - if os.path.exists(os.path.join(self.path, self.status_path)): - self.applied = [StatusEntry(l) - for l in self.opener(self.status_path).read().splitlines()] + if os.path.exists(self.join(self.status_path)): + lines = self.opener(self.status_path).read().splitlines() + self.applied = [statusentry(l) for l in lines] + + def join(self, *p): + return os.path.join(self.path, *p) def find_series(self, patch): pre = re.compile("(\s*)([^#]+)") @@ -86,12 +91,122 @@ index += 1 return None + guard_re = re.compile(r'\s?#([-+][^-+# \t\r\n\f][^# \t\r\n\f]*)') + def parse_series(self): self.series = [] + self.series_guards = [] for l in self.full_series: - s = l.split('#', 1)[0].strip() - if s: - self.series.append(s) + h = l.find('#') + if h == -1: + patch = l + comment = '' + elif h == 0: + continue + else: + patch = l[:h] + comment = l[h:] + patch = patch.strip() + if patch: + self.series.append(patch) + self.series_guards.append(self.guard_re.findall(comment)) + + def check_guard(self, guard): + bad_chars = '# \t\r\n\f' + first = guard[0] + for c in '-+': + if first == c: + return (_('guard %r starts with invalid character: %r') % + (guard, c)) + for c in bad_chars: + if c in guard: + return _('invalid character in guard %r: %r') % (guard, c) + + def set_active(self, guards): + for guard in guards: + bad = self.check_guard(guard) + if bad: + raise util.Abort(bad) + guards = dict.fromkeys(guards).keys() + guards.sort() + self.ui.debug('active guards: %s\n' % ' '.join(guards)) + self.active_guards = guards + self.guards_dirty = True + + def active(self): + if self.active_guards is None: + self.active_guards = [] + try: + guards = self.opener(self.guards_path).read().split() + except IOError, err: + if err.errno != errno.ENOENT: raise + guards = [] + for i, guard in enumerate(guards): + bad = self.check_guard(guard) + if bad: + self.ui.warn('%s:%d: %s\n' % + (self.join(self.guards_path), i + 1, bad)) + else: + self.active_guards.append(guard) + return self.active_guards + + def set_guards(self, idx, guards): + for g in guards: + if len(g) < 2: + raise util.Abort(_('guard %r too short') % g) + if g[0] not in '-+': + raise util.Abort(_('guard %r starts with invalid char') % g) + bad = self.check_guard(g[1:]) + if bad: + raise util.Abort(bad) + drop = self.guard_re.sub('', self.full_series[idx]) + self.full_series[idx] = drop + ''.join([' #' + g for g in guards]) + self.parse_series() + self.series_dirty = True + + def pushable(self, idx): + if isinstance(idx, str): + idx = self.series.index(idx) + patchguards = self.series_guards[idx] + if not patchguards: + return True, None + default = False + guards = self.active() + exactneg = [g for g in patchguards if g[0] == '-' and g[1:] in guards] + if exactneg: + return False, exactneg[0] + pos = [g for g in patchguards if g[0] == '+'] + nonpos = [g for g in pos if g[1:] not in guards] + if pos: + if not nonpos: + return True, '' + return False, nonpos + return True, '' + + def explain_pushable(self, idx, all_patches=False): + write = all_patches and self.ui.write or self.ui.warn + if all_patches or self.ui.verbose: + if isinstance(idx, str): + idx = self.series.index(idx) + pushable, why = self.pushable(idx) + if all_patches and pushable: + if why is None: + write(_('allowing %s - no guards in effect\n') % + self.series[idx]) + else: + if not why: + write(_('allowing %s - no matching negative guards\n') % + self.series[idx]) + else: + write(_('allowing %s - guarded by %r\n') % + (self.series[idx], why)) + if not pushable: + if why: + write(_('skipping %s - guarded by %r\n') % + (self.series[idx], ' '.join(why))) + else: + write(_('skipping %s - no matching guards\n') % + self.series[idx]) def save_dirty(self): def write_list(items, path): @@ -101,6 +216,7 @@ fp.close() if self.applied_dirty: write_list(map(str, self.applied), self.status_path) if self.series_dirty: write_list(self.full_series, self.series_path) + if self.guards_dirty: write_list(self.active_guards, self.guards_path) def readheaders(self, patch): def eatdiff(lines): @@ -120,7 +236,7 @@ else: break - pf = os.path.join(self.path, patch) + pf = self.join(patch) message = [] comments = [] user = None @@ -243,7 +359,7 @@ pname = ".hg.patches.merge.marker" n = repo.commit(None, '[mq]: merge marker', user=None, force=1, wlock=wlock) - self.applied.append(StatusEntry(revlog.hex(n), pname)) + self.applied.append(statusentry(revlog.hex(n), pname)) self.applied_dirty = 1 head = self.qparents(repo) @@ -253,7 +369,10 @@ if not patch: self.ui.warn("patch %s does not exist\n" % patch) return (1, None) - + pushable, reason = self.pushable(patch) + if not pushable: + self.explain_pushable(patch, all_patches=True) + continue info = mergeq.isapplied(patch) if not info: self.ui.warn("patch %s is not applied\n" % patch) @@ -261,7 +380,7 @@ rev = revlog.bin(info[1]) (err, head) = self.mergeone(repo, mergeq, head, patch, rev, wlock) if head: - self.applied.append(StatusEntry(revlog.hex(head), patch)) + self.applied.append(statusentry(revlog.hex(head), patch)) self.applied_dirty = 1 if err: return (err, head) @@ -317,6 +436,10 @@ tr = repo.transaction() n = None for patch in series: + pushable, reason = self.pushable(patch) + if not pushable: + self.explain_pushable(patch, all_patches=True) + continue self.ui.warn("applying %s\n" % patch) pf = os.path.join(patchdir, patch) @@ -356,7 +479,7 @@ raise util.Abort(_("repo commit failed")) if update_status: - self.applied.append(StatusEntry(revlog.hex(n), patch)) + self.applied.append(statusentry(revlog.hex(n), patch)) if patcherr: if not patchfound: @@ -386,7 +509,7 @@ if r: r.remove([patch], True) else: - os.unlink(os.path.join(self.path, patch)) + os.unlink(self.join(patch)) i = self.find_series(patch) del self.full_series[i] self.parse_series() @@ -405,7 +528,7 @@ if c or a or d or r: raise util.Abort(_("local changes found, refresh first")) def new(self, repo, patch, msg=None, force=None): - if os.path.exists(os.path.join(self.path, patch)): + if os.path.exists(self.join(patch)): raise util.Abort(_('patch "%s" already exists') % patch) commitfiles = [] (c, a, r, d, u) = repo.changes(None, None) @@ -425,7 +548,7 @@ if n == None: raise util.Abort(_("repo commit failed")) self.full_series[insert:insert] = [patch] - self.applied.append(StatusEntry(revlog.hex(n), patch)) + self.applied.append(statusentry(revlog.hex(n), patch)) self.parse_series() self.series_dirty = 1 self.applied_dirty = 1 @@ -628,15 +751,14 @@ if res and res == patch: return res - if not os.path.isfile(os.path.join(self.path, patch)): + if not os.path.isfile(self.join(patch)): try: sno = int(patch) except(ValueError, OverflowError): pass else: if sno < len(self.series): - patch = self.series[sno] - return patch + return self.series[sno] if not strict: # return any partial match made above if res: @@ -900,7 +1022,7 @@ self.strip(repo, top, update=False, backup='strip', wlock=wlock) n = repo.commit(filelist, message, changes[1], force=1, wlock=wlock) - self.applied[-1] = StatusEntry(revlog.hex(n), patch) + self.applied[-1] = statusentry(revlog.hex(n), patch) self.applied_dirty = 1 else: commands.dodiff(patchf, self.ui, repo, patchparent, None) @@ -922,18 +1044,26 @@ start = self.series_end() else: start = self.series.index(patch) + 1 - return [(i, self.series[i]) for i in xrange(start, len(self.series))] + unapplied = [] + for i in xrange(start, len(self.series)): + pushable, reason = self.pushable(i) + if pushable: + unapplied.append((i, self.series[i])) + self.explain_pushable(i) + return unapplied def qseries(self, repo, missing=None, summary=False): - start = self.series_end() + start = self.series_end(all_patches=True) if not missing: for i in range(len(self.series)): patch = self.series[i] if self.ui.verbose: if i < start: status = 'A' + elif self.pushable(i)[0]: + status = 'U' else: - status = 'U' + status = 'G' self.ui.write('%d %s ' % (i, status)) if summary: msg = self.readheaders(patch)[0] @@ -958,12 +1088,11 @@ self.ui.write("%s\n" % x) def issaveline(self, l): - name = l.split(':')[1] - if name == '.hg.patches.save.line': + if l.name == '.hg.patches.save.line': return True def qrepo(self, create=False): - if create or os.path.isdir(os.path.join(self.path, ".hg")): + if create or os.path.isdir(self.join(".hg")): return hg.repository(self.ui, path=self.path, create=create) def restore(self, repo, rev, delete=None, qupdate=None): @@ -984,7 +1113,7 @@ qpp = [ hg.bin(x) for x in l ] elif datastart != None: l = lines[i].rstrip() - se = StatusEntry(l) + se = statusentry(l) file_ = se.name if se.rev: applied.append(se) @@ -1039,13 +1168,13 @@ pp = r.dirstate.parents() msg += "\nDirstate: %s %s" % (hg.hex(pp[0]), hg.hex(pp[1])) msg += "\n\nPatch Data:\n" - text = msg + "\n".join(str(self.applied)) + '\n' + (ar and "\n".join(ar) - + '\n' or "") + text = msg + "\n".join([str(x) for x in self.applied]) + '\n' + (ar and + "\n".join(ar) + '\n' or "") n = repo.commit(None, text, user=None, force=1) if not n: self.ui.warn("repo commit failed\n") return 1 - self.applied.append(StatusEntry(revlog.hex(n),'.hg.patches.save.line')) + self.applied.append(statusentry(revlog.hex(n),'.hg.patches.save.line')) self.applied_dirty = 1 def full_series_end(self): @@ -1057,16 +1186,27 @@ return end + 1 return 0 - def series_end(self): + def series_end(self, all_patches=False): end = 0 + def next(start): + if all_patches: + return start + i = start + while i < len(self.series): + p, reason = self.pushable(i) + if p: + break + self.explain_pushable(i) + i += 1 + return i if len(self.applied) > 0: p = self.applied[-1].name try: end = self.series.index(p) except ValueError: return 0 - return end + 1 - return end + return next(end + 1) + return next(end) def qapplied(self, repo, patch=None): if patch and patch not in self.series: @@ -1123,7 +1263,7 @@ if existing: if not patch: patch = filename - if not os.path.isfile(os.path.join(self.path, patch)): + if not os.path.isfile(self.join(patch)): raise util.Abort(_("patch %s does not exist") % patch) else: try: @@ -1132,7 +1272,7 @@ raise util.Abort(_("unable to read %s") % patch) if not patch: patch = os.path.split(filename)[1] - if not force and os.path.exists(os.path.join(self.path, patch)): + if not force and os.path.exists(self.join(patch)): raise util.Abort(_('patch "%s" already exists') % patch) patchf = self.opener(patch, "w") patchf.write(text) @@ -1347,7 +1487,7 @@ for patch in patches: if not message: messages.append(q.readheaders(patch)[0]) - pf = os.path.join(q.path, patch) + pf = q.join(patch) (patchsuccess, files, fuzz) = q.patch(repo, pf) if not patchsuccess: raise util.Abort(_('Error folding patch %s') % patch) @@ -1369,6 +1509,51 @@ q.save_dirty() +def guard(ui, repo, *args, **opts): + '''set or print guards for a patch + + guards control whether a patch can be pushed. a patch with no + guards is aways pushed. a patch with posative guard ("+foo") is + pushed only if qselect command enables guard "foo". a patch with + nagative guard ("-foo") is never pushed if qselect command enables + guard "foo". + + with no arguments, default is to print current active guards. + with arguments, set active guards for patch. + + to set nagative guard "-foo" on topmost patch ("--" is needed so + hg will not interpret "-foo" as argument): + hg qguard -- -foo + + to set guards on other patch: + hg qguard other.patch +2.6.17 -stable + ''' + def status(idx): + guards = q.series_guards[idx] or ['unguarded'] + ui.write('%s: %s\n' % (q.series[idx], ' '.join(guards))) + q = repo.mq + patch = None + args = list(args) + if opts['list']: + if args or opts['none']: + raise util.Abort(_('cannot mix -l/--list with options or arguments')) + for i in xrange(len(q.series)): + status(i) + return + if not args or args[0][0:1] in '-+': + if not q.applied: + raise util.Abort(_('no patches applied')) + patch = q.applied[-1].name + if patch is None and args[0][0:1] not in '-+': + patch = args.pop(0) + if patch is None: + raise util.Abort(_('no patch to work with')) + if args or opts['none']: + q.set_guards(q.find_series(patch), args) + q.save_dirty() + else: + status(q.series.index(q.lookup(patch))) + def header(ui, repo, patch=None): """Print the header of the topmost or specified patch""" q = repo.mq @@ -1458,7 +1643,7 @@ if name in q.series: raise util.Abort(_('A patch named %s already exists in the series file') % name) - absdest = os.path.join(q.path, name) + absdest = q.join(name) if os.path.exists(absdest): raise util.Abort(_('%s already exists') % absdest) @@ -1479,10 +1664,10 @@ info = q.isapplied(patch) if info: - q.applied[info[0]] = StatusEntry(info[1], name) + q.applied[info[0]] = statusentry(info[1], name) q.applied_dirty = 1 - util.rename(os.path.join(q.path, patch), absdest) + util.rename(q.join(patch), absdest) r = q.qrepo() if r: wlock = r.wlock() @@ -1527,7 +1712,7 @@ util.copyfiles(path, newpath) if opts['empty']: try: - os.unlink(os.path.join(q.path, q.status_path)) + os.unlink(q.join(q.status_path)) except: pass return 0 @@ -1543,18 +1728,76 @@ repo.mq.strip(repo, rev, backup=backup) return 0 -def version(ui, q=None): - """print the version number of the mq extension""" - ui.write("mq version %s\n" % versionstr) - return 0 +def select(ui, repo, *args, **opts): + '''set or print guarded patches to push + + use qguard command to set or print guards on patch. then use + qselect to tell mq which guards to use. example: + + qguard foo.patch -stable (nagative guard) + qguard bar.patch +stable (posative guard) + qselect stable + + this sets "stable" guard. mq will skip foo.patch (because it has + nagative match) but push bar.patch (because it has posative + match). patch is pushed only if all posative guards match and no + nagative guards match. + + with no arguments, default is to print current active guards. + with arguments, set active guards as given. + + use -n/--none to deactivate guards (no other arguments needed). + when no guards active, patches with posative guards are skipped, + patches with nagative guards are pushed. + + use -s/--series to print list of all guards in series file (no + other arguments needed). use -v for more information.''' + + q = repo.mq + guards = q.active() + if args or opts['none']: + q.set_active(args) + q.save_dirty() + if not args: + ui.status(_('guards deactivated\n')) + if q.series: + ui.status(_('%d of %d unapplied patches active\n') % + (len(q.unapplied(repo)), len(q.series))) + elif opts['series']: + guards = {} + noguards = 0 + for gs in q.series_guards: + if not gs: + noguards += 1 + for g in gs: + guards.setdefault(g, 0) + guards[g] += 1 + if ui.verbose: + guards['NONE'] = noguards + guards = guards.items() + guards.sort(lambda a, b: cmp(a[0][1:], b[0][1:])) + if guards: + ui.note(_('guards in series file:\n')) + for guard, count in guards: + ui.note('%2d ' % count) + ui.write(guard, '\n') + else: + ui.note(_('no guards in series file\n')) + else: + if guards: + ui.note(_('active guards:\n')) + for g in guards: + ui.write(g, '\n') + else: + ui.write(_('no active guards\n')) def reposetup(ui, repo): - class MqRepo(repo.__class__): + class mqrepo(repo.__class__): def tags(self): if self.tagscache: return self.tagscache - tagscache = super(MqRepo, self).tags() + tagscache = super(mqrepo, self).tags() q = self.mq if not q.applied: @@ -1571,7 +1814,7 @@ return tagscache - repo.__class__ = MqRepo + repo.__class__ = mqrepo repo.mq = queue(ui, repo.join("")) cmdtable = { @@ -1602,6 +1845,9 @@ ('m', 'message', '', _('set patch header to ')), ('l', 'logfile', '', _('set patch header to contents of '))], 'hg qfold [-e] [-m ] [-l > $HGTMP/.hgrc +echo "fetch=" >> $HGTMP/.hgrc + +hg init a +echo a > a/a +hg --cwd a commit -d '1 0' -Ama + +hg clone a b +hg clone a c + +echo b > a/b +hg --cwd a commit -d '2 0' -Amb +hg --cwd a parents -q + +echo % should pull one change +hg --cwd b fetch ../a +hg --cwd b parents -q + +echo c > c/c +hg --cwd c commit -d '3 0' -Amc +hg --cwd c fetch -d '4 0' -m 'automated merge' ../a +ls c diff -r 4870f795f681 -r 49988d9f0758 tests/test-fetch.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-fetch.out Wed Aug 09 13:55:18 2006 -0500 @@ -0,0 +1,27 @@ +adding a +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +adding b +1:97d72e5f12c7 +% should pull one change +pulling from ../a +searching for changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +1:97d72e5f12c7 +adding c +pulling from ../a +searching for changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files (+1 heads) +merging with new head 2:97d72e5f12c7 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +new changeset 3:cd3a41621cf0 merges remote changes with local +a +b +c diff -r 4870f795f681 -r 49988d9f0758 tests/test-merge5.out --- a/tests/test-merge5.out Tue Aug 08 10:56:48 2006 -0500 +++ b/tests/test-merge5.out Wed Aug 09 13:55:18 2006 -0500 @@ -1,6 +1,3 @@ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved removing b -this update spans a branch affecting the following files: - b -aborting update spanning branches! -(use 'hg merge' to merge across branches or 'hg update -C' to lose changes) +abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes diff -r 4870f795f681 -r 49988d9f0758 tests/test-merge7.out --- a/tests/test-merge7.out Tue Aug 08 10:56:48 2006 -0500 +++ b/tests/test-merge7.out Wed Aug 09 13:55:18 2006 -0500 @@ -22,7 +22,7 @@ (run 'hg heads' to see heads, 'hg merge' to merge) merge: warning: conflicts during merge resolving manifests - force False allow True moddirstate True linear False + overwrite None branchmerge True partial False linear False ancestor 055d847dd401 local 2eded9ab0a5c remote 84cf5750dd20 test.txt versions differ, resolve merging test.txt diff -r 4870f795f681 -r 49988d9f0758 tests/test-mq-guards --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-mq-guards Wed Aug 09 13:55:18 2006 -0500 @@ -0,0 +1,84 @@ +#!/bin/sh + +HGRCPATH=$HGTMP/.hgrc; export HGRCPATH +echo "[extensions]" >> $HGTMP/.hgrc +echo "mq=" >> $HGTMP/.hgrc + +hg init +hg qinit + +echo x > x +hg ci -Ama + +hg qnew a.patch +echo a > a +hg add a +hg qrefresh + +hg qnew b.patch +echo b > b +hg add b +hg qrefresh + +hg qnew c.patch +echo c > c +hg add c +hg qrefresh + +hg qpop -a + +echo % should fail +hg qguard +fail + +hg qpush +echo % should guard a.patch +hg qguard +a +echo % should print +a +hg qguard +hg qpop + +hg qguard a.patch +echo % should push b.patch +hg qpush + +hg qpop +hg qselect a +echo % should push a.patch +hg qpush + +hg qguard c.patch -a +echo % should print -a +hg qguard c.patch + +echo % should skip c.patch +hg qpush -a + +hg qguard -n c.patch +echo % should push c.patch +hg qpush -a + +hg qpop -a +hg qselect -n +echo % should push all +hg qpush -a + +hg qpop -a +hg qguard a.patch +1 +2 +hg qselect 1 +echo % should push b.patch +hg qpush +hg qpop -a + +hg qselect 2 +hg qpush +hg qpop -a + +hg qselect 1 2 +echo % should push a.patch +hg qpush +hg qpop -a + +hg qguard a.patch +1 +2 -3 +hg qselect 1 2 3 +echo % should push b.patch +hg qpush diff -r 4870f795f681 -r 49988d9f0758 tests/test-mq-guards.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-mq-guards.out Wed Aug 09 13:55:18 2006 -0500 @@ -0,0 +1,54 @@ +adding x +Patch queue now empty +% should fail +abort: no patches applied +applying a.patch +Now at: a.patch +% should guard a.patch +% should print +a +a.patch: +a +Patch queue now empty +a.patch: +a +% should push b.patch +applying b.patch +Now at: b.patch +Patch queue now empty +3 of 3 unapplied patches active +% should push a.patch +applying a.patch +Now at: a.patch +% should print -a +c.patch: -a +% should skip c.patch +applying b.patch +skipping c.patch - guarded by '- a' +Now at: b.patch +% should push c.patch +applying c.patch +Now at: c.patch +Patch queue now empty +guards deactivated +2 of 3 unapplied patches active +% should push all +applying b.patch +applying c.patch +Now at: c.patch +Patch queue now empty +2 of 3 unapplied patches active +% should push b.patch +applying b.patch +Now at: b.patch +Patch queue now empty +2 of 3 unapplied patches active +applying b.patch +Now at: b.patch +Patch queue now empty +3 of 3 unapplied patches active +% should push a.patch +applying a.patch +Now at: a.patch +Patch queue now empty +2 of 3 unapplied patches active +% should push b.patch +applying b.patch +Now at: b.patch diff -r 4870f795f681 -r 49988d9f0758 tests/test-mq-qsave --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-mq-qsave Wed Aug 09 13:55:18 2006 -0500 @@ -0,0 +1,16 @@ +#!/bin/sh + +HGRCPATH=$HGTMP/.hgrc; export HGRCPATH +echo "[extensions]" >> $HGTMP/.hgrc +echo "mq=" >> $HGTMP/.hgrc + +hg init a +cd a + +echo 'base' > base +hg ci -Ambase -d '1 0' + +hg qnew -mmqbase mqbase + +hg qsave +hg qrestore 2 diff -r 4870f795f681 -r 49988d9f0758 tests/test-mq-qsave.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-mq-qsave.out Wed Aug 09 13:55:18 2006 -0500 @@ -0,0 +1,2 @@ +adding base +restoring status: hg patches saved state diff -r 4870f795f681 -r 49988d9f0758 tests/test-mq.out --- a/tests/test-mq.out Tue Aug 08 10:56:48 2006 -0500 +++ b/tests/test-mq.out Wed Aug 09 13:55:18 2006 -0500 @@ -30,6 +30,7 @@ qdelete remove a patch from the series file qdiff diff of the current patch qfold fold the named patches into the current patch + qguard set or print guards for a patch qheader Print the header of the topmost or specified patch qimport import a patch qinit init a new queue repository @@ -42,10 +43,10 @@ qrename rename a patch qrestore restore the queue state saved by a rev qsave save current queue state + qselect set or print guarded patches to push qseries print the entire series file qtop print the name of the current patch qunapplied print the patches not yet applied - qversion print the version number of the mq extension strip strip a revision and all later revs on the same branch adding a adding b/z diff -r 4870f795f681 -r 49988d9f0758 tests/test-up-local-change.out --- a/tests/test-up-local-change.out Tue Aug 08 10:56:48 2006 -0500 +++ b/tests/test-up-local-change.out Wed Aug 09 13:55:18 2006 -0500 @@ -17,7 +17,7 @@ summary: 1 resolving manifests - force False allow False moddirstate True linear True + overwrite False branchmerge False partial False linear True ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e a versions differ, resolve remote created b @@ -33,7 +33,7 @@ summary: 2 resolving manifests - force False allow False moddirstate True linear True + overwrite False branchmerge False partial False linear True ancestor a0c8bcbbb45c local 1165e8bd193e remote a0c8bcbbb45c remote deleted b removing b @@ -51,7 +51,7 @@ summary: 1 resolving manifests - force False allow False moddirstate True linear True + overwrite False branchmerge False partial False linear True ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e a versions differ, resolve remote created b @@ -98,21 +98,12 @@ date: Mon Jan 12 13:46:40 1970 +0000 summary: 2 -resolving manifests - force False allow False moddirstate True linear False - ancestor a0c8bcbbb45c local 1165e8bd193e remote 4096f2872392 - a versions differ, resolve - b versions differ, resolve -this update spans a branch affecting the following files: - a (resolve) - b (resolve) -aborting update spanning branches! -(use 'hg merge' to merge across branches or 'hg update -C' to lose changes) +abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes failed abort: outstanding uncommitted changes failed resolving manifests - force False allow True moddirstate True linear False + overwrite False branchmerge True partial False linear False ancestor a0c8bcbbb45c local 1165e8bd193e remote 4096f2872392 a versions differ, resolve b versions differ, resolve diff -r 4870f795f681 -r 49988d9f0758 tests/test-update-reverse.out --- a/tests/test-update-reverse.out Tue Aug 08 10:56:48 2006 -0500 +++ b/tests/test-update-reverse.out Wed Aug 09 13:55:18 2006 -0500 @@ -40,7 +40,7 @@ side1 side2 resolving manifests - force True allow False moddirstate True linear False + overwrite True branchmerge False partial False linear False ancestor 8515d4bfda76 local 1c0f48f8ece6 remote 0594b9004bae remote deleted side2, clobbering remote deleted side1, clobbering