Mercurial > public > mercurial-scm > hg
diff hgext/mq.py @ 13174:be7e8e9bc5e5
mq: update .hgsubstate if subrepos are clean (issue2499)
This patch prevents MQ from creating an inconsistent subrepo state. If
the .hgsub file has been changed, and none of the subrepos have
uncommitted changes, creating or updating a patch (using qnew, qrefresh,
or qrecord) will update .hgsubstate accordingly.
If any subrepos _do_ have uncommitted changes, qnew/qrefresh/qrecord
will abort.
Thanks to pmezard for proposing this solution.
author | Kevin Bullock <kbullock@ringworld.org> |
---|---|
date | Tue, 07 Dec 2010 22:14:43 -0600 |
parents | 9b46dd253052 |
children | d18a748d9c33 |
line wrap: on
line diff
--- a/hgext/mq.py Tue Dec 07 22:14:43 2010 -0600 +++ b/hgext/mq.py Tue Dec 07 22:14:43 2010 -0600 @@ -793,6 +793,19 @@ return top, patch return None, None + def check_substate(self, repo): + '''return list of subrepos at a different revision than substate. + Abort if any subrepos have uncommitted changes.''' + inclsubs = [] + wctx = repo[None] + for s in wctx.substate: + if wctx.sub(s).dirty(True): + raise util.Abort( + _("uncommitted changes in subrepository %s") % s) + elif wctx.sub(s).dirty(): + inclsubs.append(s) + return inclsubs + def check_localchanges(self, repo, force=False, refresh=True): m, a, r, d = repo.status()[:4] if (m or a or r or d) and not force: @@ -826,16 +839,23 @@ % patchfn) else: raise util.Abort(_('patch "%s" already exists') % patchfn) + + inclsubs = self.check_substate(repo) + if inclsubs: + inclsubs.append('.hgsubstate') if opts.get('include') or opts.get('exclude') or pats: + if inclsubs: + pats = list(pats or []) + inclsubs match = cmdutil.match(repo, pats, opts) # detect missing files in pats def badfn(f, msg): - raise util.Abort('%s: %s' % (f, msg)) + if f != '.hgsubstate': # .hgsubstate is auto-created + raise util.Abort('%s: %s' % (f, msg)) match.bad = badfn m, a, r, d = repo.status(match=match)[:4] else: m, a, r, d = self.check_localchanges(repo, force=True) - match = cmdutil.matchfiles(repo, m + a + r) + match = cmdutil.matchfiles(repo, m + a + r + inclsubs) if len(repo[None].parents()) > 1: raise util.Abort(_('cannot manage merge changesets')) commitfiles = m + a + r @@ -1259,6 +1279,8 @@ if repo.changelog.heads(top) != [top]: raise util.Abort(_("cannot refresh a revision with children")) + inclsubs = self.check_substate(repo) + cparents = repo.changelog.parents(top) patchparent = self.qparents(repo, top) ph = patchheader(self.join(patchfn), self.plainmode) @@ -1337,7 +1359,7 @@ r = list(dd) a = list(aa) c = [filter(matchfn, l) for l in (m, a, r)] - match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2])) + match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2] + inclsubs)) chunks = patch.diff(repo, patchparent, match=match, changes=c, opts=diffopts) for chunk in chunks: